uv/docs/guides/integration/github.md
Charlie Marsh 9d1a14e1f9
Some checks are pending
CI / cargo shear (push) Waiting to run
CI / check system | python on debian (push) Blocked by required conditions
CI / cargo dev generate-all (push) Blocked by required conditions
CI / Determine changes (push) Waiting to run
CI / lint (push) Waiting to run
CI / cargo clippy | ubuntu (push) Blocked by required conditions
CI / cargo clippy | windows (push) Blocked by required conditions
CI / cargo test | ubuntu (push) Blocked by required conditions
CI / cargo test | macos (push) Blocked by required conditions
CI / cargo test | windows (push) Blocked by required conditions
CI / check windows trampoline | aarch64 (push) Blocked by required conditions
CI / integration test | github actions (push) Blocked by required conditions
CI / check windows trampoline | i686 (push) Blocked by required conditions
CI / check windows trampoline | x86_64 (push) Blocked by required conditions
CI / test windows trampoline | i686 (push) Blocked by required conditions
CI / test windows trampoline | x86_64 (push) Blocked by required conditions
CI / typos (push) Waiting to run
CI / check cache | macos aarch64 (push) Blocked by required conditions
CI / mkdocs (push) Waiting to run
CI / build binary | linux libc (push) Blocked by required conditions
CI / build binary | linux musl (push) Blocked by required conditions
CI / build binary | macos aarch64 (push) Blocked by required conditions
CI / build binary | macos x86_64 (push) Blocked by required conditions
CI / build binary | windows x86_64 (push) Blocked by required conditions
CI / build binary | windows aarch64 (push) Blocked by required conditions
CI / cargo build (msrv) (push) Blocked by required conditions
CI / build binary | freebsd (push) Blocked by required conditions
CI / ecosystem test | pydantic/pydantic-core (push) Blocked by required conditions
CI / ecosystem test | prefecthq/prefect (push) Blocked by required conditions
CI / ecosystem test | pallets/flask (push) Blocked by required conditions
CI / integration test | pypy on windows (push) Blocked by required conditions
CI / integration test | graalpy on ubuntu (push) Blocked by required conditions
CI / integration test | graalpy on windows (push) Blocked by required conditions
CI / integration test | free-threaded python on github actions (push) Blocked by required conditions
CI / integration test | determine publish changes (push) Blocked by required conditions
CI / integration test | uv_build (push) Blocked by required conditions
CI / smoke test | linux (push) Blocked by required conditions
CI / check system | alpine (push) Blocked by required conditions
CI / smoke test | macos (push) Blocked by required conditions
CI / smoke test | windows x86_64 (push) Blocked by required conditions
CI / smoke test | windows aarch64 (push) Blocked by required conditions
CI / integration test | conda on ubuntu (push) Blocked by required conditions
CI / integration test | deadsnakes python3.9 on ubuntu (push) Blocked by required conditions
CI / integration test | free-threaded on linux (push) Blocked by required conditions
CI / integration test | free-threaded on windows (push) Blocked by required conditions
CI / integration test | pypy on ubuntu (push) Blocked by required conditions
CI / integration test | uv publish (push) Blocked by required conditions
CI / check cache | ubuntu (push) Blocked by required conditions
CI / check system | python on fedora (push) Blocked by required conditions
CI / check system | python on ubuntu (push) Blocked by required conditions
CI / check system | python on opensuse (push) Blocked by required conditions
CI / check system | python on rocky linux 8 (push) Blocked by required conditions
CI / check system | python on rocky linux 9 (push) Blocked by required conditions
CI / check system | graalpy on ubuntu (push) Blocked by required conditions
CI / check system | pypy on ubuntu (push) Blocked by required conditions
CI / check system | pyston (push) Blocked by required conditions
CI / check system | python on macos aarch64 (push) Blocked by required conditions
CI / check system | homebrew python on macos aarch64 (push) Blocked by required conditions
CI / check system | python on macos x86-64 (push) Blocked by required conditions
CI / check system | python3.10 on windows x86-64 (push) Blocked by required conditions
CI / check system | python3.10 on windows x86 (push) Blocked by required conditions
CI / check system | python3.13 on windows x86-64 (push) Blocked by required conditions
CI / check system | x86-64 python3.13 on windows aarch64 (push) Blocked by required conditions
CI / check system | windows registry (push) Blocked by required conditions
CI / check system | python3.12 via chocolatey (push) Blocked by required conditions
CI / check system | python3.9 via pyenv (push) Blocked by required conditions
CI / check system | python3.13 (push) Blocked by required conditions
CI / check system | conda3.11 on macos aarch64 (push) Blocked by required conditions
CI / check system | conda3.8 on macos aarch64 (push) Blocked by required conditions
CI / check system | conda3.11 on linux x86-64 (push) Blocked by required conditions
CI / check system | conda3.8 on linux x86-64 (push) Blocked by required conditions
CI / check system | conda3.11 on windows x86-64 (push) Blocked by required conditions
CI / check system | conda3.8 on windows x86-64 (push) Blocked by required conditions
CI / check system | amazonlinux (push) Blocked by required conditions
CI / check system | embedded python3.10 on windows x86-64 (push) Blocked by required conditions
CI / benchmarks (push) Blocked by required conditions
Bump version to v0.7.5 (#13500)
2025-05-16 20:37:17 -04:00

348 lines
8.4 KiB
Markdown

---
title: Using uv in GitHub Actions
description:
A guide to using uv in GitHub Actions, including installation, setting up Python, installing
dependencies, and more.
---
# Using uv in GitHub Actions
## Installation
For use with GitHub Actions, we recommend the official
[`astral-sh/setup-uv`](https://github.com/astral-sh/setup-uv) action, which installs uv, adds it to
PATH, (optionally) persists the cache, and more, with support for all uv-supported platforms.
To install the latest version of uv:
```yaml title="example.yml" hl_lines="11-12"
name: Example
jobs:
uv-example:
name: python
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install uv
uses: astral-sh/setup-uv@v5
```
It is considered best practice to pin to a specific uv version, e.g., with:
```yaml title="example.yml" hl_lines="14 15"
name: Example
jobs:
uv-example:
name: python
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install uv
uses: astral-sh/setup-uv@v5
with:
# Install a specific version of uv.
version: "0.7.5"
```
## Setting up Python
Python can be installed with the `python install` command:
```yaml title="example.yml" hl_lines="14 15"
name: Example
jobs:
uv-example:
name: python
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install uv
uses: astral-sh/setup-uv@v5
- name: Set up Python
run: uv python install
```
This will respect the Python version pinned in the project.
Alternatively, the official GitHub `setup-python` action can be used. This can be faster, because
GitHub caches the Python versions alongside the runner.
Set the
[`python-version-file`](https://github.com/actions/setup-python/blob/main/docs/advanced-usage.md#using-the-python-version-file-input)
option to use the pinned version for the project:
```yaml title="example.yml" hl_lines="14 15 16 17"
name: Example
jobs:
uv-example:
name: python
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install uv
uses: astral-sh/setup-uv@v5
- name: "Set up Python"
uses: actions/setup-python@v5
with:
python-version-file: ".python-version"
```
Or, specify the `pyproject.toml` file to ignore the pin and use the latest version compatible with
the project's `requires-python` constraint:
```yaml title="example.yml" hl_lines="17"
name: Example
jobs:
uv-example:
name: python
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install uv
uses: astral-sh/setup-uv@v5
- name: "Set up Python"
uses: actions/setup-python@v5
with:
python-version-file: "pyproject.toml"
```
## Multiple Python versions
When using a matrix to test multiple Python versions, set the Python version using
`astral-sh/setup-uv`, which will override the Python version specification in the `pyproject.toml`
or `.python-version` files:
```yaml title="example.yml" hl_lines="17 18"
jobs:
build:
name: continuous-integration
runs-on: ubuntu-latest
strategy:
matrix:
python-version:
- "3.10"
- "3.11"
- "3.12"
steps:
- uses: actions/checkout@v4
- name: Install uv and set the python version
uses: astral-sh/setup-uv@v5
with:
python-version: ${{ matrix.python-version }}
```
If not using the `setup-uv` action, you can set the `UV_PYTHON` environment variable:
```yaml title="example.yml" hl_lines="12"
jobs:
build:
name: continuous-integration
runs-on: ubuntu-latest
strategy:
matrix:
python-version:
- "3.10"
- "3.11"
- "3.12"
env:
UV_PYTHON: ${{ matrix.python-version }}
steps:
- uses: actions/checkout@v4
```
## Syncing and running
Once uv and Python are installed, the project can be installed with `uv sync` and commands can be
run in the environment with `uv run`:
```yaml title="example.yml" hl_lines="17-22"
name: Example
jobs:
uv-example:
name: python
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install uv
uses: astral-sh/setup-uv@v5
- name: Install the project
run: uv sync --locked --all-extras --dev
- name: Run tests
# For example, using `pytest`
run: uv run pytest tests
```
!!! tip
The
[`UV_PROJECT_ENVIRONMENT` setting](../../concepts/projects/config.md#project-environment-path) can
be used to install to the system Python environment instead of creating a virtual environment.
## Caching
It may improve CI times to store uv's cache across workflow runs.
The [`astral-sh/setup-uv`](https://github.com/astral-sh/setup-uv) has built-in support for
persisting the cache:
```yaml title="example.yml"
- name: Enable caching
uses: astral-sh/setup-uv@v5
with:
enable-cache: true
```
You can configure the action to use a custom cache directory on the runner:
```yaml title="example.yml"
- name: Define a custom uv cache path
uses: astral-sh/setup-uv@v5
with:
enable-cache: true
cache-local-path: "/path/to/cache"
```
Or invalidate it when the lockfile changes:
```yaml title="example.yml"
- name: Define a cache dependency glob
uses: astral-sh/setup-uv@v5
with:
enable-cache: true
cache-dependency-glob: "uv.lock"
```
Or when any requirements file changes:
```yaml title="example.yml"
- name: Define a cache dependency glob
uses: astral-sh/setup-uv@v5
with:
enable-cache: true
cache-dependency-glob: "requirements**.txt"
```
Note that `astral-sh/setup-uv` will automatically use a separate cache key for each host
architecture and platform.
Alternatively, you can manage the cache manually with the `actions/cache` action:
```yaml title="example.yml"
jobs:
install_job:
env:
# Configure a constant location for the uv cache
UV_CACHE_DIR: /tmp/.uv-cache
steps:
# ... setup up Python and uv ...
- name: Restore uv cache
uses: actions/cache@v4
with:
path: /tmp/.uv-cache
key: uv-${{ runner.os }}-${{ hashFiles('uv.lock') }}
restore-keys: |
uv-${{ runner.os }}-${{ hashFiles('uv.lock') }}
uv-${{ runner.os }}
# ... install packages, run tests, etc ...
- name: Minimize uv cache
run: uv cache prune --ci
```
The `uv cache prune --ci` command is used to reduce the size of the cache and is optimized for CI.
Its effect on performance is dependent on the packages being installed.
!!! tip
If using `uv pip`, use `requirements.txt` instead of `uv.lock` in the cache key.
!!! note
[post-job-hook]: https://docs.github.com/en/actions/hosting-your-own-runners/managing-self-hosted-runners/running-scripts-before-or-after-a-job
When using non-ephemeral, self-hosted runners the default cache directory can grow unbounded.
In this case, it may not be optimal to share the cache between jobs. Instead, move the cache
inside the GitHub Workspace and remove it once the job finishes using a
[Post Job Hook][post-job-hook].
```yaml
install_job:
env:
# Configure a relative location for the uv cache
UV_CACHE_DIR: ${{ github.workspace }}/.cache/uv
```
Using a post job hook requires setting the `ACTIONS_RUNNER_HOOK_JOB_STARTED` environment
variable on the self-hosted runner to the path of a cleanup script such as the one shown below.
```sh title="clean-uv-cache.sh"
#!/usr/bin/env sh
uv cache clean
```
## Using `uv pip`
If using the `uv pip` interface instead of the uv project interface, uv requires a virtual
environment by default. To allow installing packages into the system environment, use the `--system`
flag on all `uv` invocations or set the `UV_SYSTEM_PYTHON` variable.
The `UV_SYSTEM_PYTHON` variable can be defined in at different scopes.
Opt-in for the entire workflow by defining it at the top level:
```yaml title="example.yml"
env:
UV_SYSTEM_PYTHON: 1
jobs: ...
```
Or, opt-in for a specific job in the workflow:
```yaml title="example.yml"
jobs:
install_job:
env:
UV_SYSTEM_PYTHON: 1
...
```
Or, opt-in for a specific step in a job:
```yaml title="example.yml"
steps:
- name: Install requirements
run: uv pip install -r requirements.txt
env:
UV_SYSTEM_PYTHON: 1
```
To opt-out again, the `--no-system` flag can be used in any uv invocation.