diff --git a/__tests__/resolve-payload-fields.test.ts b/__tests__/resolve-payload-fields.test.ts index 0db6a3c6..350cc200 100644 --- a/__tests__/resolve-payload-fields.test.ts +++ b/__tests__/resolve-payload-fields.test.ts @@ -14,6 +14,7 @@ const payload = { githubToken: 'ghs_token', headHttpUrl: 'https://github.com/acme/repo.git', repoUrl: 'https://github.com/acme/other.git', + pullRequestNumber: 269, owner: 'acme', hasCmRepo: true, cmRepo: 'cm-repo', @@ -50,6 +51,7 @@ describe('toStepOutputs', () => { expect(toStepOutputs(payload)).toEqual({ github_token: 'ghs_token', url: 'https://github.com/acme/repo.git', + pull_request_number: '269', has_cm_repo: 'true', cm_repository: 'acme/cm-repo', cm_repo_ref: 'main', @@ -58,12 +60,22 @@ describe('toStepOutputs', () => { }) }) + it.each([1.2, -1, 0, Infinity, 'abc'])( + 'blanks a pull request number that is not a positive integer: %p', + pullRequestNumber => { + expect( + toStepOutputs({ ...payload, pullRequestNumber }).pull_request_number + ).toBe('') + } + ) + it('falls back to repoUrl and blanks the cm repo when absent', () => { expect( toStepOutputs({ repoUrl: 'https://github.com/acme/other.git' }) ).toEqual({ github_token: '', url: 'https://github.com/acme/other.git', + pull_request_number: '', has_cm_repo: 'false', cm_repository: '', cm_repo_ref: '', diff --git a/action.yml b/action.yml index a15150f6..341089bd 100644 --- a/action.yml +++ b/action.yml @@ -104,7 +104,8 @@ runs: git config checkout.defaultRemote origin git fetch --shallow-since="6 months ago" origin $'${{ steps.safe-strings.outputs.base_ref }}' git remote add upstream $'${{ steps.safe-strings.outputs.url }}' - git fetch --shallow-since="6 months ago" upstream $'${{ steps.safe-strings.outputs.head_ref }}' || echo "::warning::Failed to fetch head branch. The branch may have been deleted." + # refs/pull/N/head is mirrored on the base repo, so a fork PR head needs no fork access. + git fetch --shallow-since="6 months ago" origin $'refs/pull/${{ steps.payload-fields.outputs.pull_request_number }}/head:refs/remotes/upstream/${{ steps.safe-strings.outputs.head_ref }}' || echo "::warning::Failed to fetch head branch. The branch may have been deleted." git checkout -b $'upstream/${{ steps.safe-strings.outputs.head_ref}}' $'upstream/${{ steps.safe-strings.outputs.head_ref}}' || true git checkout $'${{ steps.safe-strings.outputs.base_ref }}' || true git checkout $'${{ steps.safe-strings.outputs.head_ref }}' || true diff --git a/scripts/resolve-payload-fields.js b/scripts/resolve-payload-fields.js index 717c7ff5..35edde91 100644 --- a/scripts/resolve-payload-fields.js +++ b/scripts/resolve-payload-fields.js @@ -155,9 +155,13 @@ function normalizeForEngine(raw) { */ function toStepOutputs(payload) { const hasCmRepo = payload.hasCmRepo === true + const prNumber = Number(payload.pullRequestNumber) + // A positive integer or '': spliced into the fetch refspec without the safe-strings escaping step. + const isPrNumber = Number.isInteger(prNumber) && prNumber > 0 return { github_token: payload.githubToken || '', url: payload.headHttpUrl || payload.repoUrl || '', + pull_request_number: isPrNumber ? String(prNumber) : '', has_cm_repo: String(hasCmRepo), cm_repository: hasCmRepo ? `${payload.owner}/${payload.cmRepo}` : '', cm_repo_ref: payload.cmRepoRef || '',