ci: tag-driven, gated release workflow (modeled on hardbyte/awa) - #351
Conversation
Publishing moves out of ci.yaml (which now only builds and tests PRs and
main) and the standalone chart-release workflow into release.yaml, triggered
by pushing a v* tag - including the tag GitHub creates when a draft release
is published. Nothing publishes until two gates pass:
version-check the tag equals the version in pyproject.toml, Cargo.toml and
the chart appVersion (check_versions.py gained --expect)
candidate-ci a successful push-triggered CI run exists for this exact SHA
then: multi-arch probe and operator images pushed with X.Y.Z / X.Y / latest
tags, keyless cosign signatures and build-provenance attestations; sdist and
wheel published to PyPI; Helm chart released via chart-releaser; and the
GitHub release created from the matching CHANGELOG.md section (kept as-is if
a draft already exists) with the Python distribution attached, then published.
CHANGELOG.md gains an [Unreleased] section and AGENTS.md documents the new
process.
Claude-Session: https://claude.ai/code/session_01U71MHip9jr1QHckFbBL4Sp
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
Deploying netchecks-docs with
|
| Latest commit: |
e7ffb33
|
| Status: | ✅ Deploy successful! |
| Preview URL: | https://0fbaa6cd.netchecks-docs.pages.dev |
| Branch Preview URL: | https://claude-pr-346-merge-review-4.netchecks-docs.pages.dev |
Coverage Report for CI Build 33627357435Coverage remained the same at 87.167%Details
Uncovered ChangesNo uncovered changes found. Coverage RegressionsNo coverage regressions found. Coverage Stats
💛 - Coveralls |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 3b54edaf15
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
Review finding: publishing a draft release to create the tag makes the release public before the gates run, so a failed gate would leave an announced release with no artifacts. The workflow already publishes an existing draft only after every job succeeds; document that as the only supported path and drop the 'publish the draft' alternative. Claude-Session: https://claude.ai/code/session_01U71MHip9jr1QHckFbBL4Sp
Ports the release process from
hardbyte/awato netchecks: the tag is the trigger, and nothing publishes until the tag matches every version manifest and CI has passed on that exact commit.What changes
New
.github/workflows/release.yaml— runs onv*tag push:version-checkcheck_versions.py --expect $TAG: tag must equalpyproject.toml,operator/Cargo.tomland the chartappVersion(real TOML/YAML parse, not grep)candidate-cici.yamlrun on this exact SHA — i.e. unit + kind integration tests passed onmainfor the commit being releasedprobe-image/operator-image+-mergeX.Y.Z,X.Y,latest,sha-…tags; keyless cosign signatures and build-provenance attestations (actions/attest, pushed to the registry) — same as awapython-dist→publish-pypiuv build→ PyPI (still viaPYPI_API_TOKEN; switching to trusted publishing is a one-line change once the publisher is registered on PyPI — the job already hasid-token: write)helm-chartgithub-release## X.Y.Zsection ofCHANGELOG.md(falling back to generated notes;--prereleasefor alpha/beta/rc). Either way the GitHub release only becomes public after every other job has succeeded.ci.yamldrops itsrelease:and tag triggers, the PyPI job and the semver image tags — it now only builds/tests PRs andmain.helm-chart-release.yamlis deleted (folded into release.yaml).AGENTS.mddocuments the new process;CHANGELOG.mdgains an## [Unreleased]section, as in awa.The one rule: push the tag, never publish a draft to create it
Publishing a draft release makes it public before the tag-triggered workflow can run, so a failed gate would leave an announced release with no package/images/chart behind it (thanks Codex). The supported path is:
A hand-written release may exist beforehand as a draft; the workflow publishes it as its final step.
Effect on the pending v0.11.0 draft
Leave the draft as it is. After this PR merges and the push-CI run on the new
maintip is green, push thev0.11.0tag at that tip; the workflow will run the gates, publish PyPI/images/chart, attach the Python distribution to your draft (keeping your notes) and publish it.Not carried over from awa (by design)
uv buildcovers it.candidate-cialready requires to have passed on the exact commit. A rehearsal gate for chart upgrades (≤0.3.x → 0.5.0 CRD adoption) would be a good follow-up.Verification
actionlintclean on both workflows;check_versions.pywith/without--expectbehaves (matching tag passes, mismatching tag fails with a clear message); the CHANGELOG-section extraction was tested against the 0.11.0 entry; ruff and typos clean. The workflow itself can only be exercised by a real tag.https://claude.ai/code/session_01U71MHip9jr1QHckFbBL4Sp