ci: persist dispatched LLGo pins before building#3
Conversation
There was a problem hiding this comment.
Review: ci — persist dispatched LLGo pins before building
The two-workflow split is sound and the design correctly relies on GitHub's rule that a workflow_dispatch sent via the REST API does create a run even when authenticated with GITHUB_TOKEN (workflow_dispatch/repository_dispatch are the documented exceptions), while the GITHUB_TOKEN-authored git push origin HEAD:main does not recursively trigger the push workflow. So exactly one build fires per dispatch — no double build, and the dispatched build does run. Payload handling is also good: attacker-influenceable fields are passed via env: (not string-interpolated into run:), DISPATCH_LLGO_COMMIT is validated to ^[0-9a-f]{40}$ before any sed/git/jq use, and the payload is built with jq -cn --arg — no command or JSON injection.
Findings below are hardening/robustness, not correctness blockers. Inline comments carry the specifics.
Additional notes (no reliable inline anchor):
- Non-existent SHA can be pinned to
main(low). Validation confirms the SHA shape and thexgo-dev/llgoallow-list but never confirms the commit exists upstream. A garbage-but-well-formed SHA would be committed tomainand only fail later at the build'sgit fetch ... "$LLGO_COMMIT"step — a noise/DoS vector, not code execution. Optional:git ls-remote https://github.com/xgo-dev/llgo "$DISPATCH_LLGO_COMMIT"before committing. - Empty
current_commitguard (low). IfLLGO_COMMITwere ever absent fromllgo-version.env, theawkyields empty, the idempotency check passes through, andsedmatches nothing — producing an empty-diffgit committhat aborts underset -euo pipefail. Assertingcurrent_commitis a 40-hex value would make that failure explicit rather than incidental.
Prior reviews and inline threads: none on this PR.
|
|
||
| permissions: | ||
| contents: write | ||
| actions: write |
There was a problem hiding this comment.
Least privilege: scope actions: write to the job that needs it. This is granted at the workflow level, so every job inherits it — including binary-size, which builds untrusted LLGo/Bent code on pull_request events. Only update-pin needs actions: write (for the workflow_dispatch API call). Consider dropping the workflow-level default to the minimum and adding a job-level permissions: { contents: write, actions: write } block on update-pin only.
|
|
||
| jobs: | ||
| binary-size: | ||
| update-pin: |
There was a problem hiding this comment.
update-pin has no timeout-minutes. The old binary-size job's timeout-minutes: 120 moved to the new build job, leaving update-pin on the 360-minute default. Since it only does git + one curl, a small explicit timeout (e.g. timeout-minutes: 5) fails fast on a hung push/dispatch instead of holding the llgo-binary-size-pages concurrency slot for hours.
| git config user.email "41898282+github-actions[bot]@users.noreply.github.com" | ||
| git add ci/llgo-size/llgo-version.env | ||
| git commit -m "ci: pin LLGo ${DISPATCH_LLGO_COMMIT:0:12}" | ||
| git push origin HEAD:main |
There was a problem hiding this comment.
Commit-then-dispatch is not atomic. The pin is committed and pushed to main here, then the build is dispatched separately below. If the subsequent curl fails (network blip, transient 5xx), main is left "pinned but not built" with no automatic retry — the next dispatch for a different SHA won't rebuild this one, and the same-SHA idempotency check (line 66) will now short-circuit it. Worth a mitigation: --retry/--max-time on the dispatch (see next comment), or ordering the dispatch before the push, or a follow-up that reconciles pinned-but-unbuilt commits.
| --arg ref main \ | ||
| --arg llgo_commit "$DISPATCH_LLGO_COMMIT" \ | ||
| '{ref: $ref, inputs: {llgo_commit: $llgo_commit}}')" | ||
| curl --fail-with-body --location --request POST \ |
There was a problem hiding this comment.
Dispatch curl has no timeout or retry. This is the load-bearing call that actually starts the build. Add --max-time/--connect-timeout and --retry 3 --retry-connrefused so a transient failure doesn't silently leave the repo pinned-but-unbuilt (see the commit-atomicity note above). --fail-with-body is good — it already fails the step on a non-2xx response.
Summary
ci/llgo-size/llgo-version.envin the normalpushtrigger scope, so a committed LLGo pin update always runs the build and Pages publication;xgo-dev/llgollgo-main-updatedevent by validating the payload, committing the newLLGO_COMMITto benchmarksmain, and explicitly dispatching the build with the same SHA;Validation
.github/workflows/llgo-binary-size.ymlgit diff --check