Skip to content

Commit 779e0e6

Browse files
theoephraimclaude
andcommitted
Fix version PR not triggering CI workflow runs
Commits pushed with GITHUB_TOKEN don't trigger workflow runs due to GitHub's anti-recursion guard. After the normal git push, recreate the tip commit via the GitHub REST API and force-update the branch ref so that pull_request workflows fire automatically — no PATs, GitHub Apps, or changes to user CI configs needed. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 4063dc4 commit 779e0e6

1 file changed

Lines changed: 48 additions & 0 deletions

File tree

  • packages/bumpy/src/commands

packages/bumpy/src/commands/ci.ts

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,49 @@ async function autoPublish(rootDir: string, config: BumpyConfig, tag?: string):
164164
await publishCommand(rootDir, { tag });
165165
}
166166

167+
// ---- GitHub API push helper ----
168+
169+
/**
170+
* After a normal `git push`, recreate the tip commit via the GitHub REST API
171+
* and force-update the branch ref to point at the API-created commit.
172+
*
173+
* Why: commits pushed with GITHUB_TOKEN don't trigger workflow runs (GitHub's
174+
* anti-recursion guard), but commits created through the REST API *do*.
175+
* The API commit has the same tree and parent so the PR diff is identical.
176+
*/
177+
async function rerouteCommitViaApi(
178+
rootDir: string,
179+
branch: string,
180+
commitMsg: string,
181+
config: BumpyConfig,
182+
): Promise<void> {
183+
const treeSha = runArgs(['git', 'rev-parse', 'HEAD^{tree}'], { cwd: rootDir });
184+
const parentSha = runArgs(['git', 'rev-parse', 'HEAD~1'], { cwd: rootDir });
185+
186+
const commitBody = JSON.stringify({
187+
message: commitMsg,
188+
tree: treeSha,
189+
parents: [parentSha],
190+
author: {
191+
name: config.gitUser.name,
192+
email: config.gitUser.email,
193+
},
194+
});
195+
196+
const apiCommitSha = await runArgsAsync(
197+
['gh', 'api', 'repos/{owner}/{repo}/git/commits', '--input', '-', '--jq', '.sha'],
198+
{ cwd: rootDir, input: commitBody },
199+
);
200+
201+
const refBody = JSON.stringify({ sha: apiCommitSha, force: true });
202+
await runArgsAsync(['gh', 'api', `repos/{owner}/{repo}/git/refs/heads/${branch}`, '-X', 'PATCH', '--input', '-'], {
203+
cwd: rootDir,
204+
input: refBody,
205+
});
206+
207+
log.dim(' Re-pushed commit via GitHub API to trigger workflow runs');
208+
}
209+
167210
// ---- version-pr mode ----
168211

169212
async function createVersionPr(
@@ -209,7 +252,12 @@ async function createVersionPr(
209252

210253
const commitMsg = ['Version packages', '', ...plan.releases.map((r) => `${r.name}@${r.newVersion}`)].join('\n');
211254
runArgs(['git', 'commit', '-F', '-'], { cwd: rootDir, input: commitMsg });
255+
256+
// Push via git first to upload objects, then recreate the commit via the
257+
// GitHub API and force-update the ref. Commits created through the REST API
258+
// *do* trigger workflow runs, whereas commits pushed with GITHUB_TOKEN do not.
212259
runArgs(['git', 'push', '-u', 'origin', branch, '--force'], { cwd: rootDir });
260+
await rerouteCommitViaApi(rootDir, branch, commitMsg, config);
213261

214262
// Create or update PR
215263
const prBody = formatVersionPrBody(plan, config.versionPr.preamble);

0 commit comments

Comments
 (0)