Skip to content

ci: tag push fires release-check tag-integrity; retire empty-commit retrigger - #59

Merged
ManningWorks merged 2 commits into
masterfrom
ci/release-check-tag-integrity
Sep 28, 2026
Merged

ManningWorks merged 2 commits into
masterfrom
ci/release-check-tag-integrity

Conversation

@ManningWorks

Copy link
Copy Markdown
Owner

What

Retires the empty-commit re-trigger remedy for release-check. The tag push itself now fires the workflow and is the green proof after a release.

Why: release-check only triggered on pushes to master, but the tag lands after the merge (merge gate: coder → reviewer → maintainer tail that merges, tags, re-triggers). Every release had a red window between merge and tag, and the documented remedy — git commit --allow-empty pushed directly to master — bypasses PR-required branch protection for a junk commit. Live instance: PR #58 (v0.9.2) merged with no tail card dispatched; the tag was pushed manually at 11:4x and the next master push went green without the empty commit.

Changes (2 files)

  1. .github/workflows/release-check.yml

    • on.push gains tags: ['v*'] (master trigger kept, single push block).
    • New tag-integrity job (if: startsWith(github.ref, "refs/tags/v")): checks out the tagged tree and fails if the tagged tree's VERSION does not equal the tag name (leading v stripped). Verifies tag content, not just existence — tag-current only proves the tag exists on origin; this catches a tag pointed at the wrong commit, the silent failure mode the current check cannot see (F10 class: verify the effect, not the handle).
    • tag-current job is byte-identical (pure addition; it also runs on tag pushes, which is harmless — it re-checks master's VERSION↔tag).
  2. AGENTS.md — two spots: the release-convention paragraph (empty-commit remedy retired; tag push is the green proof) and merge-gate step 3 (tail "pushes the tag — the tag push fires release-check (tag-integrity) which is the green proof. No empty commit.").

No VERSION bump, no CHANGELOG change — no-bump content PR; VERSION stays 0.9.2.

Verification

Local (done):

  • Contract test (TDD): RED on master (no tags trigger, no tag-integrity job) → GREEN post-change, incl. "tag-current unchanged" assertion.
  • Teeth simulation of the job's check: v0.9.2/VERSION=0.9.2 PASS; v0.9.99-test/VERSION=0.9.2 FAIL with the ::error:: line naming both values; v0.10.0/VERSION=0.10.0 PASS.
  • YAML parses; bash test/smoke.sh 60 passed 0 failed (baseline pre-change identical).

Live (two-phase — must run in the maintainer tail AFTER this PR merges, because the new workflow only exists on master then):

  1. Negative (teeth proof): push throwaway tag v0.9.99-test at the then-current master commit → tag-integrity run must FAIL (VERSION=0.9.2 ≠ 0.9.99). Record run URL, then delete the tag.
  2. Positive: delete + re-push v0.9.2 — the SAME existing tag object (re-push the ref; identical SHA = zero release-history change). tag-integrity run must PASS. Constraint: only if no box has pulled v0.9.2 since the tag push (updates are manual — check first; if any box pulled, skip this phase and note why).

Tail semantics (pinned)

MERGE-ONLY tail: no VERSION change, no tag, no re-trigger. The merge push runs tag-current and stays green (v0.9.2 is on origin). The two-phase live verification is the tail's job, per the plan above.

Tag pushes now fire release-check via a new tag-integrity job that
checks out the tagged tree (ref: github.ref_name) and fails when the
tree's VERSION does not equal the tag name with the leading v
stripped. The tag push becomes the green proof after a release;
tag-current is unchanged and also runs on tag pushes.
The empty-commit re-trigger was a junk commit pushed directly to
master, bypassing PR-required branch protection, so that a check
triggered only on master pushes would get a second reading after the
tag landed. The tag-integrity job makes the tag push itself fire
release-check, so the proof rides the push that was already required.
No empty commit, no direct push to master.
@coderabbitai

coderabbitai Bot commented Sep 28, 2026

Copy link
Copy Markdown

Important

  • 🔍 Trigger review

This repository does not receive automatic reviews because it has fewer than 10 stars.

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Advanced

Run ID: 6dcdfe9e-8fa4-4457-951c-974c06ad8095


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@ManningWorks

Copy link
Copy Markdown
Owner Author

APPROVE — Standards PASS / Spec PASS. 0 blocking, 1 non-blocking LOW.

Base pinned: reviewed origin/master (2dcd223, parent of first PR commit) — clean 2-commit linear history (455b555, 1efd7a1), 2 files, 36 insertions / 6 deletions. (Local master ref on this box was stale at pre-#58 5dfb212; a naive three-dot diff shows 5 files — artifact of the stale ref, not the PR.)

DoD items — all verified:

  • .github/workflows/release-check.yml:9 — on.push gains tags: ['v*']; master trigger kept, single push block. ✓
  • .github/workflows/release-check.yml:33-55 — new tag-integrity job: if: startsWith(github.ref, "refs/tags/v") (L38) gates it to tag pushes only; actions/checkout@v4 with ref: ${{ github.ref_name }} (L45) checks out the tagged tree; compare TAG=${GITHUB_REF_NAME#v} vs cat VERSION (L49-50) fails on mismatch with ::error:: naming both values (L51-54). Teeth are real. ✓
  • tag-current job (L12-31) byte-identical — 0 deletions in the file, pure addition. ✓
  • AGENTS.md:20-25 + AGENTS.md:87-89 — operator-applied edit matches the approved diff verbatim; both spots correct. ✓
  • grep 'empty commit' AGENTS.md → only the two new negations (L24, L89); no --allow-empty, no stale re-trigger remedy. ✓
  • VERSION still 0.9.2, no CHANGELOG.md / SKILL.md change vs origin/master. ✓
  • YAML parses; all 7 required checks SUCCESS (CodeRabbit, install±, install-regression-fix1, integration-seeded±, smoke). ✓

Spec (PR description) vs registry: "no-bump content PR, 2 files, VERSION stays 0.9.2" — confirmed against git diff origin/master..HEAD. Tag v0.9.2 (d493f30 annotated → 2dcd223 = origin/master) unchanged.

Non-blocking:

  • LOW — .github/workflows/release-check.yml:12 — tag-current (no if guard) now also runs on tag pushes, re-asserting master's VERSION↔tag. PR notes this as intended/harmless and it is self-consistent, so no action required — flagging only so a future reader knows tag pushes trigger both jobs. Optional: gate tag-current with branches: master if you want tag pushes to run the single relevant job.

Good, tightly-scoped change; the check verifies tag content (the silent failure mode tag-current can't see), which is exactly the right teeth.

@ManningWorks
ManningWorks merged commit 7d964d1 into master Sep 28, 2026
7 checks passed
@ManningWorks
ManningWorks deleted the ci/release-check-tag-integrity branch September 28, 2026 15:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant