Skip to content

fix(ci): sync versions in release pre-commit hook so tags are not stale#29

Merged
antonbabenko merged 1 commit into
masterfrom
fix/release-tag-sync-pre-commit-hook
May 18, 2026
Merged

fix(ci): sync versions in release pre-commit hook so tags are not stale#29
antonbabenko merged 1 commit into
masterfrom
fix/release-tag-sync-pre-commit-hook

Conversation

@antonbabenko
Copy link
Copy Markdown
Owner

Problem

conventional-changelog-action commits + tags + pushes, then the old step 2b amended the branch and force-pushed. The tag never moved, so vX.Y.Z (which antonbabenko/agent-plugins pins) pointed at a pre-sync tree.

Verified live: tag v1.13.0 (commit 2835989) != master tip; at the tag both skills/terraform-skill/SKILL.md and .codex-plugin/plugin.json carried 1.12.0 while the release was 1.13.0. version.json was correct (action bumps it natively before its commit).

Fix

  • Move SKILL.md + .codex-plugin/plugin.json version sync into the action's pre-commit hook (.github/release/pre-commit.js), which runs before the action's git add/commit/tag, so the synced files land in the release commit AND the tag.
  • Delete step 2b entirely: no more git commit --amend, no more git push --force-with-lease. No --force anywhere in the workflow.
  • version.json stays action-owned. skip-ci: 'true' set explicitly.
  • Expand validate.yml triggers to cover .github/workflows/** and .github/release/** so this PR exercises the sync check.

Hook: Node built-ins only, zero deps. Resolves root from GITHUB_WORKSPACE || cwd with a version.json sentinel; value-only anchored replace of the manifest version line (position / trailing-comma / byte-layout independent); throws (fails the release job) on any missing version line; explicit in-hook git add (the action only auto-stages version-file + changelog).

Verification done (local)

Scenario Result
success SKILL.md + manifest synced and staged, worktree clean, 2-space indent preserved, manifest valid JSON, layout intact
SKILL version line missing hook throws, non-zero
manifest version line missing hook throws, non-zero
manifest absent skips cleanly, resolves
sentinel missing hook throws, non-zero

Gated before merge (do NOT merge until done)

  1. Scratch-fork pipeline dry-run: push a fix: commit on a fork, assert the produced vX.Y.Z tag == release commit (single commit), git show <tag>: for SKILL.md + manifest carry the new version, .codex-plugin/ present at tag, version.json correct, no --force in final workflow.
  2. Confirm master branch protection / required checks allow the action's existing non-force bot push.

Plan converged via GPT + Gemini + Claude consensus (2 rounds). Draft until 1-2 pass.

conventional-changelog-action committed+tagged+pushed, then the old
step 2b amended the branch and force-pushed - the tag never moved, so
vX.Y.Z (which agent-plugins pins) pointed at a pre-sync tree. Verified:
tag v1.13.0 carried SKILL.md/.codex-plugin version 1.12.0 while the
release was 1.13.0.

Move the SKILL.md + .codex-plugin/plugin.json sync into the action's
pre-commit hook (.github/release/pre-commit.js), which runs before the
action's git add/commit/tag, so the synced files are in the release
commit and the tag. Delete step 2b entirely (no more amend, no more
--force push). version.json stays action-owned. Set skip-ci:'true'
explicitly. Expand validate.yml triggers to cover workflow/hook paths.

Plan converged via GPT+Gemini+Claude consensus (2 rounds).
@antonbabenko antonbabenko marked this pull request as ready for review May 18, 2026 09:25
@antonbabenko
Copy link
Copy Markdown
Owner Author

Gated verification complete - both passed

1. Scratch-repo pipeline dry-run (throwaway private repo, real automated-release.yml run, conclusion: success):

Check Result
tag commit == master tip MATCH - atomic single release commit+tag (no amend, no 2nd commit)
version.json @ tag correct
skills/terraform-skill/SKILL.md @ tag synced
.codex-plugin/plugin.json @ tag synced, file present at tag
all 4 files in ONE release commit yes (action stages version-file+CHANGELOG, hook stages SKILL.md+manifest)
--force in final workflow none
[skip ci] in release commit present (no retrigger loop)

The exact defect (tag pointing at a pre-sync tree) is resolved: synced files are now inside the tag the marketplace pins.

2. Branch protection / token: master is not protected, no rulesets; the workflow declares permissions: contents: write (overrides the repo default read). The action's existing non-force push works; no settings change required.

Observation (not a blocker): in the scratch run the bump was major; that is the conventional-changelog action's own semver math over the scratch commit range. On real merge this PR squashes as fix(ci): ... -> patch. Confirm the expected bump at merge.

Draft lifted. Ready for review.

@antonbabenko antonbabenko merged commit 6ca340d into master May 18, 2026
1 check passed
@antonbabenko antonbabenko deleted the fix/release-tag-sync-pre-commit-hook branch May 18, 2026 09:53
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