verifyReleaseRef ensures HEAD is exactly the tip of the remote default branch before any tags are created. The tool tags the current HEAD and pushes the tag immediately, but the downstream "chore: bump" commit it creates afterwards is only committed locally — gitPushTags pushes tags, never the bran
(ctx context.Context)
| 302 | // fixes merged via PRs. Refuse to tag unless HEAD matches the fetched remote |
| 303 | // default branch tip. |
| 304 | func verifyReleaseRef(ctx context.Context) error { |
| 305 | branch := remoteDefaultBranch(ctx) |
| 306 | if out, err := runGit(ctx, "fetch", "origin", branch); err != nil { |
| 307 | return fmt.Errorf("git fetch origin %s (%s): %s", branch, err, out) |
| 308 | } |
| 309 | head, err := revParse(ctx, "HEAD") |
| 310 | if err != nil { |
| 311 | return err |
| 312 | } |
| 313 | remote, err := revParse(ctx, "refs/remotes/origin/"+branch) |
| 314 | if err != nil { |
| 315 | return err |
| 316 | } |
| 317 | if head != remote { |
| 318 | return fmt.Errorf("refusing to tag: HEAD (%s) is not at the tip of origin/%s (%s); "+ |
| 319 | "merge/pull the remote default branch and ensure any local 'chore: bump' commit is pushed before releasing", |
| 320 | head, branch, remote) |
| 321 | } |
| 322 | return nil |
| 323 | } |
| 324 | |
| 325 | // remoteDefaultBranch resolves origin's default branch, falling back to "main" |
| 326 | // when origin/HEAD is not configured locally. |