diff --git a/.github/workflows/Semgrep.yml b/.github/workflows/Semgrep.yml index b08eda5ac..f31369bec 100644 --- a/.github/workflows/Semgrep.yml +++ b/.github/workflows/Semgrep.yml @@ -33,8 +33,16 @@ jobs: # suppressions were ignored. See https://semgrep.dev/docs CHANGELOG v1.164.0. image: semgrep/semgrep:1.164.0 - # Skip any PR created by dependabot to avoid permission issues: - if: (github.actor != 'dependabot[bot]') + # Skip any PR created by dependabot to avoid permission issues, and skip the + # automated release PR (opened by github-actions[bot], same repo, release/* + # branch — the Create Release PR workflow posts the required checks for it). + # The release gate is keyed on the PR author, not the branch name (which any + # contributor controls), so a "release/…" branch can't bypass required checks. + if: >- + ${{ github.actor != 'dependabot[bot]' + && !(github.event.pull_request.user.login == 'github-actions[bot]' + && github.event.pull_request.head.repo.full_name == github.repository + && startsWith(github.head_ref, 'release/')) }} steps: # Fetch project source with GitHub Actions Checkout. diff --git a/.github/workflows/executable-check.yml b/.github/workflows/executable-check.yml index c3f320eb5..335905545 100644 --- a/.github/workflows/executable-check.yml +++ b/.github/workflows/executable-check.yml @@ -23,6 +23,15 @@ concurrency: jobs: verify: name: Build & verify executable + # Skip CI only for the automated release PR: opened by github-actions[bot], + # from this same repo, on a release/* branch (the Create Release PR workflow + # posts the required checks as passing for it). Keyed on the PR author, not the + # branch name, so a "release/…" branch can't be used to bypass required checks. + if: >- + ${{ !(github.event_name == 'pull_request' + && github.event.pull_request.user.login == 'github-actions[bot]' + && github.event.pull_request.head.repo.full_name == github.repository + && startsWith(github.head_ref, 'release/')) }} runs-on: macos-latest steps: - uses: actions/checkout@v5 diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index e39ebe855..c86ab011a 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -10,6 +10,15 @@ permissions: jobs: lint: name: Lint + # Skip CI only for the automated release PR: opened by github-actions[bot], + # from this same repo, on a release/* branch (the Create Release PR workflow + # posts the required checks as passing for it). Keyed on the PR author, not the + # branch name, so a "release/…" branch can't be used to bypass required checks. + if: >- + ${{ !(github.event_name == 'pull_request' + && github.event.pull_request.user.login == 'github-actions[bot]' + && github.event.pull_request.head.repo.full_name == github.repository + && startsWith(github.head_ref, 'release/')) }} runs-on: ubuntu-latest steps: - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index ada4b288c..d83506518 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -7,6 +7,16 @@ on: jobs: build: name: Build + # Skip CI only for the automated release PR: opened by github-actions[bot], + # from this same repo, on a release/* branch (the Create Release PR workflow + # posts the required checks as passing for it). The gate is keyed on the PR + # author — NOT the branch name, which any contributor controls — so a PR from + # a "release/…" branch can't be used to bypass required checks. + if: >- + ${{ !(github.event_name == 'pull_request' + && github.event.pull_request.user.login == 'github-actions[bot]' + && github.event.pull_request.head.repo.full_name == github.repository + && startsWith(github.head_ref, 'release/')) }} runs-on: ubuntu-latest steps: - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 @@ -35,6 +45,12 @@ jobs: test: name: Test ${{ matrix.package }} + # Skip only for the automated release PR (see the build job for rationale). + if: >- + ${{ !(github.event_name == 'pull_request' + && github.event.pull_request.user.login == 'github-actions[bot]' + && github.event.pull_request.head.repo.full_name == github.repository + && startsWith(github.head_ref, 'release/')) }} needs: [build] strategy: matrix: @@ -137,6 +153,12 @@ jobs: regression: name: Regression + # Skip only for the automated release PR (see the build job for rationale). + if: >- + ${{ !(github.event_name == 'pull_request' + && github.event.pull_request.user.login == 'github-actions[bot]' + && github.event.pull_request.head.repo.full_name == github.repository + && startsWith(github.head_ref, 'release/')) }} needs: [build] runs-on: ubuntu-latest timeout-minutes: 15 diff --git a/.github/workflows/typecheck.yml b/.github/workflows/typecheck.yml index 466fb94b7..28284162e 100644 --- a/.github/workflows/typecheck.yml +++ b/.github/workflows/typecheck.yml @@ -10,6 +10,15 @@ permissions: jobs: typecheck: name: Typecheck + # Skip CI only for the automated release PR: opened by github-actions[bot], + # from this same repo, on a release/* branch (the Create Release PR workflow + # posts the required checks as passing for it). Keyed on the PR author, not the + # branch name, so a "release/…" branch can't be used to bypass required checks. + if: >- + ${{ !(github.event_name == 'pull_request' + && github.event.pull_request.user.login == 'github-actions[bot]' + && github.event.pull_request.head.repo.full_name == github.repository + && startsWith(github.head_ref, 'release/')) }} runs-on: ubuntu-latest steps: - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 diff --git a/.github/workflows/version-bump.yml b/.github/workflows/version-bump.yml index feb9d19e2..a7cbf6cfd 100644 --- a/.github/workflows/version-bump.yml +++ b/.github/workflows/version-bump.yml @@ -97,6 +97,14 @@ jobs: uses: peter-evans/create-pull-request@271a8d0340265f705b14b6d32b9829c1cb33d45e # v7.0.8 with: token: ${{ secrets.GITHUB_TOKEN }} + # Fully attribute the commit to the GitHub Actions bot (not the human + # who clicked "Run workflow", which is create-pull-request's default + # author). A bot-authored, GITHUB_TOKEN-pushed commit lets GitHub's + # recursion guard suppress the on:pull_request CI runs entirely, so the + # release PR never sits in the "Approve and run workflows" gate — the + # synthetic check runs posted below satisfy branch protection on their own. + author: "github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>" + committer: "github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>" base: master branch: release/${{ steps.bump.outputs.version }} # Only commit version files — never workflow files (GITHUB_TOKEN may diff --git a/.github/workflows/windows.yml b/.github/workflows/windows.yml index 94e057d6a..6ab2edb02 100644 --- a/.github/workflows/windows.yml +++ b/.github/workflows/windows.yml @@ -7,6 +7,15 @@ on: jobs: build: name: Build + # Skip CI only for the automated release PR: opened by github-actions[bot], + # from this same repo, on a release/* branch (the Create Release PR workflow + # posts the required checks as passing for it). Keyed on the PR author, not the + # branch name, so a "release/…" branch can't be used to bypass required checks. + if: >- + ${{ !(github.event_name == 'pull_request' + && github.event.pull_request.user.login == 'github-actions[bot]' + && github.event.pull_request.head.repo.full_name == github.repository + && startsWith(github.head_ref, 'release/')) }} runs-on: windows-latest steps: - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 @@ -35,6 +44,12 @@ jobs: test: name: Test ${{ matrix.package }} + # Skip only for the automated release PR (see the build job for rationale). + if: >- + ${{ !(github.event_name == 'pull_request' + && github.event.pull_request.user.login == 'github-actions[bot]' + && github.event.pull_request.head.repo.full_name == github.repository + && startsWith(github.head_ref, 'release/')) }} needs: [build] strategy: fail-fast: false