mcpField
P
python-github-actions

python-github-actions

github.com/josiahsiegel云与 DevOps5973 次安装19 周前更新
代码仓库

关于 python-github-actions

面向 Python 项目的 GitHub Actions CI/CD 实践指南,涵盖依赖安装、测试矩阵、缓存、可复用工作流和包发布。

主要功能

  1. 01配置 uv 与 pip 工作流
  2. 02依赖缓存
  3. 03Python 与操作系统测试矩阵
  4. 04并行及可复用工作流
  5. 05PyPI 发布指南

适用场景

  1. 01为 Python 项目搭建 CI
  2. 02跨 Python 版本和操作系统运行测试
  3. 03减少重复下载依赖
  4. 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
安装 Pythonuv 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