-
Notifications
You must be signed in to change notification settings - Fork 388
pushSignedCommits: surface actionable error with GPG seed instructions on orphan-branch push failure #32365
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
pushSignedCommits: surface actionable error with GPG seed instructions on orphan-branch push failure #32365
Changes from all commits
2086aff
70269bc
25a67ee
6f4ca4d
610b61f
6fb4c95
c2d9a1f
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -645,6 +645,49 @@ describe("push_signed_commits integration tests", () => { | |
| // Return value should be the HEAD SHA. | ||
| expect(result).toBe(expectedSha); | ||
| }); | ||
|
|
||
| it("should throw with manual seeding instructions when orphan-branch git push fails", async () => { | ||
| // Simulate a repo where "Require signed commits" is enforced. The orphan-branch | ||
| // first push uses git push directly, which will be rejected by the remote with | ||
| // GH013. We simulate this by using a bare repo that refuses the push via a | ||
| // pre-receive hook. | ||
| execGit(["checkout", "--orphan", "experiments/signed-required"], { cwd: workDir }); | ||
| execGit(["read-tree", "--empty"], { cwd: workDir }); | ||
| fs.writeFileSync(path.join(workDir, "state.json"), JSON.stringify({ runs: 1 })); | ||
| execGit(["add", "state.json"], { cwd: workDir }); | ||
| execGit(["commit", "-m", "Initial experiment state"], { cwd: workDir }); | ||
|
|
||
| // Install a pre-receive hook in the bare repo that mimics GH013 by rejecting all pushes. | ||
| const hooksDir = path.join(bareDir, "hooks"); | ||
| fs.mkdirSync(hooksDir, { recursive: true }); | ||
| const hookPath = path.join(hooksDir, "pre-receive"); | ||
| fs.writeFileSync(hookPath, "#!/bin/sh\necho 'remote: error: GH013: Repository rule violations found.' >&2\necho 'remote: - Commits must have verified signatures.' >&2\nexit 1\n"); | ||
| fs.chmodSync(hookPath, "0755"); | ||
|
|
||
| // Use the real exec so git push actually runs and hits the hook. | ||
| global.exec = makeRealExec(workDir); | ||
| const githubClient = makeMockGithubClient(); | ||
|
|
||
| let thrownErr; | ||
| try { | ||
| await pushSignedCommits({ | ||
| githubClient, | ||
| owner: "test-owner", | ||
| repo: "test-repo", | ||
| branch: "experiments/signed-required", | ||
| baseRef: "", | ||
| cwd: workDir, | ||
| }); | ||
| } catch (err) { | ||
| thrownErr = err; | ||
| } | ||
| expect(thrownErr).toBeDefined(); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [/tdd] Consider using Vitest's idiomatic await expect(
pushSignedCommits({
githubClient,
owner: "test-owner",
repo: "test-repo",
branch: "experiments/signed-required",
baseRef: "",
cwd: workDir,
})
).rejects.toThrow("failed to push orphan branch");The other assertions on |
||
| expect(thrownErr.message).toContain("failed to push orphan branch"); | ||
| expect(thrownErr.message).toContain("git switch --orphan experiments/signed-required"); | ||
| expect(thrownErr.message).toContain("git commit --allow-empty -S"); | ||
| expect(thrownErr.message).toContain("git push origin experiments/signed-required"); | ||
| expect(thrownErr.message).toContain("signed commits"); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [/tdd] The expect(thrownErr.cause).toBeDefined();
expect(thrownErr.cause.message).toMatch(/GH013|exit code/i);Preserving the original error as |
||
| }); | ||
| }); | ||
|
|
||
| // ────────────────────────────────────────────────────── | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[/diagnose] The parenthetical "(requires a GPG key configured with Git)" is inaccurate — GitHub's Require signed commits rule also accepts SSH-signed commits (
git config gpg.format ssh). A user with only an SSH signing key will follow this message and spend time on GPG setup they don't need.Suggest widening the wording:
`Run the following commands locally (requires a signing key — GPG or SSH — configured with Git):`Or simply drop the parenthetical and let the
git commit --allow-empty -Scommand surface its own error for users who haven't configured signing.