Complete Python GitHub Actions system. PROACTIVELY activate for: (1) uv-based CI workflows (10-100x faster), (2) Matrix testing across Python versions, (3) Dependency caching with setup-uv, (4) Parallel test execution, (5) Reusable workflows, (6) Publishing to PyPI with trusted publishing, (7) Code coverage with codecov, (8) Security scanning. Provides: Workflow templates, caching config, matrix strategies, composite actions. Ensures fast, reliable CI/CD pipelines.
/plugin marketplace add JosiahSiegel/claude-plugin-marketplace/plugin install python-master@claude-plugin-marketplaceThis skill inherits all available tools. When active, it can use any tool Claude has access to.
| Action | Purpose | Speed |
|---|---|---|
astral-sh/setup-uv@v4 | Install uv + caching | 10-100x faster |
actions/setup-python@v5 | Traditional pip | Baseline |
| uv CI Pattern | Code |
|---|---|
| Setup | uses: astral-sh/setup-uv@v4 with enable-cache: true |
| Install Python | uv python install ${{ matrix.python-version }} |
| Sync deps | uv sync --all-extras |
| Run tests | uv run pytest |
| Matrix Strategy | Config |
|---|---|
| Python versions | python-version: ["3.11", "3.12", "3.13"] |
| Operating systems | os: [ubuntu-latest, windows-latest, macos-latest] |
| Fail fast | fail-fast: false for full coverage |
| Optimization | Technique |
|---|---|
| Caching | enable-cache: true with setup-uv |
| Parallel jobs | Split lint/test/build |
| Concurrency | cancel-in-progress: true |
| Path filters | paths: ["src/**", "tests/**"] |
Use for CI/CD pipelines:
Related skills:
python-package-managementpython-testingpython-type-hintsGitHub Actions is the primary CI/CD platform for Python projects. This guide covers best practices for fast, reliable, and efficient Python workflows.
# .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
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 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
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"
# 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
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!
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
# uv is 10-100x faster than pip
- uses: astral-sh/setup-uv@v4
with:
enable-cache: true
strategy:
fail-fast: true # Cancel all on first failure (faster feedback)
fail-fast: false # Run all (complete coverage)
jobs:
lint:
runs-on: ubuntu-latest
test:
needs: lint # Only run if lint passes
runs-on: ubuntu-latest
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true # Cancel previous runs on same branch
on:
push:
paths:
- "src/**"
- "tests/**"
- "pyproject.toml"
paths-ignore:
- "**.md"
- "docs/**"
# Free ARM64 runners for public repos
runs-on: ubuntu-24.04-arm64 # Faster for ARM-native workloads
# 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') }}
# Solution: Use uv to manage Python versions
- uses: astral-sh/setup-uv@v4
- run: uv python install 3.13 # Works even for newest versions
# Solution: Normalize line endings
- uses: actions/checkout@v4
with:
# Prevent Windows line ending issues
persist-credentials: false
# Or in .gitattributes
# *.py text eol=lf
This skill should be used when the user asks to "create a slash command", "add a command", "write a custom command", "define command arguments", "use command frontmatter", "organize commands", "create command with file references", "interactive command", "use AskUserQuestion in command", or needs guidance on slash command structure, YAML frontmatter fields, dynamic arguments, bash execution in commands, user interaction patterns, or command development best practices for Claude Code.
This skill should be used when the user asks to "create an agent", "add an agent", "write a subagent", "agent frontmatter", "when to use description", "agent examples", "agent tools", "agent colors", "autonomous agent", or needs guidance on agent structure, system prompts, triggering conditions, or agent development best practices for Claude Code plugins.
This skill should be used when the user asks to "create a hook", "add a PreToolUse/PostToolUse/Stop hook", "validate tool use", "implement prompt-based hooks", "use ${CLAUDE_PLUGIN_ROOT}", "set up event-driven automation", "block dangerous commands", or mentions hook events (PreToolUse, PostToolUse, Stop, SubagentStop, SessionStart, SessionEnd, UserPromptSubmit, PreCompact, Notification). Provides comprehensive guidance for creating and implementing Claude Code plugin hooks with focus on advanced prompt-based hooks API.