diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 1164567568..de4d684996 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -107,7 +107,22 @@ jobs: if: "${{ !cancelled() && needs.classify_pr.outputs.skip_ci != 'true' }}" runs-on: "${{ fromJSON(needs.classify_pr.outputs.ubuntu_runner || '[\"ubuntu-latest\"]') }}" steps: + # On PRs github.ref is the merge ref (refs/pull/N/merge), so the required + # checks validate the merge result, not just the PR tip. GitHub builds that + # ref asynchronously and it can briefly 404 right after a push, so on + # failure we back off and retry the same ref once. - name: 'Checkout' + id: 'checkout' + uses: 'actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd' # v6.0.2 + continue-on-error: true + with: + ref: '${{ github.event.inputs.branch_ref || github.ref }}' + fetch-depth: 0 + - name: 'Back off for the merge ref to build' + if: "${{ steps.checkout.outcome == 'failure' }}" + run: 'sleep 10' + - name: 'Checkout (retry on transient ref lag)' + if: "${{ steps.checkout.outcome == 'failure' }}" uses: 'actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd' # v6.0.2 with: ref: '${{ github.event.inputs.branch_ref || github.ref }}' @@ -211,9 +226,22 @@ jobs: node-version: '22.x' upload-coverage: 'false' steps: + # See the Lint job's checkout: merge ref on PRs, back off and retry once on transient lag. - name: 'Checkout' + id: 'checkout' if: "${{ needs.classify_pr.outputs.skip_ci != 'true' }}" uses: 'actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd' # v6.0.2 + continue-on-error: true + with: + ref: '${{ github.event.inputs.branch_ref || github.ref }}' + - name: 'Back off for the merge ref to build' + if: "${{ needs.classify_pr.outputs.skip_ci != 'true' && steps.checkout.outcome == 'failure' }}" + run: 'sleep 10' + - name: 'Checkout (retry on transient ref lag)' + if: "${{ needs.classify_pr.outputs.skip_ci != 'true' && steps.checkout.outcome == 'failure' }}" + uses: 'actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd' # v6.0.2 + with: + ref: '${{ github.event.inputs.branch_ref || github.ref }}' # Self-hosted can't reach nodejs.org reliably; reuse the machine's Node. - name: 'Set up Node.js ${{ matrix.node-version }} (hosted)' @@ -288,9 +316,10 @@ jobs: needs: - 'classify_pr' - 'test' + # !cancelled() not always(): don't let a cancelled run hold the concurrency slot here. if: |- ${{ - always() && + !cancelled() && needs.classify_pr.outputs.skip_ci != 'true' && github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name == github.repository