ci: run the PR's own Actions via act on CircleCI (POC) - #6
Conversation
3384ab7 to
70d729b
Compare
|
Deployment note: configure two CircleCI project triggers for this pipeline:
Do not use the legacy Only build pull requests setting by itself, because merge-queue refs are push events rather than PR events. The config filters each trigger to its corresponding workflow. |
| --eventpath /tmp/pull-request-event.json \ | ||
| -P "ubuntu-latest=catthehacker/ubuntu@sha256:b839c14c4410998529ec18f951262bdf87a2b23bc1467304d07b491b9455e074" \ | ||
| --env RUSTC_WRAPPER= \ | ||
| -s GITHUB_TOKEN="${MISE_GITHUB_TOKEN:?missing restricted read-only GitHub token}" \ |
There was a problem hiding this comment.
We considered keeping these builds fully tokenless so PR-controlled workflows never receive a credential. In practice, act uses GITHUB_TOKEN both as a workflow secret and to fetch remote actions; an invalid placeholder caused every workflow with remote actions to fail authentication. Avoiding a token would require maintaining a custom actions/checkout implementation and/or recursively pre-populating an offline action cache, which reduces GitHub Actions fidelity and adds ongoing maintenance.
The trade-off here is reliability and fidelity versus exposure: we use the real token so act can run the original workflows unchanged, but PR code can access it. The token therefore must remain repository-scoped/read-only, and the CircleCI context must only be available to trusted contributors; untrusted PRs must not run these jobs.
| act "$event_name" -W ".github/workflows/<< parameters.wf >>" \ | ||
| --eventpath /tmp/github-event.json \ | ||
| -P "ubuntu-latest=catthehacker/ubuntu@sha256:b839c14c4410998529ec18f951262bdf87a2b23bc1467304d07b491b9455e074" \ | ||
| --concurrent-jobs 1 \ |
There was a problem hiding this comment.
act v0.2.89 does not synchronize concurrent reads and writes to its shared GoGitActionCache. We observed this in E2E when two jobs fetched rui314/setup-mold simultaneously and one saw the repository before action.yml was available. Serializing internal jobs is the smallest reliable workaround, but increases the runtime of multi-job workflows—especially lint.yml.
The performance-preserving alternative is to carry a small fork/patch of the pinned act version that locks GoGitActionCache.Fetch and GetTarArchive (ideally with a per-repository RW lock). That would serialize only action-cache I/O while leaving test and compilation jobs parallel. This flag can be removed once that fix is carried locally or released upstream.
There was a problem hiding this comment.
Update: a fixed v0.2.89 fork is now available as joshklop/act@v0.2.89-action-cache-fix.1 (commit 245fb90). The release includes a Linux x86_64 archive for CircleCI; its SHA-256 is 4d1093f87290cd8ed54609dd352477af75e1d95d02cdec9805d4ec2a55da3cca.
The patch adds per-cache-repository RW locks around GoGitActionCache.Fetch and streamed GetTarArchive reads, protects offline-cache reference updates, and synchronizes LocalRepositoryCache bookkeeping. Parallel access regression tests pass under Go's race detector, go vet ./pkg/runner passes, and the patched Linux binary builds with Go 1.25.0.
This PR remains on --concurrent-jobs 1 for the simplest safe path, but the fork and pinned release asset are ready if we decide to restore parallel execution.
Continues #4 from a dedicated branch.
Runs the PR's own GitHub Actions with
actunder CircleCI as a proof of concept.