Skip to content

fix(release): refuse to tag unless HEAD is at the remote default tip#553

Merged
Benehiko merged 2 commits into
mainfrom
fix/release-verify-head
Jun 8, 2026
Merged

fix(release): refuse to tag unless HEAD is at the remote default tip#553
Benehiko merged 2 commits into
mainfrom
fix/release-verify-head

Conversation

@Benehiko
Copy link
Copy Markdown
Member

@Benehiko Benehiko commented Jun 5, 2026

Why

store/v0.0.28 was tagged on 1de02f4 — the chore: bump store/v0.0.27 commit — which predates the Linux keychain DH fix (#548) that had already merged via PRs. Consumers bumping to v0.0.28 therefore did not get the fix, surfacing downstream (sandboxes, docker-auth) as intermittent unexpected end of JSON input when decoding credentials.

Root cause is in the release tool:

  • BumpModule tags the current HEAD and pushes the tag, then creates the chore: bump commit.
  • gitPushTags pushes tags only — the bump commit stays local.
  • On a re-run, if HEAD is sitting on such a local-only bump commit, the new tag lands on a commit that is not on the remote default branch and misses anything merged afterwards.

What

  • Before creating any tag, git fetch and verify HEAD equals the tip of the remote default branch (origin/HEAD, falling back to main); refuse otherwise with an actionable error.
  • Skipped in --dry / --skip-git modes (they create no tags).
  • Integration test (temp repo + bare remote) covering in-sync, local-only-commit, and pushed cases.
  • docs/releasing.md documents the workflow and the guard.

Note

store/v0.0.28 is left in place (already on the GOPROXY; deleting would break anyone pinned to it). store/v0.0.29 was cut on main HEAD with the fix and is the version consumers should use.

Test plan

  • go test ./release/... — passes
  • golangci-lint run -c ../.golangci.yml ./release/... — 0 issues

🤖 Generated with Claude Code

The release tool tags whatever HEAD points at and pushes the tag, but the
downstream "chore: bump" commit it creates afterwards is only committed
locally (gitPushTags pushes tags, never the branch). When the tool is re-run
while HEAD sits on such a local-only bump commit, the new tag lands on a
commit that is not on the remote default branch.

That is how store/v0.0.28 ended up pinned to the "chore: bump store/v0.0.27"
commit, shipping a store release that predated — and therefore did not
contain — a Linux keychain fix that had already merged via PRs.

Before creating any tag, fetch and verify HEAD equals the tip of the remote
default branch (origin/HEAD, falling back to main); refuse otherwise. The
check is skipped in --dry and --skip-git modes since they create no tags.

Adds an integration test (temp repo + bare remote) covering the in-sync,
local-only-commit, and pushed cases, and documents the release workflow and
guard in docs/releasing.md.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Copy link
Copy Markdown

@docker-agent docker-agent Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Assessment: 🟡 NEEDS ATTENTION

3 medium-severity findings in the new release guard and its tests.

Comment thread x/release/command.go
Comment thread x/release/command_test.go
Comment thread x/release/command_test.go
…et origin/HEAD

- Subtest 3 now creates a local-only commit and asserts failure before
  pushing, so the fail -> push -> pass recovery path is exercised even
  when the subtest runs in isolation.
- remoteDefaultBranch logs a diagnostic to stderr when origin/HEAD is
  unset, so a wrong "main" assumption is visible instead of surfacing as
  a confusing "couldn't find remote ref" fetch error.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@Benehiko Benehiko requested a review from joe0BAB June 8, 2026 11:43
@Benehiko Benehiko merged commit 22b2748 into main Jun 8, 2026
35 checks passed
@Benehiko Benehiko deleted the fix/release-verify-head branch June 8, 2026 13:02
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.

2 participants