Skip to content

ci: enforce version sync invariant#34

Open
lexfrei wants to merge 5 commits intomainfrom
ci/version-sync-invariant
Open

ci: enforce version sync invariant#34
lexfrei wants to merge 5 commits intomainfrom
ci/version-sync-invariant

Conversation

@lexfrei
Copy link
Copy Markdown
Contributor

@lexfrei lexfrei commented Apr 23, 2026

Summary

Add a version-sync invariant to the Lint job: hack/check-versions.sh fails the build if any tracked dependency's version drifts across its authoritative files.

Three groups are checked:

  1. cozy-installer chart — must match in galaxy.yml, roles/cozystack/defaults/main.yml, and the three examples/*/requirements.yml (compared without the leading v).
  2. k3s binary — must match across tests/ci-inventory.yml and all three examples/*/inventory.yml.
  3. k3s.orchestration collection — must match across tests/requirements.yml and all three examples/*/requirements.yml.

Renovate bumps already update all files together, so the check is transparent for automated flows. A manual version change in a single file now fails CI with a diff showing which file lags.

Changes

  • New hack/check-versions.sh using yq (preinstalled on GitHub-hosted ubuntu runners), wired as the first step of the existing Lint job in .github/workflows/test.yml.
  • New hack/test-check-versions.sh self-test: asserts the clean tree exits 0, then perturbs one file per invariant group (including a middle file for k3s to guard against future refactor bugs) and asserts exit 1 with the correct DRIFT in <group> label on stderr. Runs alongside in the same Lint job.
  • README: fix stale cozystack_chart_version default in the optional variables table (1.2.21.3.0).
  • CHANGELOG: move Unreleased section to the top of the file to match the reverse-chronological convention in the project CLAUDE.md.

Test plan

  • Script verified locally: positive run prints three OK lines; negative runs (via self-test) exit 1 with the right label for each group including a middle-file perturbation.
  • shellcheck clean on both scripts.
  • ansible-lint passes (CI)
  • ansible-test sanity passes (CI)
  • Tested on a live cluster — N/A (CI-only change)
  • Idempotency verified — N/A

Summary by CodeRabbit

  • Chores
    • Updated CI pipeline to run version invariant checks, validating version consistency across configuration files.
    • Added regression tests for version validation to ensure drift detection functions as expected.

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Apr 23, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: b5788d3d-9112-4976-837b-650364fded4e

📥 Commits

Reviewing files that changed from the base of the PR and between 1b6ca05 and 50961b9.

📒 Files selected for processing (4)
  • .github/workflows/test.yml
  • CHANGELOG.rst
  • hack/check-versions.sh
  • hack/test-check-versions.sh
🚧 Files skipped from review as they are similar to previous changes (3)
  • .github/workflows/test.yml
  • hack/check-versions.sh
  • hack/test-check-versions.sh

📝 Walkthrough

Walkthrough

The pull request introduces automated version invariant validation by adding two new Bash scripts to enforce synchronization of chart versions, Kubernetes versions, and collection versions across multiple YAML configuration files, alongside a corresponding CI workflow integration and changelog documentation.

Changes

Cohort / File(s) Summary
CI Workflow Integration
.github/workflows/test.yml
Lint job updated to run hack/check-versions.sh followed by hack/test-check-versions.sh before existing Python setup and linting tasks.
Documentation
CHANGELOG.rst
Changelog entry added documenting the new CI version invariant checks and their coverage of chart version, k3s binary version, and k3s.orchestration version alignment across tracked files.
Version Validation Scripts
hack/check-versions.sh, hack/test-check-versions.sh
New shell scripts: check-versions.sh validates version synchronization across repo YAML files using yq extraction; test-check-versions.sh runs regression tests by seeding drift scenarios and verifying nonzero exit codes with expected DRIFT error output.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~22 minutes

Poem

🐰 Versions once scattered, now held in place,
Through scripts and checks at a steady pace,
We hop through YAML, ensuring they align,
k3s and charts in perfect line!
Tests guard the drift, none shall escape,
Version harmony in every shape! 🔄✨

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 40.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely summarizes the main change: enforcing version sync invariants in CI via a new verification script.
Description check ✅ Passed The description comprehensively covers the changes and purpose, but some template test items lack detailed CI verification status.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch ci/version-sync-invariant

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share
Review rate limit: 0/1 reviews remaining, refill in 60 minutes.

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces a new CI script, hack/check-versions.sh, which ensures version strings remain synchronized across multiple configuration files, including galaxy.yml, role defaults, and example requirements. The script is integrated into the Lint job to prevent version drift. Feedback was provided to improve the clarity of error reporting by aligning a label with the actual variable name used in the code.

Comment thread hack/check-versions.sh Outdated

report "cozy-installer" \
"galaxy.yml:version" "$cozy_galaxy" \
"roles/cozystack/defaults/main.yml:chart_version" "$cozy_role" \
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The label used in the report for the role defaults file is slightly inconsistent with the actual key name. In roles/cozystack/defaults/main.yml, the variable is named cozystack_chart_version. Updating the label to match the key exactly will make it easier to locate the variable if a drift is reported.

Suggested change
"roles/cozystack/defaults/main.yml:chart_version" "$cozy_role" \
"roles/cozystack/defaults/main.yml:cozystack_chart_version" "$cozy_role" \

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Applied in a5c43f4. The cozy-installer group now labels the role default as roles/cozystack/defaults/main.yml:cozystack_chart_version (full variable name) so a DRIFT report points directly at the variable to grep for in the file.

@lexfrei lexfrei marked this pull request as ready for review April 23, 2026 09:49
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@hack/check-versions.sh`:
- Around line 70-101: The yq/get_collection_version command substitutions (e.g.,
cozy_galaxy, k3s_ci, orch_tests) can silently produce empty strings on failure
which bypasses report; enable bash's inherit_errexit (shopt -s inherit_errexit)
before these assignments or add explicit non-empty validation after each
assignment (or inside report()) to set err=1 and print a clear error when a
value is empty; update the block that assigns
cozy_galaxy/cozy_role/cozy_rhel/... and k3s_ci/k3s_rhel/.../orch_tests to either
enable inherit_errexit at top or to check each variable (and call err=1/report
error) before calling report().

In `@README.md`:
- Line 313: Update the Unreleased section of CHANGELOG.rst to include the chart
version bump: add a bullet "Bump cozystack_chart_version to 1.3.0" so the
changelog reflects the change made to roles/cozystack/defaults/main.yml
(cozystack_chart_version) and matches the README.md/galaxy.yml updates; place
the bullet alongside the other Unreleased entries for new features and CI
improvements.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 46c50414-cdb6-47cc-8958-94692b504a50

📥 Commits

Reviewing files that changed from the base of the PR and between 58eca80 and 1b6ca05.

📒 Files selected for processing (5)
  • .github/workflows/test.yml
  • CHANGELOG.rst
  • README.md
  • hack/check-versions.sh
  • hack/test-check-versions.sh

Comment thread hack/check-versions.sh
Comment thread README.md Outdated
| --- | --- | --- |
| `cozystack_chart_ref` | `oci://ghcr.io/cozystack/cozystack/cozy-installer` | Helm chart OCI reference |
| `cozystack_chart_version` | `1.2.2` | Helm chart version |
| `cozystack_chart_version` | `1.3.0` | Helm chart version |
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot Apr 23, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
rg -nP '^\s*(version|cozystack_chart_version)\s*[:=]' galaxy.yml roles/cozystack/defaults/main.yml
rg -nP 'cozystack\.installer' -A3 examples/*/requirements.yml

