Clone of https://github.com/NixOS/nixpkgs.git (to stress-test knotserver)
1name: Get merge commit 2 3description: 'Checks whether the Pull Request is mergeable and checks out the repo at up to two commits: The result of a temporary merge of the head branch into the target branch ("merged"), and the parent of that commit on the target branch ("target"). Handles push events and merge conflicts gracefully.' 4 5inputs: 6 mergedSha: 7 description: "The merge commit SHA, previously collected." 8 type: string 9 merged-as-untrusted: 10 description: "Whether to checkout the merge commit in the ./untrusted folder." 11 type: boolean 12 targetSha: 13 description: "The target commit SHA, previously collected." 14 type: string 15 target-as-trusted: 16 description: "Whether to checkout the target commit in the ./trusted folder." 17 type: boolean 18 19outputs: 20 mergedSha: 21 description: "The merge commit SHA" 22 value: ${{ steps.commits.outputs.mergedSha }} 23 targetSha: 24 description: "The target commit SHA" 25 value: ${{ steps.commits.outputs.targetSha }} 26 27runs: 28 using: composite 29 steps: 30 - id: commits 31 if: ${{ !inputs.mergedSha && !inputs.targetSha }} 32 uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1 33 with: 34 script: | 35 if (context.eventName == 'push') return core.setOutput('mergedSha', context.sha) 36 37 for (const retryInterval of [5, 10, 20, 40, 80]) { 38 console.log("Checking whether the pull request can be merged...") 39 const prInfo = (await github.rest.pulls.get({ 40 owner: context.repo.owner, 41 repo: context.repo.repo, 42 pull_number: context.payload.pull_request.number 43 })).data 44 45 if (prInfo.state != 'open') throw new Error ("PR is not open anymore.") 46 47 if (prInfo.mergeable == null) { 48 console.log(`GitHub is still computing whether this PR can be merged, waiting ${retryInterval} seconds before trying again...`) 49 await new Promise(resolve => setTimeout(resolve, retryInterval * 1000)) 50 continue 51 } 52 53 let mergedSha, targetSha 54 55 if (prInfo.mergeable) { 56 console.log("The PR can be merged.") 57 58 mergedSha = prInfo.merge_commit_sha 59 targetSha = (await github.rest.repos.getCommit({ 60 owner: context.repo.owner, 61 repo: context.repo.repo, 62 ref: prInfo.merge_commit_sha 63 })).data.parents[0].sha 64 } else { 65 console.log("The PR has a merge conflict.") 66 67 mergedSha = prInfo.head.sha 68 targetSha = (await github.rest.repos.compareCommitsWithBasehead({ 69 owner: context.repo.owner, 70 repo: context.repo.repo, 71 basehead: `${prInfo.base.sha}...${prInfo.head.sha}` 72 })).data.merge_base_commit.sha 73 } 74 75 console.log(`Checking the commits:\nmerged:${mergedSha}\ntarget:${targetSha}`) 76 core.setOutput('mergedSha', mergedSha) 77 core.setOutput('targetSha', targetSha) 78 return 79 } 80 throw new Error("Not retrying anymore. It's likely that GitHub is having internal issues: check https://www.githubstatus.com.") 81 82 - if: inputs.merged-as-untrusted && (inputs.mergedSha || steps.commits.outputs.mergedSha) 83 # Would be great to do the checkouts in git worktrees of the existing spare checkout instead, 84 # but Nix is broken with them: 85 # https://github.com/NixOS/nix/issues/6073 86 uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 87 with: 88 ref: ${{ inputs.mergedSha || steps.commits.outputs.mergedSha }} 89 path: untrusted 90 91 - if: inputs.target-as-trusted && (inputs.targetSha || steps.commits.outputs.targetSha) 92 uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 93 with: 94 ref: ${{ inputs.targetSha || steps.commits.outputs.targetSha }} 95 path: trusted