Skip to content

Commit 3a66c1c

Browse files
committed
fix(open-pr): keep retry pushes on recorded commits
1 parent 28631a0 commit 3a66c1c

3 files changed

Lines changed: 31 additions & 3 deletions

File tree

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77
- Added review prompt provenance and budget accounting for included files, omitted files, prompt bytes, and approximate tokens.
88
- Hardened review ingestion so provider findings must cite included files with valid line ranges and matching evidence quotes.
99
- Fixed `clawpatch open-pr` so repositories without default-branch metadata use a dedicated patch branch and let GitHub choose the PR base.
10+
- Fixed `clawpatch open-pr` retries to push the recorded patch commit instead of any later local branch tip.
11+
- Fixed `clawpatch ci --since` empty-review output so it reports `reviewed: 0`.
1012
- Fixed Express route mapping for aliased Router imports that follow block comment banners, thanks @rohitjavvadi.
1113
- Fixed Bun package-manager detection to recognize the text `bun.lock` lockfile, thanks @austinm911.
1214

src/app.ts

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -257,7 +257,7 @@ export async function ciCommand(
257257
return {
258258
initialized,
259259
mapped: numberField(mapped, "features"),
260-
reviewed: numberField(reviewed, "reviewed"),
260+
reviewed: numberField(reviewed, "reviewed") ?? 0,
261261
findings: reviewFindings,
262262
reportFindings: report.findings ?? 0,
263263
report: report.output ?? null,
@@ -1117,6 +1117,7 @@ export async function openPrCommand(
11171117
force,
11181118
);
11191119
let commitSha = patch.git.commitSha;
1120+
const hadRecordedCommit = commitSha !== null;
11201121
if (commitSha === null) {
11211122
if (git.currentBranch !== branch) {
11221123
const switchArgs = (await localBranchExists(git.root, branch))
@@ -1160,7 +1161,11 @@ export async function openPrCommand(
11601161
prUrl: patch.git.prUrl,
11611162
});
11621163
}
1163-
await checkedRun("git push", runCommandArgs("git", ["push", "-u", "origin", branch], git.root));
1164+
commitSha = assertDefined(commitSha, "missing patch commit");
1165+
const pushArgs = hadRecordedCommit
1166+
? ["push", "origin", `${commitSha}:refs/heads/${branch}`]
1167+
: ["push", "-u", "origin", branch];
1168+
await checkedRun("git push", runCommandArgs("git", pushArgs, git.root));
11641169
const ghArgs = prCreateArgs(base, branch, title, draft);
11651170
const gh = await checkedRun("gh pr create", runCommandArgs(githubCli(), ghArgs, git.root, body));
11661171
const prUrl = firstUrl(gh.stdout) ?? gh.stdout.trim();
@@ -1537,7 +1542,11 @@ function plannedPrCommands(
15371542
}
15381543
commands.push(`git commit -m ${shellArg(title)} -- ${shellPathspecArgs(commitFiles)}`);
15391544
}
1540-
commands.push(`git push -u origin ${shellArg(branch)}`);
1545+
commands.push(
1546+
patch.git.commitSha === null
1547+
? `git push -u origin ${shellArg(branch)}`
1548+
: `git push origin ${shellArg(`${patch.git.commitSha}:refs/heads/${branch}`)}`,
1549+
);
15411550
commands.push(`gh ${prCreateArgs(base, branch, title, draft).map(shellArg).join(" ")}`);
15421551
return commands;
15431552
}

src/workflow.test.ts

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -517,6 +517,7 @@ describe("workflow", () => {
517517
const summary = await readFile(summaryPath, "utf8");
518518

519519
expect(result).toMatchObject({
520+
reviewed: 0,
520521
findings: 0,
521522
reportFindings: 1,
522523
});
@@ -3721,6 +3722,16 @@ describe("workflow", () => {
37213722
);
37223723
expect(afterFailure?.git.commitSha).toMatch(/^[a-f0-9]{40}$/u);
37233724
expect(afterFailure?.git.branchName).toBe("clawpatch/pat_open_pr_retry");
3725+
const recordedCommit = afterFailure?.git.commitSha;
3726+
if (recordedCommit === null || recordedCommit === undefined) {
3727+
throw new Error("missing recorded patch commit");
3728+
}
3729+
3730+
await writeFixture(root, "src/unrelated.ts", "export const unrelated = true;\n");
3731+
await checkCommand(root, "git add src/unrelated.ts");
3732+
await checkCommand(root, 'git -c commit.gpgsign=false commit -q -m "unrelated"');
3733+
const advancedHead = (await runCommand("git rev-parse HEAD", root)).stdout.trim();
3734+
expect(advancedHead).not.toBe(recordedCommit);
37243735

37253736
process.env["CLAWPATCH_GH"] = successGh;
37263737
await expect(
@@ -3731,6 +3742,12 @@ describe("workflow", () => {
37313742
).resolves.toMatchObject({
37323743
pr: "https://github.com/openclaw/clawpatch/pull/999",
37333744
});
3745+
const remoteHead = (
3746+
await runCommand("git ls-remote --heads origin clawpatch/pat_open_pr_retry", root)
3747+
).stdout
3748+
.trim()
3749+
.split(/\s+/u)[0];
3750+
expect(remoteHead).toBe(recordedCommit);
37343751
} finally {
37353752
if (previousGh === undefined) {
37363753
delete process.env["CLAWPATCH_GH"];

0 commit comments

Comments
 (0)