diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 1c803f9..7cdb1b7 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -1,13 +1,50 @@ name: CI on: - push: - branches: [main] pull_request: + types: [opened, synchronize, reopened, ready_for_review] + +permissions: + contents: read + +concurrency: + group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}-${{ github.event.pull_request.draft }} + cancel-in-progress: true jobs: + gate: + if: github.event.pull_request.draft == false + runs-on: ubuntu-latest + timeout-minutes: 3 + outputs: + run: ${{ steps.base.outputs.run }} + steps: + - id: base + env: + GH_TOKEN: ${{ github.token }} + REPO: ${{ github.repository }} + BASE: ${{ github.base_ref }} + HEAD_SHA: ${{ github.event.pull_request.head.sha }} + # The gate never fails a PR. A behind branch skips the check with a notice; + # an API error runs it, since a skipped check would read as a pass. + run: | + behind=$(gh api "repos/$REPO/compare/$BASE...$HEAD_SHA" --jq .behind_by) || behind="" + if [ -z "$behind" ]; then + echo "::warning::Could not compare with $BASE. Running CI anyway." + echo "run=true" >> "$GITHUB_OUTPUT" + elif [ "$behind" = "0" ]; then + echo "run=true" >> "$GITHUB_OUTPUT" + else + echo "::notice::This branch is $behind commits behind $BASE. Update it to run CI." + echo "run=false" >> "$GITHUB_OUTPUT" + fi + check: + needs: gate + if: needs.gate.outputs.run == 'true' runs-on: ubuntu-latest + # The whole job takes under a minute. A hang should cost minutes, not hours. + timeout-minutes: 15 steps: - uses: actions/checkout@v4