#!/bin/sh # Tests for the CI gate workflow. # # The regression these exist for: this repo had a release workflow that # auto-tagged every push to main, and a `task check` / `task test` suite that # nothing ever ran. CI reported green having tested nothing — a gate that # fails *open*. These assertions pin the wiring so it cannot silently regress. set -u ROOT=$(CDPATH= cd -- "$(dirname -- "$0")/.." && pwd) SUT="$ROOT/.gitea/workflows/ci.yml" pass=0 fail=0 ok() { pass=$((pass + 1)); printf ' ok %s\n' "$1"; } no() { fail=$((fail + 1)); printf ' FAIL %s\n' "$1"; } if [ ! -f "$SUT" ]; then printf 'FAIL: %s does not exist\n' "$SUT" exit 1 fi ok 'ci.yml exists' # A pull_request trigger is what gives tbd_ship a CI run to read on the head # commit of a branch; without one it fails closed and never merges (#22). grep -qE '^ pull_request:' "$SUT" \ && ok 'runs on pull_request' \ || no 'runs on pull_request' grep -qE '^ +push:' "$SUT" \ && ok 'runs on push' \ || no 'runs on push' grep -qE '^ +- *(run: *)?task check$|task check' "$SUT" \ && ok 'gate runs task check' \ || no 'gate runs task check' grep -qE 'task test' "$SUT" \ && ok 'gate runs task test' \ || no 'gate runs task test' # The point of the gate: tagging must not happen on a red check. tag_job=$(awk '/^ tag:/{f=1} f&&/^ [a-z][a-z_-]*:/&&!/^ tag:/{f=0} f' "$SUT") printf '%s' "$tag_job" | grep -qE '^ +needs: *gate' \ && ok 'tag job needs the gate' \ || no 'tag job needs the gate' # The old workflow file must be gone, or two workflows race on the same push # and the ungated one still tags. [ ! -f "$ROOT/.gitea/workflows/release.yml" ] \ && 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 ]