From 6910f1b5a5b38ae959552a14e98ea2a03d7b2ba8 Mon Sep 17 00:00:00 2001 From: Defame1297 Date: Sun, 9 Aug 2026 19:55:36 +0000 Subject: [PATCH] fix(lint): reject checkpoint-suffixed tags as the release-gate baseline MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git describe --match is a shell glob, not a regex: the trailing `*`s in 'v[0-9]*.[0-9]*.[0-9]*' match any suffix, so a tag like v1.2.3-checkpoint or v1.2.3-rc1 satisfied the pattern and could be picked as LAST_TAG instead of the true last release. That silently shifts the diff baseline and can let a push skip a required release. --exclude '*-*' rules out any tag carrying a hyphenated suffix. Added a regression test that tags a release-relevant change with a v1.0.1-checkpoint tag right after v1.0.0 and asserts the gate still fires — confirmed it fails against the pre-fix script and passes against the fix. --- scripts/check-release-needed.sh | 7 ++++++- tests/test-check-release-needed.sh | 18 ++++++++++++++++++ 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/scripts/check-release-needed.sh b/scripts/check-release-needed.sh index 61b8b27..ad2e094 100755 --- a/scripts/check-release-needed.sh +++ b/scripts/check-release-needed.sh @@ -55,7 +55,12 @@ fi # experiment tag reachable from the pushed ref must not shift the diff baseline. # The tag is resolved from $PUSHED_REF, not HEAD, for the same reason the diff # is: a tag reachable only from HEAD is not part of the history being pushed. -LAST_TAG="$(git describe --tags --abbrev=0 --match 'v[0-9]*.[0-9]*.[0-9]*' "$PUSHED_REF" 2>/dev/null || true)" +# --match is a shell glob, not a regex: its trailing `*`s match any suffix, so +# without --exclude a pre-release/checkpoint tag like v1.2.3-checkpoint or +# v1.2.3-rc1 also satisfies 'v[0-9]*.[0-9]*.[0-9]*' and could be picked over the +# true last release tag. --exclude is glob syntax too, so '*-*' is what actually +# rules out any tag carrying a hyphenated suffix, leaving only bare vMAJOR.MINOR.PATCH. +LAST_TAG="$(git describe --tags --abbrev=0 --match 'v[0-9]*.[0-9]*.[0-9]*' --exclude '*-*' "$PUSHED_REF" 2>/dev/null || true)" if [[ -z "$LAST_TAG" ]]; then echo "FAIL: no release tag exists yet, but .pre-commit-hooks.yaml already exposes hooks to external consumers." >&2 diff --git a/tests/test-check-release-needed.sh b/tests/test-check-release-needed.sh index 440960b..410281b 100755 --- a/tests/test-check-release-needed.sh +++ b/tests/test-check-release-needed.sh @@ -419,6 +419,24 @@ else fail "the repo's own .pre-commit-hooks.yaml no longer satisfies the entry constraints: $OUT20" fi +# --- 21. A vX.Y.Z-suffixed checkpoint tag must not satisfy the release gate --- +# git describe --match uses shell-glob semantics, not regex: the trailing `*` in +# 'v[0-9]*.[0-9]*.[0-9]*' matches any suffix, so a pre-release/checkpoint tag like +# v1.0.1-checkpoint also satisfies the glob and can be picked as LAST_TAG instead +# of the true last release tag — hiding a real release-relevant change that landed +# before the checkpoint tag from the diff. +echo "" +echo "--- ignores a vX.Y.Z-checkpoint tag and still flags the change since the real release tag ---" +FIXTURE21="$(make_tagged_fixture)"; track "$FIXTURE21" +echo "v2" > "$FIXTURE21/scripts/skill-size-check.sh" +(cd "$FIXTURE21" && git add -A && git commit -q -m "real release-relevant change" && git tag v1.0.1-checkpoint) +OUT21=$(run_check "$FIXTURE21" "refs/heads/main" || true) +if echo "$OUT21" | grep -q "skill-size-check.sh"; then + pass "still flags the release-relevant change since v1.0.0, ignoring the vX.Y.Z-checkpoint tag" +else + fail "a vX.Y.Z-checkpoint tag satisfied the glob and hid a real release-relevant change" +fi + echo "" echo "Results: $PASS passed, $FAIL failed" [[ $FAIL -eq 0 ]]