Repository navigation
feat(examples): starter CI, lint and AGENTS.md for collection-fleet - #174
Merged
Merged
Conversation
Bring what decdn/fleet learned back into the template it was copied from: - CI (pre-commit; a fresh Galaxy install, a vars-shadowing guard, inventory parse and playbook syntax-check; actionlint), pre-commit, yamllint, markdownlint and dependabot configs, and an AGENTS.md/CLAUDE.md skeleton. - Document group-wide secrets in group_vars/<group>/secret.yml, and that a group_vars/<group>/ directory silently replaces a <group>.yml beside it. - requirements.yml floors were still >=0.2.0: raise them to the current releases, and have scripts/release.sh move a collection's floor in its release commit. Guards: make test-scripts checks the floors equal the galaxy.yml versions and that the example pins this repo's action SHAs and hook revs; galaxy/check-playbooks.sh runs the example against the built collections (inventory parses, every playbook it names ships and syntax-checks); CI's actionlint and yamllint cover its workflow and inventory. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
There was a problem hiding this comment.
🟢 Approval recommended
No unresolved defects were identified in the starter configuration, release-floor handling, or regression guards.
No open issues 🎉
What changed in this PR
Makes the collection-fleet example a more complete starter repository, with CI, linting, operator guidance, and release-synchronized collection requirements.
Changes:
- Adds starter CI, lint configuration, dependency updates, and agent guidance.
- Documents and checks Ansible vars-file shadowing.
- Synchronizes collection floors during releases and adds regression checks.
| File | Description |
|---|---|
tests/scripts-test.sh |
Tests pin alignment and release-floor updates. |
scripts/release.sh |
Updates and restores example floors during releases. |
RELEASING.md |
Documents release-floor synchronization. |
examples/collection-fleet/requirements.yml |
Raises collection minimum versions. |
examples/collection-fleet/README.md |
Explains CI, secrets, and upgrades. |
examples/collection-fleet/CLAUDE.md |
References fleet agent guidance. |
examples/collection-fleet/AGENTS.md |
Adds fleet-specific operating guidance. |
examples/collection-fleet/.yamllint |
Configures inventory YAML linting. |
examples/collection-fleet/.pre-commit-config.yaml |
Adds hygiene and lint hooks. |
examples/collection-fleet/.markdownlint-cli2.yaml |
Configures Markdown linting. |
examples/collection-fleet/.github/workflows/ci.yml |
Adds lint, inventory, and playbook checks. |
examples/collection-fleet/.github/dependabot.yml |
Schedules action and hook updates. |
CONTRIBUTING.md |
Documents expanded validation coverage. |
ansible/README.md |
Explains group-secret shadowing. |
ansible/galaxy/check-playbooks.sh |
Validates the example against built collections. |
AGENTS.md |
Documents example maintenance couplings. |
.pre-commit-config.yaml |
Lints the example’s Ansible inputs. |
.github/workflows/ci.yml |
Includes example changes and workflow linting. |
Review effort: Balanced
- CI loads the inventory with ansible-inventory --list, which reads every vars file (--graph read none), and says what it cannot check: what a role makes of the variables. - The vars-shadowing check is now scripts/check-vars-shadowing.sh, run by a pre-commit hook on the working tree (where git-ignored secret.yml directories exist) and by CI; it also catches .yml beside .yaml and extensionless names. - The Galaxy install retries only transient errors, and fails at once with an ::error:: otherwise; the workflow runs bash with pipefail. - check-playbooks.sh: unset the caller's inventory overrides, assert the hosts example's groups (a cfg that is not read gives an implicit localhost, exit 0), and say which doc file is missing instead of exiting silently. - fleet_pins_check refuses a tag-pinned action, an unknown hook repo and a yamllint pin in another spelling; release.sh says why a floor cannot move (already there, N entries); more release.sh and shadowing tests. - Docs: sudo-rs advice only where a become password is sent, first-run wording that matches the hosts examples, host-over-group secret precedence and group_vars/all, the floor's window before Galaxy publishes. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
examples/collection-fleet/gets the things our own fleet repo added after it was copied from this template:Starter CI and lint.
.github/workflows/ci.ymlhas three jobs:pre-commit.ansible:scripts/check-vars-shadowing.sh;ansible-inventory --list;decdn.publisher.site,.backupand.decommission.actionlint.The example also gets
.pre-commit-config.yaml,.yamllint,.markdownlint-cli2.yamland.github/dependabot.yml. The workflow and README say plainly what CI can't check: what a role does with your variables. Only a--check --diffrun shows that.The vars-shadowing trap. Ansible reads only one of
<name>/,<name>.yml,<name>.yamland<name>.jsoningroup_vars/andhost_vars/, and gives no warning. So agroup_vars/decdn_nodes/directory, made to hold a git-ignoredsecret.yml, drops every setting indecdn_nodes.yml.group_vars/all/.AGENTS.md(andCLAUDE.md→@AGENTS.md) for a fleet copy, with a This fleet section for the operator to fill in.Current floors.
requirements.ymlstill said>=0.2.0; it now saysdecdn.node >=0.4.0anddecdn.publisher >=0.3.1.scripts/release.shnow moves a collection's floor in its release commit, and refuses with a clear reason when it can't: the floor is already at the new version, or there are 0 or 2 or more entries for the collection. RELEASING.md notes the short window before Galaxy publishes the new version.Guards
make test-scriptschecks:galaxy.ymlversion;ci.ymlis pinned to a commit SHA that this repo'sci.ymlalso uses;It also runs
check-vars-shadowing.shon the example's inventory, plus four kinds of shadowing pair. New release.sh fixture cases cover:ansible/galaxy/check-playbooks.sh, run bymake galaxy-checkand thegalaxy-buildjob, runs the example the way a copy would, once with each collection's hosts example:ansible.cfg, and has the expected groups (a cfg that isn't read can't pass silently);decdn.<collection>.<playbook>named in its README, AGENTS.md or CI ships and passes a syntax check.CI's
ansiblepath filter now includesexamples/collection-fleet/**.CI's actionlint lints the example workflow too, and a root yamllint hook covers the example under its own
.yamllint.Test plan
make test-scripts: all passpre-commit run --all-files, in the repo and in a scratch copy of the examplegalaxy/check-playbooks.sh node|publisher, plus negative cases: an unknown playbook name, anansible.cfgwith no inventory, and an exportedANSIBLE_INVENTORYansiblesteps by hand against Galaxy (decdn.node0.4.0,decdn.publisher0.3.1). With a floor Galaxy doesn't have, the install fails at once with::error::group_vars/decdn_nodes/secret.ymlnext todecdn_nodes.ymlactionlinton the example workflow🤖 Generated with Claude Code