A pull from a fork gets its check: the gate fetches refs/pull/<n>/head when the head is not on a branch, and the preview skips forks #40
No reviewers
Labels
No labels
agent-work
agent-working
ultracode
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
trevato-apps/forge!40
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "grokbot/forge:fix/ci-fork-pr-checkout"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
check.yml cloned this repository and checked out GITHUB_SHA. A fork's head
commit is here only as refs/pull//head, which a clone does not fetch, so
every gate shard of a fork pull died at "clone source at this ref" with
"fatal: reference is not a tree" before running a test (PR #39, run 893).
preview.yml cloned --branch "$GITHUB_HEAD_REF", a branch that exists only in
the fork; a fork pull gets no secrets either, and a preview builds and pushes
an image of the pull's code, so it now skips pulls from forks.
Why now
#39 (#39) is the first pull from a fork, and it is blocked by this: all three gate shards fail at "clone source at this ref" with
fatal: reference is not a tree: cf8de4df…(run 893), and preview fails withRemote branch fix/2171-flow-unused-imports not found in upstream origin(run 894). No test ran.Security review
With this change, a fork pull's own code runs in
check.yml(bun install,scripts/test-shards.ts, the tests). What that code can reach:check.ymlreferences nosecrets.*. Forgejo also leavessecretsempty for apull_requestwhose head is a fork.github.token, scoped to the "clone source" step env and embedded insrc/.git/configby the clone. Fork code in later steps can read it from there, and the runner hands job tokens to steps in other ways too, so scrubbing the URL would not be a real boundary. What matters is Forgejo's rule that apull_requestrun's automatic token has no write permission (read-only for forks). It can read this public repository, which anyone can already do.gatenorcheckpushes git, builds or pushes images or charts, signs anything, or calls a write API (/ci/previewand the registry appear only inpreview.ymlandrelease.yml). No cache is shared with privileged workflows, so nothing can be poisoned.pull_request, notpull_request_target. The fork's code never runs with base-repository privileges. Fork pulls from users without elevated rights still need a maintainer's approval before Actions run them (Forgejo default).refs/pull/<n>/headis fetched only when$GITHUB_SHAis not already in the clone (fork pulls). It is the same commit the event names; nothing else changes for pushes to main or same-repository pulls.REGISTRY_TOKEN/cosign secrets (empty for forks anyway) and builds and pushes an image of the pull's code, so the job is skipped whenhead.repo.full_name != github.repository. Teardown is skipped too; there is nothing to tear down.Conclusion: no secret or write token reaches fork code in
check.yml, and its jobs cannot push or publish. No extra gating needed beyond the preview skip.Known baseline on main (not this change)
test/og-png.test.ts"median of three cold renders is within 300 ms" failed main's push gate shard 2 (run 889: 616 ms / 708 ms on the half-core, 512 MiB runner). Pulls whose fast tier includes it (e.g. #39) may hit it too.Validation
pipeline/validateona9797560: pass in 6s — bun 1.3.14, CI-shaped env (scrubbed vars, runner PATH), exact check.yml shard + forge.json commands.bun install --frozen-lockfileforge.json check.fastcheck.yml gate (1) pull_requestcheck.yml gate (2) pull_requestcheck.yml gate (3) pull_requesttest output (failures, totals)