ci: run firmwareci for fork pull requests - #372
Open
RiSKeD wants to merge 1 commit into
Open
Conversation
Pull requests from forks run without repository secrets, so FWCI_TOKEN is empty and the FirmwareCI step in fwci-test cannot submit a job. Skip that job for fork pull requests and add fwci-fork, which triggers on the completion of fwci-test, downloads the binaries it already built, and submits them from the base repository where the secrets live. Fork-authored code never runs in the new workflow. It checks out this repository, not the contributor's, and only hands the build artifact to FirmwareCI. What still needs a human is the hardware itself, so the job sits behind the firmwareci-fork environment: approving it means letting a contributor's build run on a real DUT. The artifact comes from a run of the contributor's code, so the filename lookup rejects anything but a single plainly named path before it reaches GITHUB_OUTPUT, and event payload values are passed through the environment instead of being interpolated into the script. BRANCH is pinned to main because the fork's branch does not exist here and the FirmwareCI config has to resolve against a branch of this repository. COMMIT_HASH comes from the workflow_run payload, which carries the pull request head commit rather than the base ref this workflow runs on. The firmwareci-fork environment must exist with required reviewers before this has any effect. Signed-off-by: Fabian Wienand <fabian.wienand@blindspot.software>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
Pull requests from forks run without repository secrets, so
secrets.FWCI_TOKENis empty and the Upload to FirmwareCI step infwci-testfails. #334 (9elements/dutctl-9e→BlindspotSoftware/dutctl) is the current example. Everything else in that workflow — the goreleaser build,get-matrix,validate-config— needs no secrets and already passes on fork PRs.There is no setting that fixes this. GitHub's "send secrets to fork pull request workflows" toggle is private-repository-only; the API rejects it here with
Fork PR workflow settings is not allowed for public repositories.Change
Split the submission out of the run that has no secrets.
fwci-test— the FirmwareCI job is now skipped on fork pull requests. Same-repo pull requests, pushes and merge groups are unaffected and still submit inline.fwci-fork(new) — triggers onfwci-testcompleting, downloads thebinariesartifact that run already produced, and submits it from this repository, where the secrets live.Fork-authored code never runs in the privileged job. It checks out this repository, not the contributor's, and does nothing but hand the build artifact to FirmwareCI. That closes the credential exposure; it does not close the hardware question, which is what the environment gate is for.
Required before this does anything
Create an environment named
firmwareci-fork(Settings → Environments) with required reviewers. A fork pull request then parks at Waiting for approval until a maintainer approves, and approving means letting a contributor's build run on a real DUT.The environment is the whole gate. Without required reviewers configured, this submits every fork pull request to hardware automatically.
Hardening
The artifact is the output of a run of the contributor's code, so the job treats it as untrusted input:
GITHUB_OUTPUT— a filename containing a newline would otherwise let the artifact append arbitrary step outputs;Debugscript throughenv:rather than being interpolated into it.Details worth knowing
BRANCH: mainis deliberate. FirmwareCI resolvestest-dutctlper branch, and the fork's branch does not exist in this repository, so resolving against it would miss.COMMIT_HASHstill points at the fork's head commit, so the job reports against the commit actually under test.workflow_run.pull_requestsis empty for cross-repository runs, which is why the job keys offhead_shaandhead_repositoryinstead of the PR number.CONFIGcomes from this repository's tree, not the fork's. A fork PR that editscontrib/dutagent-cfg-example.yamlwould be tested against the base version. Not the case for Gude PDU support #334. If that matters later, add the config as a separate artifact — appending it tobinarieswould shift the tree and break the existinglsglobs infwci-test.v6.0. It is never reached on a fork pull request now, so this does not depend on BlindspotSoftware/actions#24 landing. Bumping tov6.2afterwards adds a backstop: the action itself then reports a skip instead of failing if a fork run ever reaches it.Testing
actionlintis clean on both files. The path guard was exercised locally: a normal goreleaser path is accepted, a two-match/newline result exits 1.The first real fork pull request is what verifies the rest — specifically that the FirmwareCI check run posts back onto the pull request. The GitHub App is installed on this repository and the fork's head commit exists here via
refs/pull/N/head, so it should; worth watching on the first run.