From b21831f483cc961322542dc037db99579b030449 Mon Sep 17 00:00:00 2001 From: Oleg S <97077423+RobotSail@users.noreply.github.com> Date: Tue, 14 Apr 2026 19:37:55 -0400 Subject: [PATCH] fix: support fork PRs by fetching via refs/pull/N/head For cross-repository (fork) PRs, the head branch doesn't exist on the origin remote. The action previously tried `git fetch origin ` which fails with "couldn't find remote ref". Now detects fork PRs via `isCrossRepository` from the GraphQL API and fetches using `pull//head:` refspec instead, which GitHub exposes for all PR heads regardless of source repo. Changes: - Add `isCrossRepository` to PR GraphQL query and type - Use `refs/pull/N/head` refspec for fork PRs in setupBranch() Fixes #1218 --- src/github/api/queries/github.ts | 1 + src/github/operations/branch.ts | 15 ++++++++++++++- src/github/types.ts | 1 + test/data-formatter.test.ts | 1 + 4 files changed, 17 insertions(+), 1 deletion(-) diff --git a/src/github/api/queries/github.ts b/src/github/api/queries/github.ts index 7bceb8f9d..c5257ea19 100644 --- a/src/github/api/queries/github.ts +++ b/src/github/api/queries/github.ts @@ -12,6 +12,7 @@ export const PR_QUERY = ` baseRefName headRefName headRefOid + isCrossRepository createdAt updatedAt lastEditedAt diff --git a/src/github/operations/branch.ts b/src/github/operations/branch.ts index b2c145b7a..2f9e58226 100644 --- a/src/github/operations/branch.ts +++ b/src/github/operations/branch.ts @@ -168,7 +168,20 @@ export async function setupBranch( // Execute git commands to checkout PR branch (dynamic depth based on PR size) // Using execFileSync instead of shell template literals for security - execGit(["fetch", "origin", `--depth=${fetchDepth}`, branchName]); + // For fork PRs, the branch doesn't exist on origin - use refs/pull/N/head instead + if (prData.isCrossRepository) { + console.log( + `Fork PR detected, fetching via refs/pull/${entityNumber}/head`, + ); + execGit([ + "fetch", + "origin", + `--depth=${fetchDepth}`, + `pull/${entityNumber}/head:${branchName}`, + ]); + } else { + execGit(["fetch", "origin", `--depth=${fetchDepth}`, branchName]); + } execGit(["checkout", branchName, "--"]); console.log(`Successfully checked out PR branch for PR #${entityNumber}`); diff --git a/src/github/types.ts b/src/github/types.ts index d982620da..4c39bbe0e 100644 --- a/src/github/types.ts +++ b/src/github/types.ts @@ -57,6 +57,7 @@ export type GitHubPullRequest = { baseRefName: string; headRefName: string; headRefOid: string; + isCrossRepository: boolean; createdAt: string; updatedAt?: string; lastEditedAt?: string; diff --git a/test/data-formatter.test.ts b/test/data-formatter.test.ts index 4c6b150dd..ec2d78f65 100644 --- a/test/data-formatter.test.ts +++ b/test/data-formatter.test.ts @@ -24,6 +24,7 @@ describe("formatContext", () => { baseRefName: "main", headRefName: "feature/test", headRefOid: "abc123", + isCrossRepository: false, createdAt: "2023-01-01T00:00:00Z", additions: 50, deletions: 30,