8000 fix(ci): do not publish the beta from a fork PR by avelino · Pull Request #127 · avelino/mcp · GitHub
[go: up one dir, main page]

Skip to content

fix(ci): do not publish the beta from a fork PR - #127

Merged
avelino merged 1 commit into
mainfrom
avelino/fix/release-beta-fork-guard
Oct 19, 2026
Merged

avelino merged 1 commit into
mainfrom
avelino/fix/release-beta-fork-guard

Conversation

@avelino
@avelino avelino commented Oct 19, 2026 •
Copy link
Copy Markdown
Owner

What

Release Beta runs when CI completes. CI also runs on pull_request, including from a fork. branches: [main] compares the triggering run's head branch name, so a fork PR opened from a branch named main matches. The workflow then checks out github.event.workflow_run.head_sha — the fork's commit — and the token at the top of the file was contents: write and packages: write. That is enough to delete prereleases, create a GitHub release, and push ghcr.io/avelino/mcp.

Each job now runs only when all of these hold:

  • github.event.workflow_run.conclusion == 'success'
  • github.event.workflow_run.event == 'push'
  • github.event.workflow_run.head_repository.full_name == github.repository
  • github.event.workflow_run.head_branch == 'main'

publish and docker also require needs.build.result == 'success'. A job-level if replaces the implicit success check, and a skipped build must not go on to delete releases.

The workflow token is contents: read. contents: write is only on publish (delete and create the prerelease, including the tag). packages: write is only on docker. Checkouts set persist-credentials: false, so the token is not left in .git/config next to cargo build. The head SHA is passed in the environment instead of being expanded inside run:.

Every action stays pinned to the same commit. dtolnay/rust-toolchain publishes a moving v1 tag, which no longer points at the commit the workflows pin, so that comment no longer claims the tag.

workflow_run stays. zizmor flags that trigger on its own; the ignore on that line is that finding, and the job if is the control.

Why a fork run is skipped

A fork PR whose branch is named main still starts this workflow, because the on: filter cannot tell a push from a pull request. The job condition is then false: the triggering event is pull_request, and head_repository.full_name is the fork, not this repository. build is skipped before checkout, so the fork SHA is never checked out. publish and docker need build and repeat the same check, so they are skipped too. No prerelease is deleted, no release is created, and nothing is pushed to GHCR.

A pull request from this repository is skipped for the same reason: the event is not push. The beta is published only after CI succeeds on a push to main here.

How it was tested

actionlint 1.7.12 and zizmor 1.31.1:

$ actionlint .github/workflows/release-beta.yml
$ echo $?
0

$ zizmor .github/workflows/release-beta.yml
No findings to report. Good job! (1 ignored, 12 suppressed)
$ echo $?
0

The ignored finding is dangerous-triggers on workflow_run, which zizmor reports for the trigger itself. The twelve suppressed results are below the default persona.

Not run here: the release. It runs after CI succeeds on a push to main. The Windows build is unchanged; #122 covers that.

workflow_run's branches filter matches the triggering run's head
branch name. CI also runs on pull_request, so a fork PR from a
branch named main used to check out that SHA with contents: write
and packages: write.

Jobs now run only after a successful push to main in this
repository. Write scopes sit on the jobs that create the release
and push the images.

Signed-off-by: Avelino <31996+avelino@users.noreply.github.com>
@avelino
avelino merged commit 57dbd9c into main Oct 19, 2026
7 checks passed
@avelino
avelino deleted the avelino/fix/release-beta-fork-guard branch October 19, 2026 09:01
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

0