在 GitHub Actions 中使用 uv
安装
在 GitHub Actions 中使用 uv 时,我们推荐使用官方的
astral-sh/setup-uv action,它可以安装 uv、将其添加到
PATH、(可选)持久化缓存等,并支持所有 uv 支持的平台。
安装最新版本的 uv:
name: Example
jobs:
uv-example:
name: python
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- name: Install uv
uses: astral-sh/setup-uv@08807647e7069bb48b6ef5acd8ec9567f424441b # v8.1.0
最佳实践是锁定到特定的 uv 版本,例如:
name: Example
jobs:
uv-example:
name: python
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- name: Install uv
uses: astral-sh/setup-uv@08807647e7069bb48b6ef5acd8ec9567f424441b # v8.1.0
with:
# 安装特定版本的 uv。
version: "0.11.23"
设置 Python
可以使用 python install 命令安装 Python:
name: Example
jobs:
uv-example:
name: python
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- name: Install uv
uses: astral-sh/setup-uv@08807647e7069bb48b6ef5acd8ec9567f424441b # v8.1.0
- name: Set up Python
run: uv python install
这将遵循项目中锁定的 Python 版本。
或者,也可以使用 GitHub 官方的 setup-python action。这种方式可能更快,因为
GitHub 会将 Python 版本与 runner 一起缓存。
设置
python-version-file
选项以使用项目中锁定的版本:
name: Example
jobs:
uv-example:
name: python
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- name: "Set up Python"
uses: actions/setup-python@v6
with:
python-version-file: ".python-version"
- name: Install uv
uses: astral-sh/setup-uv@08807647e7069bb48b6ef5acd8ec9567f424441b # v8.1.0
或者,指定 pyproject.toml 文件以忽略锁定版本,使用与项目 requires-python 约束兼容的最新版本:
name: Example
jobs:
uv-example:
name: python
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- name: "Set up Python"
uses: actions/setup-python@v6
with:
python-version-file: "pyproject.toml"
- name: Install uv
uses: astral-sh/setup-uv@08807647e7069bb48b6ef5acd8ec9567f424441b # v8.1.0
多 Python 版本
当使用矩阵(matrix)来测试多个 Python 版本时,通过 astral-sh/setup-uv 设置 Python 版本,
这将覆盖 pyproject.toml 或 .python-version 文件中的 Python 版本规范:
jobs:
build:
name: continuous-integration
runs-on: ubuntu-latest
strategy:
matrix:
python-version:
- "3.10"
- "3.11"
- "3.12"
steps:
- uses: actions/checkout@v6
- name: Install uv and set the Python version
uses: astral-sh/setup-uv@08807647e7069bb48b6ef5acd8ec9567f424441b # v8.1.0
with:
python-version: ${{ matrix.python-version }}
如果不使用 setup-uv action,可以设置 UV_PYTHON 环境变量:
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@v6
同步和运行
安装好 uv 和 Python 之后,可以使用 uv sync 安装项目,并使用 uv run 在环境中运行命令:
name: Example
jobs:
uv-example:
name: python
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- name: Install uv
uses: astral-sh/setup-uv@08807647e7069bb48b6ef5acd8ec9567f424441b # v8.1.0
- name: Install the project
run: uv sync --locked --all-extras --dev
- name: Run tests
# 例如,使用 `pytest`
run: uv run pytest tests
Tip
UV_PROJECT_ENVIRONMENT 设置可
用于将依赖安装到系统 Python 环境中,而不是创建虚拟环境。
缓存
在多次工作流运行之间存储 uv 的缓存可以提高 CI 效率。
astral-sh/setup-uv 内置了持久化缓存的支持:
- name: Enable caching
uses: astral-sh/setup-uv@08807647e7069bb48b6ef5acd8ec9567f424441b # v8.1.0
with:
enable-cache: true
或者,你也可以使用 actions/cache action 手动管理缓存:
jobs:
install_job:
env:
# 为 uv 缓存配置一个固定位置
UV_CACHE_DIR: /tmp/.uv-cache
steps:
# ... 设置 Python 和 uv 的步骤 ...
- name: Restore uv cache
uses: actions/cache@v5
with:
path: /tmp/.uv-cache
key: uv-${{ runner.os }}-${{ hashFiles('uv.lock') }}
restore-keys: |
uv-${{ runner.os }}-${{ hashFiles('uv.lock') }}
uv-${{ runner.os }}
# ... 安装包、运行测试等步骤 ...
- name: Minimize uv cache
run: uv cache prune --ci
uv cache prune --ci 命令用于减小缓存大小,并针对 CI 进行了优化。
其对性能的影响取决于所安装的包。
Tip
如果使用 uv pip,请在缓存键中使用 requirements.txt 而不是 uv.lock。
Note
当使用非临时性的自托管 runner 时,默认缓存目录可能会无限增长。 在这种情况下,在作业之间共享缓存可能不是最优选择。相反,可以将缓存 移到 GitHub Workspace 内部,并使用 Post Job Hook 在作业完成后将其删除。
使用 post job hook 需要在自托管 runner 上将 ACTIONS_RUNNER_HOOK_JOB_STARTED 环境
变量设置为清理脚本的路径,例如下面所示的脚本。
使用 uv pip
如果使用 uv pip 接口而非 uv 项目接口,uv 默认需要一个虚拟环境。
要允许将包安装到系统环境中,可以在所有 uv 调用中使用 --system 标志,或设置 UV_SYSTEM_PYTHON 变量。
UV_SYSTEM_PYTHON 变量可以在不同作用域中定义。
在顶层定义以对整个工作流生效:
或者,针对工作流中的特定作业:
或者,针对作业中的特定步骤:
steps:
- name: Install requirements
run: uv pip install -r requirements.txt
env:
UV_SYSTEM_PYTHON: 1
要重新退出系统模式,可以在任何 uv 调用中使用 --no-system 标志。
私有仓库
如果你的项目依赖私有 GitHub 仓库, 你需要配置一个个人访问令牌(personal access token,PAT)以允许 uv 获取它们。
创建具有私有仓库读取权限的 PAT 后,将其添加为仓库密钥(repository secret)。
然后,你可以使用 gh CLI(默认安装在 GitHub Actions
runner 中)来配置
Git 凭据助手(credential helper),以便对 github.com 上托管的仓库使用 PAT 进行查询。
例如,如果你将仓库密钥命名为 MY_PAT:
steps:
- name: Register the personal access token
run: echo "${{ secrets.MY_PAT }}" | gh auth login --with-token
- name: Configure the Git credential helper
run: gh auth setup-git
发布到 PyPI
可以使用 uv 从 GitHub Actions 构建并将你的包发布到 PyPI。我们在 astral-sh/trusted-publishing-examples 中提供了一个独立示例。该工作流使用可信发布(trusted publishing),因此无需配置任何凭据。
在示例工作流中,我们使用一个脚本来测试源分发包(source distribution)和 wheel 是否都能正常工作,以及是否遗漏了任何文件。此步骤为推荐步骤,但并非必须。
首先,向你的项目添加一个发布工作流:
name: "Publish release to PyPI"
on:
push:
tags:
# 在任何以 `v` 开头的标签上发布,例如 v0.1.0
- v*
jobs:
run:
runs-on: ubuntu-latest
environment:
name: pypi
permissions:
id-token: write
contents: read
steps:
- name: Checkout
uses: actions/checkout@v6
- name: Install uv
uses: astral-sh/setup-uv@08807647e7069bb48b6ef5acd8ec9567f424441b # v8.1.0
- name: Install Python 3.13
run: uv python install 3.13
- name: Build
run: uv build
# 检查基本功能是否正常,以及是否遗漏了关键文件
- name: Smoke test (wheel)
run: uv run --isolated --no-project --with dist/*.whl tests/smoke_test.py
- name: Smoke test (source distribution)
run: uv run --isolated --no-project --with dist/*.tar.gz tests/smoke_test.py
- name: Publish
run: uv publish
然后,在 GitHub 仓库的 "Settings" -> "Environments" 下创建工作流中定义的环境。

在 PyPI 项目的 "Publishing" 设置中添加一个可信发布者(trusted publisher)。 确保所有字段与你的 GitHub 配置匹配。

保存后:

最后,创建一个发布标签并推送。确保它以 v 开头以匹配工作流中的模式。