fix(#1186): guard hotfix version regex against leading zeros (ADR-218) (#1214)

Replace `^[0-9]+\.[0-9]+\.[1-9][0-9]*$` with
`^(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)\.[1-9][0-9]*$` in the hotfix
branch of the validate-version step, consistent with the two sibling
patterns already using the strict (0|[1-9][0-9]*) guard. Adds
regression assertions to tests/adr-218-release-version-validation.test.cjs
that prove `01.2.3` and `1.02.3` are rejected.

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Tom Boucher
2026-06-14 10:45:42 -04:00
committed by GitHub
parent 9e5d4b266b
commit e79e4e18b3
2 changed files with 16 additions and 7 deletions

View File

@@ -65,7 +65,7 @@ jobs:
if echo "$VERSION" | grep -qE '^(0|[1-9][0-9]*)\.0\.0$'; then
IS_MAJOR="true"
fi
elif echo "$VERSION" | grep -qE '^[0-9]+\.[0-9]+\.[1-9][0-9]*$'; then
elif echo "$VERSION" | grep -qE '^(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)\.[1-9][0-9]*$'; then
# Patch / hotfix release (X.Y.Z, Z>0)
IS_HOTFIX="true"
if [ "$ACTION" = "rc" ]; then

View File

@@ -254,12 +254,21 @@ describe('ADR-218 — leading-zero rejection regex (behavioral)', () => {
// Patch = 0 must be rejected (that is the minor/major form)
assert.equal(re.test('1.2.0'), false, 'Hotfix pattern must not match X.Y.0 (Z must be >0)');
// NOTE: The hotfix regex in release.yml currently permits leading zeros on
// the major and minor segments (e.g. `1.01.3` and `01.2.3` both pass).
// This is a known gap tracked in issue #1186. The assertions below are
// intentionally absent for those cases: this test documents CURRENT
// behavior, not ideal behavior. Fix #1186 will harden the pattern and
// add leading-zero rejection assertions here.
// ADR-218 / #1186: hotfix pattern must also reject leading zeros on major
// and minor segments. The old `[0-9]+` form allowed e.g. `01.2.3` and
// `1.02.3`. The corrected pattern uses `(0|[1-9][0-9]*)` for both.
const shouldRejectLeadingZero = [
'01.2.3', // leading zero in major
'1.02.3', // leading zero in minor
];
for (const v of shouldRejectLeadingZero) {
assert.equal(
re.test(v), false,
`Hotfix version "${v}" should be REJECTED (leading zero) but was accepted.\n` +
`Pattern: ${hotfixPatterns[0]}\n` +
`ADR-218 / #1186: restore (0|[1-9][0-9]*) on major and minor segments.`
);
}
});
test('extracted patterns use strict leading-zero guard, not the old [0-9]+ form', () => {