Skip to content

Commit 66198bd

Browse files
theoephraimclaude
andcommitted
Fix tag pushing and GitHub release creation
`git push --follow-tags` only pushes annotated tags reachable from pushed commits. Since bumpy creates lightweight tags and may have no new commits, tags were silently not being pushed, causing `gh release create` to fail with "tag exists locally but has not been pushed". - Switch to `git push` + `git push --tags` to ensure lightweight tags are pushed - Pass `--target <SHA>` to `gh release create` as a fallback Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 7b59cb2 commit 66198bd

3 files changed

Lines changed: 37 additions & 7 deletions

File tree

.bumpy/fix-tag-push-and-release.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
---
2+
'@varlock/bumpy': patch
3+
---
4+
5+
Fix git tag pushing and GitHub release creation
6+
7+
- Use `git push --tags` instead of `--follow-tags` so lightweight tags are actually pushed to the remote
8+
- Pass `--target` commit SHA to `gh release create` as a fallback in case tags haven't propagated

packages/bumpy/src/core/git.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,11 @@ export function createTag(tag: string, opts?: { cwd?: string }): void {
77

88
/** Push commits and tags to remote */
99
export function pushWithTags(opts?: { cwd?: string }): void {
10-
run('git push --follow-tags', opts);
10+
// Use `--tags` instead of `--follow-tags` because:
11+
// - `--follow-tags` only pushes *annotated* tags reachable from pushed commits
12+
// - We create lightweight tags and may have no new commits to push
13+
run('git push', opts);
14+
run('git push --tags', opts);
1115
}
1216

1317
/** Check if there are uncommitted changes */

packages/bumpy/src/core/github-release.ts

Lines changed: 24 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,11 @@ import { tryRun, runAsync } from '../utils/shell.ts';
22
import { log } from '../utils/logger.ts';
33
import type { PlannedRelease, Changeset } from '../types.ts';
44

5+
/** Get the current HEAD commit SHA */
6+
function getHeadSha(rootDir: string): string | null {
7+
return tryRun('git rev-parse HEAD', { cwd: rootDir });
8+
}
9+
510
export interface GitHubReleaseOptions {
611
dryRun?: boolean;
712
title?: string;
@@ -19,6 +24,8 @@ export async function createIndividualReleases(
1924
return;
2025
}
2126

27+
const headSha = getHeadSha(rootDir);
28+
2229
for (const release of releases) {
2330
const tag = `${release.name}@${release.newVersion}`;
2431
const body = buildReleaseBody(release, changesets);
@@ -30,9 +37,14 @@ export async function createIndividualReleases(
3037
}
3138

3239
try {
33-
await runAsync(`gh release create "${tag}" --title "${escapeShell(title)}" --notes "${escapeShell(body)}"`, {
34-
cwd: rootDir,
35-
});
40+
// Use --target so gh can create the tag on the remote if it wasn't pushed yet
41+
const targetFlag = headSha ? ` --target "${headSha}"` : '';
42+
await runAsync(
43+
`gh release create "${tag}" --title "${escapeShell(title)}" --notes "${escapeShell(body)}"${targetFlag}`,
44+
{
45+
cwd: rootDir,
46+
},
47+
);
3648
log.dim(` Created GitHub release: ${title}`);
3749
} catch (err) {
3850
log.warn(` Failed to create GitHub release for ${tag}: ${err instanceof Error ? err.message : err}`);
@@ -72,9 +84,15 @@ export async function createAggregateRelease(
7284
// Create the tag if it doesn't exist
7385
tryRun(`git tag "${tag}"`, { cwd: rootDir });
7486

75-
await runAsync(`gh release create "${tag}" --title "${escapeShell(title)}" --notes "${escapeShell(body)}"`, {
76-
cwd: rootDir,
77-
});
87+
// Use --target so gh can create the tag on the remote if it wasn't pushed yet
88+
const headSha = getHeadSha(rootDir);
89+
const targetFlag = headSha ? ` --target "${headSha}"` : '';
90+
await runAsync(
91+
`gh release create "${tag}" --title "${escapeShell(title)}" --notes "${escapeShell(body)}"${targetFlag}`,
92+
{
93+
cwd: rootDir,
94+
},
95+
);
7896
log.success(`Created aggregate GitHub release: ${title}`);
7997
} catch (err) {
8098
log.warn(`Failed to create aggregate GitHub release: ${err instanceof Error ? err.message : err}`);

0 commit comments

Comments
 (0)