diff --git a/.gitea/workflows/ci.yml b/.gitea/workflows/ci.yml index 8f54585..02129b6 100644 --- a/.gitea/workflows/ci.yml +++ b/.gitea/workflows/ci.yml @@ -133,6 +133,33 @@ jobs: git add "$manifest" # The trailer below stops this push from re-triggering the tagger. git commit -m "chore(release): plugin.json version $version" -m "Skip-Release: true" + + # skills#46. This commit is pushed with secrets.GITEA_TOKEN, and a + # push authenticated with the Actions token does NOT trigger + # workflows -- deliberate platform behaviour to stop CI recursing. + # `Skip-Release: true` stops the tagger recursing; nothing stopped + # the whole run, `gate` included, from never firing on this commit. + # + # So every release left main's HEAD with zero CI runs. Measured: + # 6cc224f (0.19.4) and f031c2b (0.19.5) each have none, and the + # koala cluster's CIHeadUncovered{repo=skills} had been firing on it + # for 85 hours -- an alert that can only be cleared by an unrelated + # human push. + # + # The commit is not cosmetic: plugin.json's version is what Claude + # Code gates plugin updates on, `task check` asserts it is not + # behind the latest tag, and the sed-and-retry logic above already + # shipped a mismatched manifest once (v0.10.0 reading 0.9.0). + # + # Gating it HERE rather than re-triggering CI afterwards: the commit + # is produced here, so it can be validated here, at the cost of one + # `task check` instead of a second full run -- and with no recursion + # risk to reintroduce. + if ! task check; then + echo "::error::the release-bump commit fails task check -- not pushing it" >&2 + exit 1 + fi + if git push origin HEAD:main; then echo "bumped $manifest to $version" exit 0 diff --git a/tests/ci_gate_test.sh b/tests/ci_gate_test.sh index c410955..be8edad 100644 --- a/tests/ci_gate_test.sh +++ b/tests/ci_gate_test.sh @@ -53,5 +53,31 @@ printf '%s' "$tag_job" | grep -qE '^ +needs: *gate' \ && ok 'ungated release.yml removed' \ || no 'ungated release.yml removed' +# skills#46. The manifest-bump commit is created and pushed by the `tag` job +# using secrets.GITEA_TOKEN, and a push authenticated with the Actions token +# does not trigger workflows -- deliberate platform behaviour to stop CI +# recursing. So the ONE commit in this repo that no CI run has ever seen is the +# one the release job writes, every release: +# +# 6cc224f chore(release): plugin.json version 0.19.4 -> 0 runs +# f031c2b chore(release): plugin.json version 0.19.5 -> 0 runs +# +# The koala cluster's CIHeadUncovered{repo=skills} alert had been firing on it +# for 85 hours when this was found, and it cannot clear on its own -- only an +# unrelated human push moves main's HEAD to a tested commit. +# +# The commit is not nothing: plugin.json's version is what Claude Code gates +# plugin updates on, `task check` asserts it is not behind the latest tag, and +# the sed-and-retry logic that writes it already shipped a mismatched manifest +# once (v0.10.0 with the manifest reading 0.9.0). +# +# Anchored past comments: the tag job's prose already SAYS "`task check` +# asserts the manifest is not behind the latest tag", and a bare grep matches +# that and passes. A grep for a concept matches the rationale, and the more +# carefully a thing is documented the more likely that is. +printf '%s' "$tag_job" | grep -qE '^[^#]*task check' \ + && ok 'the release-bump commit is gated before it is pushed' \ + || no 'the release-bump commit is pushed with no gate -- nothing ever tests it (#46)' + printf '\nci_gate: %d passed, %d failed\n' "$pass" "$fail" [ "$fail" -eq 0 ]