Repository navigation
Allow an exact shared cache key written only by protected pushes - #269
Conversation
In a pull-request workflow every actions/cache key must name github.event_name, so a cache written by one event is never read by another. That rule also forbids the safe direction: a cache that only pushes to the protected branch save, which pull request and merge group runs only restore. Allow an exact, unpartitioned key on two steps: - actions/cache/restore with no restore-keys; - actions/cache/save whose condition is a top-level conjunction requiring github.event_name == 'push' and github.ref == the protected ref. The combined actions/cache action, any restore prefix, and a save any other event or branch can run still need the event partition. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
|
Reviewed exact head This follows GitHub's cache scope rules: default-branch consumers cannot restore caches from child branches. The consuming workflow must still cover all relevant source, lock, toolchain and platform inputs in its key. Skip a build only on an exact cache hit, and keep ordinary build validation on a miss. |



Why
The server's Shared Server fixtures spend about 4 of every run's critical-path minutes building the same pinned,
--lockedSDK adapter dependencies. Every fixture job waits for them. Caching the adapters' Cargo registry and build tree would save that time, but the central policy requires${{ github.event_name }}in every cache key of a pull-request workflow. A cache saved only by pushes to main could then never be read by pull request or merge group runs, which are the runs it is meant to speed up.The partition prevents untrusted writes from reaching trusted reads. The opposite direction is safe: trusted pushes to main write, and pull request and merge group runs only read. This exception is limited to restore-only consumers and saves that require a protected-branch push, with positive and negative policy tests.
Change
In a pull-request workflow, an exact key without the event partition is allowed only on:
actions/cache/restorewith norestore-keys(a broad prefix could substitute stale output);actions/cache/savewhoseifis a top-level conjunction requiring bothgithub.event_name == 'push'andgithub.ref == '<protected ref>'. Other terms may narrow it further, such assuccess()or a cache-miss check.Everything else is unchanged and still needs the partition:
actions/cacheaction;restore-keys;Tests
python -m unittest tests.test_qualification_policy: 23 tests pass, two of them new.restore-keys;||in place of&&;!= 'pull_request'in place of== 'push';actions/cacheaction.The server-side change, with its key computed by a classified
scripts/cihelper, follows once this lands.🤖 Generated with Claude Code