Skip to main content
Integrate uv into your GitHub Actions workflows for fast, reliable Python dependency management and CI/CD automation.

Installation

1

Install latest version

Use the official astral-sh/setup-uv action:
name: CI

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v6

      - name: Install uv
        uses: astral-sh/setup-uv@v7
2

Pin to specific version (recommended)

- name: Install uv
  uses: astral-sh/setup-uv@v7
  with:
    version: "0.10.8"

Setting Up Python

Using uv python install

Install Python using uv (respects project’s pinned version):
steps:
  - uses: actions/checkout@v6

  - name: Install uv
    uses: astral-sh/setup-uv@v7

  - name: Set up Python
    run: uv python install

Using actions/setup-python

Alternatively, use GitHub’s cached Python versions:
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@v7
Or use pyproject.toml for the latest compatible version:
- name: Set up Python
  uses: actions/setup-python@v6
  with:
    python-version-file: "pyproject.toml"

Matrix Builds

Test across multiple Python versions:
jobs:
  test:
    runs-on: ubuntu-latest
    strategy:
      matrix:
        python-version:
          - "3.10"
          - "3.11"
          - "3.12"

    steps:
      - uses: actions/checkout@v6

      - name: Install uv and set Python version
        uses: astral-sh/setup-uv@v7
        with:
          python-version: ${{ matrix.python-version }}

      - name: Install dependencies
        run: uv sync --locked

      - name: Run tests
        run: uv run pytest

Using UV_PYTHON Environment Variable

jobs:
  test:
    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
      - name: Install uv
        uses: astral-sh/setup-uv@v7

Installing Dependencies

1

Sync project dependencies

- name: Install the project
  run: uv sync --locked --all-extras
2

Install without dev dependencies

- name: Install the project
  run: uv sync --locked --no-dev
3

Run tests

- name: Run tests
  run: uv run pytest tests

Caching

Built-in Caching with setup-uv

The easiest approach uses the action’s built-in caching:
- name: Install uv with caching
  uses: astral-sh/setup-uv@v7
  with:
    enable-cache: true

Manual Caching with actions/cache

For more control, use the actions/cache action:
jobs:
  test:
    runs-on: ubuntu-latest
    env:
      UV_CACHE_DIR: /tmp/.uv-cache

    steps:
      - uses: actions/checkout@v6

      - name: Install uv
        uses: astral-sh/setup-uv@v7

      - 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: Install dependencies
        run: uv sync --locked

      - name: Run tests
        run: uv run pytest

      - name: Minimize uv cache
        run: uv cache prune --ci
Use uv cache prune --ci to optimize cache size. If using uv pip, replace uv.lock with requirements.txt in the cache key.

Complete CI Workflow

Here’s a complete example combining best practices:
name: CI

on:
  push:
    branches: [main]
  pull_request:

jobs:
  test:
    runs-on: ubuntu-latest
    strategy:
      matrix:
        python-version: ["3.10", "3.11", "3.12"]

    steps:
      - uses: actions/checkout@v6

      - name: Install uv
        uses: astral-sh/setup-uv@v7
        with:
          version: "0.10.8"
          enable-cache: true
          python-version: ${{ matrix.python-version }}

      - name: Install dependencies
        run: uv sync --locked --all-extras

      - name: Run linter
        run: uv run ruff check .

      - name: Run type checker
        run: uv run mypy .

      - name: Run tests
        run: uv run pytest tests --cov

Using uv pip

If using the uv pip interface, enable system Python:
# Workflow-level
env:
  UV_SYSTEM_PYTHON: 1

jobs:
  test:
    steps:
      - name: Install dependencies
        run: uv pip install -r requirements.txt
Or at the job level:
jobs:
  test:
    env:
      UV_SYSTEM_PYTHON: 1
    steps:
      - name: Install dependencies
        run: uv pip install -r requirements.txt
Or at the step level:
steps:
  - name: Install requirements
    run: uv pip install -r requirements.txt
    env:
      UV_SYSTEM_PYTHON: 1

Private Repositories

Access private GitHub repositories using a Personal Access Token (PAT):
1

Create and store PAT

Create a PAT with repository read access and add it as a repository secret (e.g., MY_PAT).
2

Configure Git credential helper

steps:
  - name: Register personal access token
    run: echo "${{ secrets.MY_PAT }}" | gh auth login --with-token

  - name: Configure Git credential helper
    run: gh auth setup-git

  - name: Install dependencies
    run: uv sync --locked

Publishing to PyPI

Publish packages using trusted publishing (no credentials needed):
1

Create publish workflow

name: Publish

on:
  push:
    tags:
      - v*

jobs:
  publish:
    runs-on: ubuntu-latest
    environment:
      name: pypi
    permissions:
      id-token: write
      contents: read

    steps:
      - uses: actions/checkout@v6

      - name: Install uv
        uses: astral-sh/setup-uv@v7

      - name: Install Python
        run: uv python install 3.13

      - name: Build
        run: uv build

      - name: Test wheel
        run: uv run --isolated --no-project --with dist/*.whl tests/smoke_test.py

      - name: Test source distribution
        run: uv run --isolated --no-project --with dist/*.tar.gz tests/smoke_test.py

      - name: Publish
        run: uv publish
2

Configure PyPI environment

Create a pypi environment in your repository settings under Settings → Environments.
3

Add trusted publisher

Configure trusted publishing in your PyPI project settings, matching the workflow name, environment, and repository details.
4

Trigger release

git tag -a v0.1.0 -m v0.1.0
git push --tags
See astral-sh/trusted-publishing-examples for a complete working example.

Build docs developers (and LLMs) love