ci(refactor-release): adopt dotted RC identifiers - #12793
ci(refactor-release): adopt dotted RC identifiers#12793DariuszPorowski wants to merge 2 commits into
Conversation
6261084 to
a914717
Compare
There was a problem hiding this comment.
Pull request overview
This PR updates Radius release automation to use SemVer-native -rc.N identifiers while preserving historical -rcN compatibility.
Changes:
- Centralizes RC validation, parsing, and release selection.
- Updates workflows, Helm coverage, upgrades, and release documentation.
- Adds tests for RC ordering and release-version handling.
Reviewed changes
Copilot reviewed 17 out of 17 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Summary | Final review note |
|---|---|---|
pkg/upgrade/preflight/version_check.go |
Upgrade compatibility handling | Moderate (2 votes): Normalize legacy rcN values for comparison; rc9 → rc10 is currently rejected. |
pkg/upgrade/preflight/version_check_test.go |
RC ordering tests | — |
eng/design-notes/tools/2026-03-goreleaser-release-lifecycle.md |
Lifecycle documentation updates | — |
docs/contributing/contributing-releases/README.md |
Release runbook updates | — |
deploy/Chart/tests/helpers_test.yaml |
Dotted RC Helm tag coverage | — |
build/test.mk |
Focused test registration | — |
.github/workflows/release-verification.yaml |
Updated release-version example | — |
.github/workflows/functional-test-noncloud.yaml |
Updated image-tag example | — |
.github/workflows/functional-test-cloud.yaml |
Updated image-tag example | — |
.github/scripts/validate_semver.py |
Dotted RC validation | — |
.github/scripts/release-version.sh |
Shared RC policy helpers | — |
.github/scripts/release-version-format_test.sh |
Version policy and parsing tests | — |
.github/scripts/release-verification.sh |
Release verification integration | — |
.github/scripts/release-get-version.sh |
Release candidate selection | Moderate (3 votes): Undotted candidates can still be emitted for new releases; reject or canonicalize them while preserving existing legacy tags. |
.github/scripts/release-get-version_test.sh |
Selector and compatibility tests | — |
.github/scripts/get_release_version.py |
Release metadata parsing | — |
.github/scripts/checkout-release-codebase.sh |
Release checkout validation | — |
Suppressed comments (3)
.github/scripts/checkout-release-codebase.sh:85
- The shared policy still accepts historical
vX.Y.Z-rcNvalues, but this new checkout error lists only the dotted form. Keep the error guidance consistent with the compatibility promise by mentioning the legacy form as accepted input.
echo "Expected semantic version format (e.g., '0.61.0' or '0.61.0-rc.1')"
.github/scripts/release-get-version_test.sh:214
- Because
REPOSITORIESare empty here, this test exercises a brand-new release rather than historical reconciliation. As written it locks in selectingv0.62.0-rc2for the path that later creates tags, so it permits the legacy form to be emitted; seed an existing legacy tag to test reconciliation and add an empty-repository assertion for the chosen reject-or-canonicalize behavior.
run_selector "${rc}" "${REPOSITORIES[@]}"
.github/scripts/release-verification.sh:139
- The shared policy still accepts historical
vX.Y.Z-rcNvalues, but this new validation error lists only the dotted form. When verification rejects a nearby malformed version, the message should mention the legacy form as accepted input too, otherwise the CLI guidance contradicts the compatibility promise.
echo "Error: Invalid version format. Expected format: X.Y.Z or X.Y.Z-rc.N" >&2
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
| if is_legacy_rc_version "${version_number}"; then | ||
| canonical_version="$(canonical_radius_rc_version "${version_number}")" | ||
| printf 'Warning: %s uses the historical RC form; use v%s for new releases.\n' \ | ||
| "${version}" "${canonical_version}" >&2 |
|
|
||
| // Allow upgrades within the same minor version (patch bumps, prerelease upgrades) | ||
| // e.g., 0.55.0-rc4 -> 0.55.0-rc5, 0.55.0-rc5 -> 0.55.0, 0.55.0 -> 0.55.1 | ||
| // e.g., 0.61.0-rc.2 -> 0.61.0-rc.10, 0.61.0-rc.10 -> 0.61.0, 0.61.0 -> 0.61.1 |
a914717 to
9529362
Compare
Dependency Review✅ No vulnerabilities or license issues or OpenSSF Scorecard issues found.Scanned FilesNone |
Functional Tests - upgrade-noncloud1 tests ±0 0 ✅ ±0 5m 5s ⏱️ ±0s For more details on these failures, see this check. Results for commit 4954991. ± Comparison against base commit d4f7cc1. ♻️ This comment has been updated with latest results. |
9529362 to
f58c094
Compare
f58c094 to
b7bbf25
Compare
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## dp/release-identifier-correlation #12793 +/- ##
=====================================================================
- Coverage 59.78% 59.77% -0.01%
=====================================================================
Files 778 778
Lines 45918 45918
=====================================================================
- Hits 27450 27449 -1
- Misses 18468 18469 +1 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
b7bbf25 to
190f3a8
Compare
190f3a8 to
6848ff9
Compare
042f019 to
16d7e3d
Compare
Functional Tests - kubernetes-noncloud23 tests 23 ✅ 8m 6s ⏱️ Results for commit 366806a. ♻️ This comment has been updated with latest results. |
There was a problem hiding this comment.
🔵 Needs a closer look
The release selector can still emit a newly introduced legacy -rcN tag, contrary to the stated policy.
Review details
Suppressed comments (1)
.github/scripts/release-get-version.sh:43
- Legacy RCs are accepted unconditionally here, so adding a brand-new
v0.62.0-rc2entry toversions.yamlstill selects that value and the release workflow passes it directly torelease-create-tag-and-branch.sh, emitting the legacy form. This contradicts the stated policy that legacy identifiers are read only for historical reconciliation. Reject legacy values unless existing release state proves this is a reconciliation/resume, and updatetest_legacy_rc_remains_acceptedto cover both historical and new-tag cases.
if is_legacy_rc_version "${version_number}"; then
canonical_version="$(canonical_radius_rc_version "${version_number}")"
printf 'Warning: %s uses the historical RC form; use v%s for new releases.\n' \
"${version}" "${canonical_version}" >&2
- Files reviewed: 17/17 changed files
- Comments generated: 0 new
- Review effort level: Balanced
366806a to
7ad0271
Compare
7ad0271 to
9e0e754
Compare
3e8e727 to
ac37e6d
Compare
ac37e6d to
aee314a
Compare
14c088f to
289e46d
Compare
917b444 to
1377cd4
Compare
Functional Tests - ucp-cloud4 tests 4 ✅ 32s ⏱️ Results for commit 4954991. ♻️ This comment has been updated with latest results. |
1377cd4 to
4954991
Compare
Use the SemVer-native rc.N form for new release candidates while preserving historical rcN parsing for verification, upgrades, and release reconciliation. Centralize Radius release-version policy, update operator guidance and active examples, and add focused coverage across tag parsing, selectors, Helm tags, and upgrade ordering. Signed-off-by: Dariusz Porowski <3431813+DariuszPorowski@users.noreply.github.com>
Signed-off-by: Dariusz Porowski <3431813+DariuszPorowski@users.noreply.github.com>
4954991 to
21190c3
Compare
Radius functional test overviewClick here to see the test run details
Test Status⌛ Building Radius and pushing container images for functional tests... |
Summary
-rc.Nform for new Radius release candidates, starting at-rc.1-rcNparsing and reconciliation without emitting that form for new releasesThis is PR 11 in stack #12738 and is based on #12783.
Reason for change
Legacy identifiers such as
rc10are one alphanumeric SemVer prerelease identifier and therefore sort beforerc2. The dotted form (rc.10) makes the RC number a numeric identifier, so standard SemVer tooling orders releases correctly. Historical tags must remain readable for verification, upgrades, and previous-release reconciliation.How to test
make test-release-version-format(24 checks)make test-release-get-version(11 real-git tests)make test-helm(134 tests)go test ./pkg/upgrade/preflight -run 'TestVersionCompatibilityCheck_Run|TestValidateVersionJump'shellcheckandshfmt -don changed/new release scriptsactionlint -shellcheck=on changed workflows; changed shell files were checked separatelymarkdownlint-cli2andmarkdown-table-formatter --checkon changed docsversions.yamlrunbook example withyqzizmor --pedantic --min-severity medium .github/workflows/release-verification.yamlmake spellcheckcould not run locally becausecspellis not installed; Markdown lint and table checks pass.File change summary
.github/scripts/release-version.sh.github/scripts/release-version-format_test.sh.github/scripts/release-get-version*.github/scripts/{validate_semver.py,get_release_version.py,release-verification.sh,checkout-release-codebase.sh}.github/workflows/*.yaml-rc.N.pkg/upgrade/preflight/version_check*rc.2torc.10upgrade ordering while retaining legacy compatibility.deploy/Chart/tests/helpers_test.yamldocs/contributing/contributing-releases/README.mdeng/design-notes/tools/2026-03-goreleaser-release-lifecycle.mdbuild/test.mkeng/design-notes/tools/2026-09-goreleaser-stack-review/pr-11-dotted-rc-identifiers.md