Skip to content

ci: run the checks on pull requests, and never publish from one - #2

Merged
cmonaco0317 merged 1 commit into
mainfrom
ci-pr-trigger
Aug 11, 2026
Merged

ci: run the checks on pull requests, and never publish from one#2
cmonaco0317 merged 1 commit into
mainfrom
ci-pr-trigger

Conversation

@cmonaco0317

Copy link
Copy Markdown
Owner

deploy.yml triggered only on push to main, so test, copy-drift and
build first ran after a change had landed. That is how README.md and
SECURITY.md sat on a public page claiming npm audit reports 0 advisories while
it actually reported 4 — nothing ran the assertion until a merge did.

Two guards had to go in before this was safe:

  • deploy is gated to push-on-main. It publishes straight to the live site,
    so without this a PR could publish itself.
  • The concurrency group is keyed by ref. It was a single pages group with
    cancel-in-progress, so opening a PR would have cancelled an in-flight deploy
    of main and left the site mid-update.

This PR is its own test: pull_request runs are evaluated against the merge
commit's workflow file, so if the checks appear below, the trigger works.

🤖 Generated with Claude Code

Until now deploy.yml triggered only on push to main, so the test, copy-drift and
build jobs first executed AFTER a change had already landed. That is how a stale
`npm audit` figure sat in README.md and SECURITY.md claiming 0 advisories while
the real count was 4: nothing ran the assertion until a merge did, and by then
the false claim was already on a public page.

Two things had to be true before this was safe to switch on:

- `deploy` must not run on a pull request. It pushes whatever was built straight
  to the public site, so without a guard this change would let any PR publish
  itself. Gated to push-on-main.

- The concurrency group must not be shared. It was a single `pages` group with
  cancel-in-progress, so a PR opening would have cancelled an in-flight deploy of
  main and left the published site mid-update. Keyed by ref now; deploys still
  serialise against each other because they all run on refs/heads/main.

Note this makes `github.head_ref` reachable for the first time in the copy-drift
job — on a fork PR that value is attacker-influencable. It was already handled
correctly: passed through `env:` rather than interpolated into the shell,
quoted, validated against ^[A-Za-z0-9._/-]{1,200}$, and refs shaped like an
option are rejected in favour of the default branch. That defence was written
for exactly this case and is now load-bearing rather than theoretical.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@cmonaco0317
cmonaco0317 merged commit 8e36bb3 into main Aug 11, 2026
4 checks passed
@cmonaco0317
cmonaco0317 deleted the ci-pr-trigger branch August 11, 2026 03:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant