mirror of
https://github.com/astral-sh/uv.git
synced 2025-07-09 22:35:01 +00:00

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
348 lines
8.4 KiB
Markdown
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.
|