From 399d2c53318ecf2746e7a7da3a44e459b062fee5 Mon Sep 17 00:00:00 2001 From: Rob Decker <852280+robdecker@users.noreply.github.com> Date: Tue, 22 Sep 2026 12:44:47 -0700 Subject: [PATCH 1/2] ci: allow the release workflow to be triggered manually The first release run failed at startup, because the repository allows only four actions to run and the workflow introduced two more. A run that fails at startup cannot be re-run, and `main` takes no direct pushes, so the only way to retry was to merge another pull request purely to produce a push. Add `workflow_dispatch` so the workflow can be started from the Actions tab once whatever blocked it is fixed. --- .github/workflows/release.yml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 1e90c201..65b28d56 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -4,6 +4,11 @@ on: push: branches: - main + # Manual trigger. A run that fails at startup (a workflow file the runner + # rejects, an action the repository does not allow) cannot be re-run, and + # `main` takes no direct pushes, so without this the only way to retry is + # to merge another pull request. + workflow_dispatch: # Default to read-only. Each job widens only what it needs. permissions: From e2aa91702d761497d237a5c09f2b3e54e2b5328f Mon Sep 17 00:00:00 2001 From: Rob Decker <852280+robdecker@users.noreply.github.com> Date: Tue, 22 Sep 2026 12:48:59 -0700 Subject: [PATCH 2/2] ci: only release from main, now that the workflow can be run by hand Adding `workflow_dispatch` in the previous commit opened a path it should not have. A manual run lets whoever starts it choose the branch, and both the workflow definition and the checked-out code then come from that branch, while npm's trusted publisher matches on repository and workflow filename rather than on ref. So anyone with write access could push a branch, dispatch it, and publish to the `latest` tag without review. That is a regression against the reason `main` requires a reviewed pull request in the first place. Gate both jobs on `github.ref == 'refs/heads/main'`, which leaves the manual trigger useful for retrying a run from `main` and closes the arbitrary-branch path. The check is repeated on the publish job rather than inherited: skipping release-please already skips it, but the job that holds `id-token` and can publish should not rely on another job's condition to stay on `main`. --- .github/workflows/release.yml | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 65b28d56..085aac5d 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -27,7 +27,15 @@ jobs: release-please: runs-on: ubuntu-latest timeout-minutes: 10 - if: github.repository == 'chapter-three/next-drupal' + # The ref check is a security control, not a tidy-up. A manual run lets + # whoever starts it pick the branch, and both this file and the checked-out + # code would then come from that branch, while npm's trusted publisher + # matches on repository and workflow filename rather than on ref. Without + # this, anyone with write access could publish from a branch nobody + # reviewed. Releases come from `main` or they do not happen. + if: >- + github.repository == 'chapter-three/next-drupal' && + github.ref == 'refs/heads/main' # No permissions block: both steps authenticate with the app token, so the # job's own GITHUB_TOKEN stays at the workflow default of contents: read. # The app's permissions are set on the app itself, not here. @@ -63,7 +71,13 @@ jobs: # automatically, so no --provenance flag is needed. publish: needs: release-please - if: needs.release-please.outputs.releases_created == 'true' + # Skipping release-please already skips this job, since its output would be + # empty. The ref check is repeated anyway: this is the job that holds + # id-token and can publish, so it should not depend on another job's + # condition to stay on `main`. + if: >- + needs.release-please.outputs.releases_created == 'true' && + github.ref == 'refs/heads/main' runs-on: ubuntu-latest timeout-minutes: 15 permissions: