diff options
| author | omnom62 <75066712+omnom62@users.noreply.github.com> | 2026-07-28 05:09:47 +1000 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2026-07-28 05:09:47 +1000 |
| commit | b0243027a73583eed7014ae924fbc79bb55577b5 (patch) | |
| tree | 822de31d5246309612f50c6a1c8b6f5717dba8eb /.github | |
| parent | 2e2a0f2da3df1a3197bef3c19d3e7deecf869759 (diff) | |
| parent | 17041b6f6953b993762854a67953fb35176b46e7 (diff) | |
| download | vyos.vyos-b0243027a73583eed7014ae924fbc79bb55577b5.tar.gz vyos.vyos-b0243027a73583eed7014ae924fbc79bb55577b5.zip | |
Merge branch 'main' into fix/black-formatting
Diffstat (limited to '.github')
| l--------- | .github/copilot-instructions.md | 1 | ||||
| -rw-r--r-- | .github/instructions/modules.instructions.md | 37 | ||||
| -rw-r--r-- | .github/instructions/tests.instructions.md | 114 | ||||
| -rw-r--r-- | .github/mergify.yml | 34 | ||||
| -rw-r--r-- | .github/workflows/ah_token_refresh.yml | 2 | ||||
| -rw-r--r-- | .github/workflows/cla-check.yml | 2 | ||||
| -rw-r--r-- | .github/workflows/codecoverage.yml | 2 | ||||
| -rw-r--r-- | .github/workflows/codeql.yml | 30 |
8 files changed, 219 insertions, 3 deletions
diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md new file mode 120000 index 00000000..be77ac83 --- /dev/null +++ b/.github/copilot-instructions.md @@ -0,0 +1 @@ +../AGENTS.md
\ No newline at end of file diff --git a/.github/instructions/modules.instructions.md b/.github/instructions/modules.instructions.md new file mode 100644 index 00000000..d7782e1e --- /dev/null +++ b/.github/instructions/modules.instructions.md @@ -0,0 +1,37 @@ +--- +applyTo: "plugins/**,meta/runtime.yml" +--- + +# Plugin conventions + +## Module option descriptions + +- Must be complete English sentences ending with a period. +- No grammar errors. Common mistake: "the number hops" should be "the number of hops". +- Deprecated options must include `removed_in_version` and `removed_from_collection` fields. +- Do not add new options with `deprecated: true` — remove deprecated options entirely. + +## rm_templates files + +Files in `plugins/module_utils/network/vyos/rm_templates/` define regex parsers and Jinja2 generators for a resource module. Each entry has: +- `name` — unique identifier +- `getval` — compiled regex with named groups +- `setval` — Jinja2 template or callable producing a VyOS CLI command +- `result` — dict mapping regex groups to facts structure +- `shared` (optional) — bool, whether the template applies to a shared config block + +## meta/runtime.yml redirects + +Short-name redirects must point to the actual module name with the `vyos_` prefix. For example: +```yaml +snmp_server: + redirect: vyos.vyos.vyos_snmp_server # correct + # NOT: vyos.vyos.vyos_snmp_servers # wrong (pluralized) +``` + +Verify any changed redirect target exists as a real module file under `plugins/modules/`. + +## cliconf / terminal plugins + +`plugins/cliconf/vyos.py` — do not modify without understanding edit-mode and commit semantics. +`plugins/terminal/vyos.py` — handles prompt detection; regex changes require testing against all supported VyOS versions listed in README.md. diff --git a/.github/instructions/tests.instructions.md b/.github/instructions/tests.instructions.md new file mode 100644 index 00000000..150db41e --- /dev/null +++ b/.github/instructions/tests.instructions.md @@ -0,0 +1,114 @@ +--- +applyTo: "tests/unit/**" +--- + +# Unit test conventions + +## Base class and structure + +All test classes inherit from `TestVyosModule` in `tests/unit/modules/network/vyos/vyos_module.py`. + +```python +class TestVyosFooModule(TestVyosModule): + module = vyos_foo + + def setUp(self): ... + def tearDown(self): ... + def load_fixtures(self, commands=None, filename=None): ... + def test_...(self): ... +``` + +## Mocking: resource modules + +Resource module tests require two framework-level patches in `setUp` with corresponding cleanup in `tearDown`: + +```python +# in setUp: +self.mock_get_resource_connection_config = patch( + "ansible_collections.ansible.netcommon.plugins.module_utils.network.common.cfg.base.get_resource_connection" +) +self.get_resource_connection_config = self.mock_get_resource_connection_config.start() + +self.mock_get_resource_connection_facts = patch( + "ansible_collections.ansible.netcommon.plugins.module_utils.network.common.facts.facts.get_resource_connection" +) +self.get_resource_connection_facts = self.mock_get_resource_connection_facts.start() + +# in tearDown: +self.mock_get_resource_connection_config.stop() +self.mock_get_resource_connection_facts.stop() +``` + +Most resource module tests also patch the facts class's `get_device_data` method directly and use it in `load_fixtures`: + +```python +# in setUp: +self.mock_execute_show_command = patch( + "ansible_collections.vyos.vyos.plugins.module_utils.network.vyos." + "facts.{resource}.{resource}.{Resource}Facts.get_device_data" +) +self.execute_show_command = self.mock_execute_show_command.start() + +# in load_fixtures: +def load_from_file(*args, **kwargs): + return load_fixture("vyos_{resource}_config.cfg") +self.execute_show_command.side_effect = load_from_file +``` + +An alternative pattern sets `self.get_resource_connection_facts.return_value.get_config.return_value = fixture_data` in `load_fixtures` instead — both approaches work, but the `get_device_data` pattern is used by most existing tests. + +## Mocking: legacy modules + +Legacy modules (`vyos_vlan`, `vyos_config`, `vyos_command`, etc.) patch the specific helper the module calls, directly in the module under test. Which helper depends on the module: + +```python +# vyos_command, vyos_facts, vyos_ping — patch run_commands +self.mock_run_commands = patch("ansible_collections.vyos.vyos.plugins.modules.vyos_foo.run_commands") +# vyos_config — patch get_config / load_config +self.mock_load_config = patch("ansible_collections.vyos.vyos.plugins.modules.vyos_foo.load_config") +``` + +In `load_fixtures`, configure the mock using `side_effect` (for dynamic fixture loading) or `return_value` (for a fixed response): + +```python +# side_effect — used by most existing legacy tests +def load_from_file(*args, **kwargs): + return load_fixture("vyos_foo_config.cfg") +self.run_commands.side_effect = load_from_file + +# return_value — acceptable for simple fixed responses +self.run_commands.return_value = [SHOW_OUTPUT] +``` + +## load_fixtures and filename + +`execute_module()` always calls `load_fixtures()`. Never set mock return values inside a test method — they will be overwritten by the next `execute_module` call. Use the `filename` parameter to vary the fixture: + +```python +def load_fixtures(self, commands=None, filename=None): + if filename == "empty": + self.run_commands.return_value = [EMPTY_OUTPUT] + else: + self.run_commands.return_value = [DEFAULT_OUTPUT] +``` + +Then call: `self.execute_module(changed=True, commands=commands, filename="empty")` + +## Fixture files + +Raw device CLI output lives in `tests/unit/modules/network/vyos/fixtures/` as `.cfg` files. +Load with `load_fixture("vyos_foo_config.cfg")`. + +## Required test coverage for resource modules + +A complete resource module test file should cover all applicable states: +- `merged` (including an idempotent case) +- `replaced` +- `overridden` +- `deleted` +- `rendered` — assert `result["rendered"]` matches expected CLI commands +- `gathered` — assert `result["gathered"]` contains expected structured data +- `parsed` — pass `running_config=raw_string` and assert `result["parsed"]` + +Flag test files that are missing `rendered`, `gathered`, or `parsed` tests without explanation. + diff --git a/.github/mergify.yml b/.github/mergify.yml new file mode 100644 index 00000000..43353ea4 --- /dev/null +++ b/.github/mergify.yml @@ -0,0 +1,34 @@ +# yaml-language-server: $schema=https://docs.mergify.com/mergify-configuration-schema.json +extends: mergify +merge_protections_settings: + reporting_method: check-runs + +pull_request_rules: + - name: Flag product T-ID format violation in PR title or commit messages + description: > + Product-repo convention: the PR title AND every commit's first line must + match `T<digits>: <text>` (optional `scope: ` prefix). The title is always + checked; the per-commit check is exempted when a maintainer applies the + `legacy` label — an escape hatch for grandfathered PRs whose commit history + cannot be rewritten (repos that squash-merge AND block force-push, e.g. + vyos.vyos enforces `non_fast_forward` on ~ALL branches with zero bypass). + New PRs are still nudged toward the convention; `legacy` is the deliberate, + maintainer-controlled opt-out. Relocated from the central config (T8966) + so the convention is opt-in per product repo. Name is intentionally + distinct from any central rule name so this stays additive (not an + `extends:` override). Legacy-label escape added 2026-06-08 (T8966). + conditions: + - '-closed' + - '-merged' + - '-author~=\[bot\]$' + - 'author!=copilot-swe-agent' + - 'author!=vyosbot' + - or: + - '-title~=^(([a-zA-Z0-9\-_.]+:\s)?)T\d+:\s+[^\s]+.*' + - and: + - 'label!=legacy' + - 'commits[*].commit_message~=^(?!(([a-zA-Z0-9\-_.]+:\s)?)T\d+:\s+[^\s]+).*' + actions: + label: + toggle: + - invalid-task-id diff --git a/.github/workflows/ah_token_refresh.yml b/.github/workflows/ah_token_refresh.yml index 0346920e..09d2f9db 100644 --- a/.github/workflows/ah_token_refresh.yml +++ b/.github/workflows/ah_token_refresh.yml @@ -7,7 +7,7 @@ on: jobs: refresh: - uses: ansible/team-devtools/.github/workflows/ah_token_refresh.yml@v26.1.0 + uses: ansible/team-devtools/.github/workflows/ah_token_refresh.yml@v26.4.0 with: environment: release secrets: diff --git a/.github/workflows/cla-check.yml b/.github/workflows/cla-check.yml index da3e6efd..fa96d19d 100644 --- a/.github/workflows/cla-check.yml +++ b/.github/workflows/cla-check.yml @@ -11,5 +11,5 @@ on: types: [created] jobs: call-cla-assistant: - uses: vyos/vyos-cla-signatures/.github/workflows/cla-reusable.yml@current + uses: vyos/vyos-cla-signatures/.github/workflows/cla-reusable.yml@production secrets: inherit diff --git a/.github/workflows/codecoverage.yml b/.github/workflows/codecoverage.yml index 878ae247..ee71e179 100644 --- a/.github/workflows/codecoverage.yml +++ b/.github/workflows/codecoverage.yml @@ -62,7 +62,7 @@ jobs: working-directory: ${{ steps.identify.outputs.collection_path }} - name: Upload coverage report to Codecov - uses: codecov/codecov-action@v5 + uses: codecov/codecov-action@v7 with: directory: ${{ steps.identify.outputs.collection_path }} fail_ci_if_error: false diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml new file mode 100644 index 00000000..b83b94e0 --- /dev/null +++ b/.github/workflows/codeql.yml @@ -0,0 +1,30 @@ +name: "Perform CodeQL Analysis" + +on: + push: + branches: + - main + paths: + - '**' + - '!.github/**' + - '!**/*.md' + pull_request: + branches: + - main + paths: + - '**' + - '!.github/**' + - '!**/*.md' + schedule: + - cron: '52 13 * * 0' + +permissions: + actions: read + contents: read + security-events: write + +jobs: + codeql-analysis-call: + uses: vyos/.github/.github/workflows/codeql-analysis.yml@production + with: + languages: "['python']" |
