From 5842dd07982cea842f87c0a0230aca45eafd1ae7 Mon Sep 17 00:00:00 2001 From: John Carmack Date: Mon, 10 Aug 2026 09:33:04 -0500 Subject: [PATCH] ci: dispatch CI onto release-please PRs so required checks report GitHub now gates pull_request workflow runs from bot-authored PRs behind manual approval, so CI never starts on the release-please PR and its required checks (test/npm/deny, pinned to the Actions app) sit at Expected forever, blocking the release PR. Dispatch ci.yml onto the release branch from the release workflow instead: a workflow_dispatch run carrying GITHUB_TOKEN is exempt from the approval gate and produces real Actions check runs. The jobs' release-please skip guard now also matches ref_name, so the dispatched run reports the checks green in seconds without re-running the suite. --- .github/workflows/ci.yml | 27 ++++++++++++++++----------- .github/workflows/release.yml | 19 +++++++++++++++++++ 2 files changed, 35 insertions(+), 11 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 452315c..5563435 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -11,18 +11,22 @@ name: CI # workflows), and main is already CI-gated on every push via the workflow_call # above, so re-running the whole suite on that PR is pure redundancy — yet its # three jobs are required status checks, so the PR can't merge until they report. -# release-please commits with GITHUB_TOKEN, whose events don't reliably trigger -# this workflow, so those checks would otherwise sit unreported and the release -# PR would stay blocked, needing a human to re-trigger CI. Instead each job below -# skips itself on the release-please branch; a skipped job reports Success and so -# satisfies the required check, letting the release PR go green with no -# intervention. On a workflow_call from a push the head_ref is empty, so the full -# suite still runs on main. (If a fourth required check is ever added, give it the -# same guard.) +# The catch: release-please authors that PR as github-actions[bot], and GitHub +# gates the pull_request run from a bot-authored PR behind manual approval, so it +# never starts, no check runs are created, and the required checks sit unreported +# forever. So release.yml dispatches this workflow (workflow_dispatch) onto the +# release-please branch instead — API-triggered runs carrying GITHUB_TOKEN are +# exempt from that approval gate and do start. Each job below skips itself on the +# release-please branch (matched via head_ref on a PR run, or ref_name on the +# dispatched run); a skipped job reports Success and so satisfies the required +# check, letting the release PR go green with no intervention. On a workflow_call +# from a push the ref_name is 'main', so the full suite still runs on main. (If a +# fourth required check is ever added, give it the same guard.) on: pull_request: workflow_call: + workflow_dispatch: permissions: contents: read @@ -38,7 +42,8 @@ jobs: test: # Skip on release-please's PR (see header) — a skipped job counts as a # passing required check, so the release PR merges without a full CI re-run. - if: ${{ !startsWith(github.head_ref, 'release-please--') }} + # head_ref matches the PR run; ref_name the workflow_dispatch run. + if: ${{ !startsWith(github.head_ref, 'release-please--') && !startsWith(github.ref_name, 'release-please--') }} runs-on: ubuntu-latest timeout-minutes: 15 env: @@ -72,7 +77,7 @@ jobs: # the real binary through the wrapper's shim. Without this, a broken # resolver or a platform table that has drifted from the wrapper's # optionalDependencies would only surface after publishing. - if: ${{ !startsWith(github.head_ref, 'release-please--') }} + if: ${{ !startsWith(github.head_ref, 'release-please--') && !startsWith(github.ref_name, 'release-please--') }} runs-on: ubuntu-latest timeout-minutes: 15 env: @@ -135,7 +140,7 @@ jobs: run: sccache --show-stats deny: - if: ${{ !startsWith(github.head_ref, 'release-please--') }} + if: ${{ !startsWith(github.head_ref, 'release-please--') && !startsWith(github.ref_name, 'release-please--') }} runs-on: ubuntu-latest timeout-minutes: 10 steps: diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index f77a093..56e02f1 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -34,12 +34,31 @@ jobs: needs: ci runs-on: ubuntu-latest timeout-minutes: 10 + # A job-level block replaces the inherited perms, so restate them; actions: + # write is new, for the `gh workflow run` in the dispatch step below. + permissions: + contents: write + pull-requests: write + actions: write outputs: release_created: ${{ steps.release.outputs.release_created }} tag_name: ${{ steps.release.outputs.tag_name }} steps: - uses: googleapis/release-please-action@45996ed1f6d02564a971a2fa1b5860e934307cf7 # v5.0.0 id: release + # release-please authors the release PR as github-actions[bot], and GitHub + # gates a bot-authored PR's pull_request run behind manual approval, so + # ci.yml never starts there and its app-pinned required checks (test/npm/ + # deny) sit unreported. Dispatch ci.yml onto the release branch instead: a + # workflow_dispatch run carrying GITHUB_TOKEN skips that approval gate, and + # its jobs self-skip on the release-please branch, reporting the required + # checks green in seconds. prs_created is true when a PR was created or + # updated; on a merge push that only cuts a release it's false and this skips. + - name: Dispatch CI onto the release PR + if: ${{ steps.release.outputs.prs_created == 'true' }} + env: + GH_TOKEN: ${{ github.token }} + run: gh workflow run ci.yml --repo "$GITHUB_REPOSITORY" --ref "${{ fromJSON(steps.release.outputs.pr).headBranchName }}" build: needs: release-please