Repository: cozystack/ansible-cozystack

Length of output: 971


🏁 Script executed:

cat -n CHANGELOG.rst | head -100

Repository: cozystack/ansible-cozystack

Length of output: 6034


Add CHANGELOG.rst entry documenting cozystack_chart_version bump to 1.3.0.

The default chart version in roles/cozystack/defaults/main.yml was bumped from 1.2.2 to 1.3.0, matching the updates in galaxy.yml and README.md. However, the Unreleased section of CHANGELOG.rst documents new features and CI improvements but omits this chart version bump. Previous chart version bumps (v1.2.2, v1.2.1, v1.1.3, v1.1.2, v1.0.2) each got their own changelog entry. Add a bullet to the Unreleased section: Bump cozystack_chart_version to 1.3.0.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@README.md` at line 313, Update the Unreleased section of CHANGELOG.rst to
include the chart version bump: add a bullet "Bump cozystack_chart_version to
1.3.0" so the changelog reflects the change made to
roles/cozystack/defaults/main.yml (cozystack_chart_version) and matches the
README.md/galaxy.yml updates; place the bullet alongside the other Unreleased
entries for new features and CI improvements.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Out of scope for this PR. The 1.3.0 chart bump landed in main via a separate renovate PR that already created the v1.3.0 tag, so this PR does not bump the chart version — it only adds the CI invariant and fixes a stale README default. The missing CHANGELOG entry is a pre-existing gap in the release flow (the release workflow tags but doesn't rename Unreleased); the correct fix is to create a real v1.3.0 section alongside a change to the release workflow, which is a separate concern.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@lexfrei, understood — thanks for the context. The README update here is purely correcting a stale default that lagged behind the Renovate-driven 1.3.0 bump, not introducing a new version change, so a CHANGELOG entry in this PR would indeed be misattributed. Withdrawing this comment.


✏️ Learnings added
Learnt from: lexfrei
Repo: cozystack/ansible-cozystack PR: 34
File: README.md:313-313
Timestamp: 2026-04-23T10:42:54.380Z
Learning: In cozystack/ansible-cozystack, README.md default values for `cozystack_chart_version` can lag behind the actual version in `roles/cozystack/defaults/main.yml` and `galaxy.yml` after Renovate PRs. A PR that only corrects a stale README default is NOT bumping the chart version and does NOT require a CHANGELOG entry. The missing CHANGELOG entry for a released version (e.g. v1.3.0) is a pre-existing gap in the release flow: the release workflow tags the repo but does not rename the `Unreleased` CHANGELOG section to the new version. The correct fix is to create a proper versioned section alongside a release workflow change, handled separately.

Note: Learnings are effective only in the context of similar code segments. To apply general coding guidelines, please configure review instructions. You can manage existing learnings in the app.


🧠 Learnings used
Learnt from: CR
Repo: cozystack/ansible-cozystack PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-04-15T11:53:04.566Z
Learning: Applies to roles/cozystack/defaults/main.yml : Collection version is inherited from `cozystack/cozystack` and tracks the upstream Cozystack chart version in `roles/cozystack/defaults/main.yml:cozystack_chart_version`. Do NOT bump collection version just because a PR adds features or fixes bugs.

Learnt from: CR
Repo: cozystack/ansible-cozystack PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-04-15T11:53:04.566Z
Learning: Applies to CHANGELOG.rst : `CHANGELOG.rst` must use per-version sections in reverse chronological order. For changes on `main` without a version bump, use an `Unreleased` section at the top. Rename it to the new version when upstream bumps. Never attribute new changes to an already-tagged version.

@lexfrei lexfrei enabled auto-merge (squash) April 23, 2026 10:45
@lexfrei lexfrei self-assigned this Apr 24, 2026
@kvaps
Copy link
Copy Markdown
Member

kvaps commented May 1, 2026

Cannot merge — branch has conflicts with main. Please rebase onto current main and push, then I'll re-merge.

lexfrei added 5 commits May 1, 2026 20:10
Add hack/check-versions.sh and wire it into the Lint job. The script
fails the build if any of three tracked dependency groups drifts across
its authoritative files:

- cozy-installer chart version: galaxy.yml, defaults/main.yml, and the
  three examples/*/requirements.yml (compared without the leading "v")
- k3s binary version: ci-inventory.yml and all examples/*/inventory.yml
- k3s.orchestration collection version: tests/requirements.yml and all
  examples/*/requirements.yml

Assisted-By: Claude <noreply@anthropic.com>
Signed-off-by: Aleksei Sviridkin <f@lex.la>
- Fix stale cozystack_chart_version default in README (1.2.2 -> 1.3.0)
- Move CHANGELOG Unreleased section to the top (reverse-chronological)
- check-versions.sh: guard missing yq, normalise strip_v across all
  cozy-installer values, return status from report() instead of
  mutating a global so calls from subshells stay correct
- Add hack/test-check-versions.sh self-test covering the positive path
  and one negative per invariant; wire into the Lint job

Assisted-By: Claude <noreply@anthropic.com>
Signed-off-by: Aleksei Sviridkin <f@lex.la>
- Add a middle-file perturbation (examples/suse/inventory.yml) to
  test-check-versions.sh so the self-test does not implicitly rely on
  report() always comparing every value against pairs[1]
- Document why the k3s group does not use strip_v (every inventory
  already uses the v-prefixed form and adding one without it should
  fail on purpose)

Assisted-By: Claude <noreply@anthropic.com>
Signed-off-by: Aleksei Sviridkin <f@lex.la>
Address review feedback from gemini-code-assist on hack/check-versions.sh:
use the full `cozystack_chart_version` name (matching the actual key in
roles/cozystack/defaults/main.yml) instead of the abbreviated
`chart_version` so a DRIFT report points directly at the variable to
inspect.

Assisted-By: Claude <noreply@anthropic.com>
Signed-off-by: Aleksei Sviridkin <f@lex.la>
Address review feedback from coderabbitai on hack/check-versions.sh:
without `inherit_errexit`, a failing yq in $(...) would silently
become an empty string and pass every equality check, so drift could
go undetected if a tracked key were renamed.

- Enable `shopt -s inherit_errexit` so command-substitution failures
  propagate into outer assignments under `set -e`.
- Add a defence-in-depth empty-value guard inside report() that fails
  loudly when the reference value is empty.
- Extend test-check-versions.sh with a case that deletes
  `galaxy.yml:version` and asserts the script exits nonzero instead
  of reporting OK on an empty string.

Assisted-By: Claude <noreply@anthropic.com>
Signed-off-by: Aleksei Sviridkin <f@lex.la>
@lexfrei lexfrei force-pushed the ci/version-sync-invariant branch from 3065bea to 50961b9 Compare May 1, 2026 17:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants