Cache uv dependencies to speed up PR checks#333
Conversation
| name: build cache on ${{ matrix.python-version }} | ||
| runs-on: ubuntu-latest | ||
| strategy: | ||
| fail-fast: false | ||
| matrix: | ||
| python-version: ["3.10", "3.11", "3.12", "3.13"] | ||
|
|
||
| steps: | ||
| - name: Checkout repository | ||
| uses: actions/checkout@v4 | ||
|
|
||
| - name: Install uv | ||
| uses: astral-sh/setup-uv@v7 | ||
| with: | ||
| python-version: ${{ matrix.python-version }} | ||
| enable-cache: false | ||
|
|
||
| - name: Install dependencies and populate cache | ||
| run: | | ||
| echo "Building global UV cache..." | ||
| uv sync --all-packages --all-extras | ||
| echo "Cache populated successfully" | ||
|
|
||
| - name: Save uv caches | ||
| uses: actions/cache/save@v4 | ||
| with: | ||
| path: | | ||
| ~/.cache/uv | ||
| ~/.local/share/uv | ||
| .venv | ||
| key: uv-main-${{ matrix.python-version }}-${{ hashFiles('uv.lock') }} No newline at end of file |
Check warning
Code scanning / CodeQL
Workflow does not contain permissions Medium
This autofix suggestion was applied.
Show autofix suggestion
Hide autofix suggestion
Copilot Autofix
AI 3 months ago
In general, the fix is to explicitly declare a restrictive permissions: block, either at the workflow root or at the job level, granting only the scopes required. For this workflow, the steps only need to read repository contents (for checkout) and do not need to write to the repo or interact with issues/PRs, so contents: read at the workflow level is sufficient. actions/cache/save uses dedicated cache APIs and does not require repo write permissions.
The best minimal fix without changing existing behavior is to add a root-level permissions: block just after the name: (before on:), specifying contents: read. This will apply to all jobs in this workflow (there is only build-cache). No other scopes (like pull-requests, issues, etc.) are necessary based on the current steps. No additional imports or code changes are needed; we only modify .github/workflows/cache-dependencies.yml.
Concretely: in .github/workflows/cache-dependencies.yml, insert:
permissions:
contents: readbetween line 1 (name: Build uv cache) and line 3 (on:). The rest of the workflow remains unchanged.
| @@ -1,5 +1,8 @@ | ||
| name: Build uv cache | ||
|
|
||
| permissions: | ||
| contents: read | ||
|
|
||
| on: | ||
| push: | ||
| branches: |
There was a problem hiding this comment.
So I guess we need a top level:
permissions:
contents: readblock. But to write to the cache, maybe we need read,write?
Might have to play with it. I'm not seeing cache-management explicitly discussed in this doc on workflow permissions syntax
…in permissions Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>
davidharting
left a comment
There was a problem hiding this comment.
This is awesome! Great find with that article. Will be really nice to not waste time on every PR building a bespoke cache.
| strategy: | ||
| fail-fast: false | ||
| matrix: | ||
| python-version: ["3.10", "3.11", "3.12", "3.13"] |
There was a problem hiding this comment.
Nice! Was wondering how our multi-python version stuff would make this differ from the post you linked.
Pretty simple - just run across all python versions and include python-version in the cache key!
| name: build cache on ${{ matrix.python-version }} | ||
| runs-on: ubuntu-latest | ||
| strategy: | ||
| fail-fast: false | ||
| matrix: | ||
| python-version: ["3.10", "3.11", "3.12", "3.13"] | ||
|
|
||
| steps: | ||
| - name: Checkout repository | ||
| uses: actions/checkout@v4 | ||
|
|
||
| - name: Install uv | ||
| uses: astral-sh/setup-uv@v7 | ||
| with: | ||
| python-version: ${{ matrix.python-version }} | ||
| enable-cache: false | ||
|
|
||
| - name: Install dependencies and populate cache | ||
| run: | | ||
| echo "Building global UV cache..." | ||
| uv sync --all-packages --all-extras | ||
| echo "Cache populated successfully" | ||
|
|
||
| - name: Save uv caches | ||
| uses: actions/cache/save@v4 | ||
| with: | ||
| path: | | ||
| ~/.cache/uv | ||
| ~/.local/share/uv | ||
| .venv | ||
| key: uv-main-${{ matrix.python-version }}-${{ hashFiles('uv.lock') }} No newline at end of file |
There was a problem hiding this comment.
So I guess we need a top level:
permissions:
contents: readblock. But to write to the cache, maybe we need read,write?
Might have to play with it. I'm not seeing cache-management explicitly discussed in this doc on workflow permissions syntax
|
|
||
| - name: Install uv | ||
| uses: astral-sh/setup-uv@caf0cab7a618c569241d31dcd442f54681755d39 # astral-sh/setup-uv@v3 | ||
| uses: astral-sh/setup-uv@eac588ad8def6316056a12d4907a9d4d84ff7a3b # v7 |
There was a problem hiding this comment.
thanks for the upgrades!
| .venv | ||
| key: uv-main-${{ matrix.python-version }}-${{ hashFiles('uv.lock') }} | ||
| restore-keys: | | ||
| uv-main-${{ matrix.python-version }}- |
There was a problem hiding this comment.
I'm not really clear why restore-keys does not include the uv.lock hash
There was a problem hiding this comment.
Was this for your own debugging or is this something we want to keep around?
It looks like it overlaps somewhat with our noxfile tests
Description
Since we run all of our actions across multiple Python versions, this should speed up PR checks significantly. This only affects PRs - releases still refresh all dependencies when installing.
Reference: https://szeyusim.medium.com/optimizing-uv-in-github-actions-one-global-cache-to-rule-them-all-9c64b42aee7f