关于 python-github-actions
面向 Python 项目的 GitHub Actions CI/CD 实践指南,涵盖依赖安装、测试矩阵、缓存、可复用工作流和包发布。
主要功能
- 01配置 uv 与 pip 工作流
- 02依赖缓存
- 03Python 与操作系统测试矩阵
- 04并行及可复用工作流
- 05PyPI 发布指南
适用场景
- 01为 Python 项目搭建 CI
- 02跨 Python 版本和操作系统运行测试
- 03减少重复下载依赖
- 04自动发布软件包到 PyPI
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ josiahsiegel/ claude-plugin-marketplace --skill python-github-actions安装后在 Claude Code 中输入/python-github-actions确认已加载。
详细介绍
快速参考
| 操作 | 用途 | 速度 |
|---|---|---|
astral-sh/setup-uv@v4 | 安装 uv 并启用缓存 | 快 10–100 倍 |
actions/setup-python@v5 | 传统 pip | 基准 |
| uv CI 模式 | 代码 |
|---|---|
| 设置 | uses: astral-sh/setup-uv@v4,并设置 enable-cache: true |
| 安装 Python | uv python install ${{ matrix.python-version }} |
| 同步依赖 | uv sync --all-extras |
| 运行测试 | uv run pytest |
| 矩阵策略 | 配置 |
|---|---|
| Python 版本 | python-version: ["3.11", "3.12", "3.13"] |
| 操作系统 | os: [ubuntu-latest, windows-latest, macos-latest] |
| 快速失败 | 设置 fail-fast: false 以实现完整覆盖 |
| 优化项 | 方法 |
|---|---|
| 缓存 | 配合 setup-uv 设置 enable-cache: true |
| 并行作业 | 将 lint/test/build 拆分开 |
| 并发 | cancel-in-progress: true |
| 路径筛选 | paths: ["src/**", "tests/**"] |
何时使用此技能
适用于 CI/CD 工作流:
- 为 Python 项目配置 GitHub Actions
- 缓存依赖项,加快构建
- 跨多个 Python 版本进行矩阵测试
- 将软件包发布到 PyPI
- 代码覆盖率和安全扫描
相关技能:
- 有关软件包管理,请参见
python-package-management - 有关测试,请参见
python-testing - 有关类型检查,请参见
python-type-hints
Python GitHub Actions 优化
概述
GitHub Actions 是 Python 项目的主要 CI/CD 平台。本指南介绍如何构建快速、可靠且高效的 Python 工作流。
快速入门工作流
# .github/workflows/ci.yml
name: CI
on:
push:
branches: [main]
pull_request:
branches: [main]
jobs:
test:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: ["3.11", "3.12", "3.13"]
steps:
- uses: actions/checkout@v4
- name: Install uv
uses: astral-sh/setup-uv@v4
- name: Set up Python ${{ matrix.python-version }}
run: uv python install ${{ matrix.python-version }}
- name: Install dependencies
run: uv sync --all-extras --dev
- name: Run linting
run: uv run ruff check .
- name: Run type checking
run: uv run mypy src
- name: Run tests
run: uv run pytest --cov
基于 uv 的现代工作流
使用 uv 进行设置
name: CI with uv
on:
push:
branches: [main]
pull_request:
jobs:
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install uv
uses: astral-sh/setup-uv@v4
with:
version: "latest"
enable-cache: true # Automatic caching!
- name: Lint with ruff
run: |
uv run ruff check .
uv run ruff format --check .
type-check:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: astral-sh/setup-uv@v4
with:
enable-cache: true
- name: Type check with mypy
run: uv run mypy src
test:
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
python-version: ["3.11", "3.12", "3.13"]
steps:
- uses: actions/checkout@v4
- uses: astral-sh/setup-uv@v4
with:
enable-cache: true
- name: Set up Python
run: uv python install ${{ matrix.python-version }}
- name: Install dependencies
run: uv sync --all-extras
- name: Run tests
run: uv run pytest -v --cov --cov-report=xml
- name: Upload coverage
uses: codecov/codecov-action@v4
with:
file: ./coverage.xml
使用 uv 缓存依赖项
# uv handles caching automatically with setup-uv
- uses: astral-sh/setup-uv@v4
with:
enable-cache: true
cache-dependency-glob: "uv.lock"
# This caches:
# - Downloaded packages
# - Python installations
# - Virtual environments
基于传统 pip 的工作流
手动设置缓存
name: CI with pip
on: [push, pull_request]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: "3.12"
cache: "pip" # Built-in pip caching
cache-dependency-path: |
requirements.txt
requirements-dev.txt
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -r requirements.txt
pip install -r requirements-dev.txt
- name: Run tests
run: pytest
高级缓存
- name: Cache pip packages
uses: actions/cache@v4
with:
path: ~/.cache/pip
key: ${{ runner.os }}-pip-${{ hashFiles('**/requirements*.txt') }}
restore-keys: |
${{ runner.os }}-pip-
- name: Cache pre-commit hooks
uses: actions/cache@v4
with:
path: ~/.cache/pre-commit
key: pre-commit-${{ hashFiles('.pre-commit-config.yaml') }}
并行构建与矩阵构建
高效的矩阵策略
jobs:
test:
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false # Don't cancel all on first failure
matrix:
os: [ubuntu-latest, windows-latest, macos-latest]
python-version: ["3.11", "3.12", "3.13"]
exclude:
# Skip Python 3.13 on Windows (if issues)
- os: windows-latest
python-version: "3.13"
steps:
- uses: actions/checkout@v4
- uses: astral-sh/setup-uv@v4
with:
enable-cache: true
- run: uv python install ${{ matrix.python-version }}
- run: uv sync
- run: uv run pytest
按测试类型拆分
jobs:
unit:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: astral-sh/setup-uv@v4
- run: uv sync
- run: uv run pytest tests/unit -v
integration:
runs-on: ubuntu-latest
needs: unit # Run after unit tests pass
steps:
- uses: actions/checkout@v4
- uses: astral-sh/setup-uv@v4
- run: uv sync
- run: uv run pytest tests/integration -v
e2e:
runs-on: ubuntu-latest
needs: integration
steps:
- uses: actions/checkout@v4
- uses: astral-sh/setup-uv@v4
- run: uv sync
- run: uv run pytest tests/e2e -v
可复用工作流
复合操作
# .github/actions/python-setup/action.yml
name: Python Setup
description: Set up Python environment with uv
inputs:
python-version:
description: Python version to use
default: "3.12"
runs:
using: composite
steps:
- name: Install uv
uses: astral-sh/setup-uv@v4
with:
enable-cache: true
- name: Set up Python
shell: bash
run: uv python install ${{ inputs.python-version }}
- name: Install dependencies
shell: bash
run: uv sync --all-extras
# .github/workflows/ci.yml
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: ./.github/actions/python-setup
with:
python-version: "3.12"
- run: uv run pytest
可复用工作流
# .github/workflows/python-test.yml
name: Reusable Python Test
on:
workflow_call:
inputs:
python-version:
type: string
default: "3.12"
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: astral-sh/setup-uv@v4
with:
enable-cache: true
- run: uv python install ${{ inputs.python-version }}
- run: uv sync
- run: uv run pytest
# .github/workflows/ci.yml
jobs:
test-3-11:
uses: ./.github/workflows/python-test.yml
with:
python-version: "3.11"
test-3-12:
uses: ./.github/workflows/python-test.yml
with:
python-version: "3.12"
YAML 锚点(2025 年功能)
# Reduce repetition with anchors
name: CI
on: [push, pull_request]
# Define anchor
x-common-steps: &common-steps
- uses: actions/checkout@v4
- uses: astral-sh/setup-uv@v4
with:
enable-cache: true
jobs:
lint:
runs-on: ubuntu-latest
steps:
*common-steps # Reference anchor
- run: uv run ruff check .
test:
runs-on: ubuntu-latest
steps:
*common-steps # Reuse same steps
- run: uv sync
- run: uv run pytest
发布到 PyPI
name: Publish
on:
release:
types: [published]
jobs:
publish:
runs-on: ubuntu-latest
permissions:
id-token: write # Required for trusted publishing
steps:
- uses: actions/checkout@v4
- uses: astral-sh/setup-uv@v4
- name: Build package
run: uv build
- name: Publish to PyPI
uses: pypa/gh-action-pypi-publish@release/v1
# No password needed with trusted publishing!
完整 CI/CD 示例
name: CI/CD
on:
push:
branches: [main]
pull_request:
release:
types: [published]
env:
PYTHON_VERSION: "3.12"
jobs:
# ========== Quality Checks ==========
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: astral-sh/setup-uv@v4
with:
enable-cache: true
- run: uv sync --only-dev
- run: uv run ruff check .
- run: uv run ruff format --check .
type-check:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: astral-sh/setup-uv@v4
with:
enable-cache: true
- run: uv sync
- run: uv run mypy src
# ========== Tests ==========
test:
needs: [lint, type-check]
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, windows-latest, macos-latest]
python-version: ["3.11", "3.12", "3.13"]
steps:
- uses: actions/checkout@v4
- uses: astral-sh/setup-uv@v4
with:
enable-cache: true
- run: uv python install ${{ matrix.python-version }}
- run: uv sync
- name: Run tests
run: uv run pytest -v --cov --cov-report=xml
- name: Upload coverage
if: matrix.os == 'ubuntu-latest' && matrix.python-version == '3.12'
uses: codecov/codecov-action@v4
with:
file: ./coverage.xml
fail_ci_if_error: true
# ========== Security ==========
security:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: astral-sh/setup-uv@v4
- run: uv sync
- run: uv run pip-audit # Check for known vulnerabilities
- run: uv run bandit -r src # Security linting
# ========== Build ==========
build:
needs: test
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: astral-sh/setup-uv@v4
- name: Build package
run: uv build
- name: Upload artifact
uses: actions/upload-artifact@v4
with:
name: dist
path: dist/
# ========== Publish ==========
publish:
if: github.event_name == 'release'
needs: build
runs-on: ubuntu-latest
permissions:
id-token: write
steps:
- uses: actions/download-artifact@v4
with:
name: dist
path: dist/
- name: Publish to PyPI
uses: pypa/gh-action-pypi-publish@release/v1
性能优化技巧
1. 使用 uv 实现最快安装
# uv is 10-100x faster than pip
- uses: astral-sh/setup-uv@v4
with:
enable-cache: true
2. 快速失败(或不快速失败)
strategy:
fail-fast: true # Cancel all on first failure (faster feedback)
fail-fast: false # Run all (complete coverage)
3. 作业依赖关系
jobs:
lint:
runs-on: ubuntu-latest
test:
needs: lint # Only run if lint passes
runs-on: ubuntu-latest
4. 并发控制
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true # Cancel previous runs on same branch
5. 跳过不必要的运行
on:
push:
paths:
- "src/**"
- "tests/**"
- "pyproject.toml"
paths-ignore:
- "**.md"
- "docs/**"
6. ARM64 运行器(2025 年)
# Free ARM64 runners for public repos
runs-on: ubuntu-24.04-arm64 # Faster for ARM-native workloads
常见问题与解决方案
问题:pip install 速度慢
# Solution: Use uv
- uses: astral-sh/setup-uv@v4
with:
enable-cache: true
问题:缓存不起作用
# Solution: Verify cache key matches dependency files
- uses: actions/cache@v4
with:
path: ~/.cache
key: deps-${{ hashFiles('uv.lock', 'pyproject.toml') }}
问题:找不到 Python 版本
# Solution: Use uv to manage Python versions
- uses: astral-sh/setup-uv@v4
- run: uv python install 3.13 # Works even for newest versions
问题:测试在 Windows 上失败
# Solution: Normalize line endings
- uses: actions/checkout@v4
with:
# Prevent Windows line ending issues
persist-credentials: false
# Or in .gitattributes
# *.py text eol=lf
评论
支持 Markdown