Let only Test save the shared uv cache - #592
Merged
Merged
Conversation
astral-sh/setup-uv derives its cache key from architecture, runner image, Python version and a hash of the dependency files, so every job that runs the same OS and the same Python version derives the same key. When such jobs run from one push, they all try to reserve that key at save time; the first to finish wins and the rest log Failed to save: Unable to reserve cache with key setup-uv-2-..., another job may be creating this cache. The warning is save-time only and harmless -- the losing job would have written identical content -- but it is log noise. Giving each workflow its own cache via cache-suffix was considered and rejected in audeering/audeer#207: it multiplies near-identical caches for no benefit. Instead keep the one shared key and make exactly one writer. Documentation, Linter and Publish set save-cache: false; Test keeps the default and is the sole writer. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Contributor
Reviewer's guide (collapsed on small PRs)Reviewer's GuideCentralizes uv cache writes in CI so only a single job (a specific Test matrix leg) saves the shared uv cache, eliminating Sequence diagram for shared uv cache writes across workflowssequenceDiagram
participant Documentation
participant Linter
participant Publish
participant Test_plain_3_10
participant Test_pandas_3_10
participant Test_3_12
participant setup_uv
participant GitHubActionsCache
Documentation->>setup_uv: setup-uv v9.0.0 (save-cache: false)
setup_uv->>GitHubActionsCache: restore cache
Linter->>setup_uv: setup-uv v9.0.0 (save-cache: false)
setup_uv->>GitHubActionsCache: restore cache
Publish->>setup_uv: setup-uv v9.0.0 (save-cache: false)
setup_uv->>GitHubActionsCache: restore cache
Test_plain_3_10->>setup_uv: setup-uv v9.0.0 (save-cache: true)
setup_uv->>GitHubActionsCache: restore cache
alt [cold key]
setup_uv->>GitHubActionsCache: save cache
else [warm key]
setup_uv->>GitHubActionsCache: not saving cache
end
Test_pandas_3_10->>setup_uv: setup-uv v9.0.0 (save-cache: false)
setup_uv->>GitHubActionsCache: restore cache
Test_3_12->>setup_uv: setup-uv v9.0.0 (save-cache: true)
setup_uv->>GitHubActionsCache: restore cache
alt [cold key]
setup_uv->>GitHubActionsCache: save cache
else [warm key]
setup_uv->>GitHubActionsCache: not saving cache
end
Flow diagram for conditional uv cache saving in Test workflowflowchart TD
A[Test job matrix leg] --> B[Check matrix.pandas]
B -->|matrix.pandas set| C[save-cache: false]
B -->|matrix.pandas not set| D[save-cache: true]
C --> E[setup-uv restore only]
D --> F[setup-uv restore]
F --> G[setup-uv save cache on cold key]
F --> H[setup-uv not saving cache on warm key]
File-Level Changes
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
The Test matrix declares ubuntu-latest + Python 3.10 twice, once plain and once with pandas==2.1.4. Same OS and same Python means the same setup-uv cache key, so those two legs race with each other and the previous commit alone does not silence them. Measured on this pull request with a cold key (run 31098374254, attempt 2): both legs missed setup-uv-2-x86_64-unknown-linux-gnu-ubuntu-24.04-3.10.20-ed955f29..., the pandas leg saved it at 11:50:33 and the plain leg reported at 11:50:37 Failed to save: Unable to reserve cache with key setup-uv-2-...-3.10.20-..., another job may be creating this cache. That was the only warning left, and it came from this pair alone. Making the variant leg skip the save leaves exactly one writer in Test: matrix.pandas is unset for every other leg, so the expression is true there and false for the pandas leg. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Member
Author
|
@sourcery-ai review |
There was a problem hiding this comment.
Pull request overview
This PR reduces GitHub Actions warning annotations from astral-sh/setup-uv cache save-key collisions by ensuring only one job/workflow attempts to save the shared uv cache key.
Changes:
- Disable uv cache saving in
Documentation,Linter, andPublishworkflows (save-cache: false). - In
Test, disable cache saving for thepandasmatrix leg so only oneubuntu-latest + 3.10leg writes the cache.
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
| .github/workflows/test.yml | Makes only the non-pandas matrix legs save the uv cache to avoid intra-workflow cache key races. |
| .github/workflows/publish.yml | Disables uv cache saving to avoid cross-workflow save-key collisions. |
| .github/workflows/linter.yml | Disables uv cache saving to avoid cross-workflow save-key collisions. |
| .github/workflows/doc.yml | Disables uv cache saving to avoid cross-workflow save-key collisions. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
hagenw
approved these changes
Aug 6, 2026
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
Every workflow installs uv with
astral-sh/setup-uv.The action derives its cache key from architecture, runner image, Python version
and a hash of the dependency files:
Nothing in that key identifies the workflow or the job, so every job on the same
OS with the same Python version derives the same key.
When several such jobs run from one push they all try to reserve that key at save
time, the first to finish wins, and the rest log:
It is save-time only and harmless — the losing job's content would have been
identical — but it surfaces as a yellow warning annotation on the check run.
mainhas it. The most recent push (d1f07f7)produced two colliding key groups:
setup-uvispost-if: success()and this job failed on an unrelatedlinkchecktimeout)Unable to reserve cacheUnable to reserve cacheMeasured frequency: 2 of the 61 uv-installing jobs across the last six commits on
main, and both of them on that one push.The five commits before it ran
setup-uv@v5, whose key(
setup-uv-1-…-no-dependency-glob) was already populated, so every job got acache hit and logged
not saving cache— no save attempt, no race.The collision is therefore structural but only visible when the key is fresh:
it returns on every key rotation (uv major version, runner image, Python patch
release, dependency change), which is exactly what d1f07f7 did by moving to v9.
Fix
Single-saver. Keep the one shared key and make exactly one writer:
Documentation,LinterandPublishpasssave-cache: false(an input of
setup-uvv9.0.0, defaulttrue), which leavesTestas the onlyworkflow that writes.
That alone was not enough here, and the second commit says why.
Testin this repository declaresubuntu-latest+ Python3.10twice — onceplain and once with
pandas==2.1.4— so those two legs share a key with eachother, inside one workflow.
Measured on this PR with a cold key: both legs missed, the
pandasleg saved,and the plain leg emitted the one remaining warning.
So the
pandasleg now skips the save as well, viasave-cache: ${{ !matrix.pandas }}—truefor every leg that does not setmatrix.pandas,falsefor the one that does — leaving exactly one writer inTest.Measuring this needed care:
mainhad already populated the v9 keys, so thefirst run of this PR got a cache hit on every job, nothing tried to save,
and zero warnings proved nothing.
The numbers above come from re-running all three workflows after deleting the
ubuntu-24.043.10.20and3.12.13uv caches, which reproduces the cold-keyconditions of d1f07f7.
actions/cachesteps (theemodbtest data) are untouched; this is only aboutthe uv cache.
Trade-off
After a cache-key rotation the non-saving workflows miss the cache once, until
the next
Testrun populates the new key.That costs a second or two per job, for one run.
Context
Ports audeering/audeer#207 (merged, reviewer-approved).
opensmile-pythonandaudformatget the same treatment.mainhere never got the fix becaused1f07f7
merged before the warning was diagnosed.
Giving each workflow its own cache via
cache-suffixwas considered and rejectedin audeer#207: it multiplies near-identical caches for no benefit.
Test plan
8d3b87d
Unable to reserve cacheannotations on the head commit, verifiedwith the uv caches deleted first so that every job really attempts a save
For the record, on the colliding keys of that run:
save-cacheDocumentation - build (ubuntu-latest, 3.12)falsesave-cache is false. Skipping save cache step.Linter - buildfalsesave-cache is false. Skipping save cache step.Test - build (ubuntu-latest, 3.12)trueuv cache saved with key: setup-uv-2-...-3.12.13-...Test - build (ubuntu-latest, 3.10)trueuv cache saved with key: setup-uv-2-...-3.10.20-...Test - build (ubuntu-latest, 3.10, pandas==2.1.4)falsesave-cache is false. Skipping save cache step.One writer per key, no reservation contest.
An earlier attempt on the first commit alone, with the same cold key, still
warned once - the two 3.10 legs - which is what the second commit fixes.