plugins/python3-development/skills/python3-publish-release-pipeline/SKILL.md
Set up CI/CD pipeline for Python package publishing to PyPI. Use when preparing to publish a package, when setting up automated releases, or when configuring GitHub Actions or GitLab CI for Python projects.
npx skillsauth add jamie-bitflight/claude_skills python3-publish-release-pipelineInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
<pipeline_target>$ARGUMENTS</pipeline_target>
The model configures CI/CD pipelines for automated Python package publishing.
<pipeline_target/>
If no argument provided, detect from repository (look for .github/ or .gitlab-ci.yml).
Consult ../python3-development/references/python3-standards.md when applying shared architecture, typing, testing, or CLI rules; full standards, graphs, and amendment process are documented there.
.github/
├── workflows/
│ ├── ci.yml # Run on every push/PR
│ ├── release.yml # Run on version tags
│ └── docs.yml # Optional: documentation
└── dependabot.yml # Optional: dependency updates
name: CI
on:
push:
branches: [main]
pull_request:
branches: [main]
jobs:
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install uv
uses: astral-sh/setup-uv@v4
with:
enable-cache: true
- name: Set up Python
run: uv python install 3.11
- name: Install dependencies
run: uv sync --all-extras
- name: Run ruff
run: |
uv run ruff check src/ tests/
uv run ruff format --check src/ tests/
- name: Run type check (ty default; swap to mypy if hooks/CI run mypy — not merely [tool.mypy])
run: uv run ty check src/ tests/
test:
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
python-version: ["3.11", "3.12", "3.13"]
steps:
- uses: actions/checkout@v4
- name: Install uv
uses: astral-sh/setup-uv@v4
with:
enable-cache: true
- name: Set up Python ${{ matrix.python-version }}
run: uv python install ${{ matrix.python-version }}
- name: Install dependencies
run: uv sync --all-extras
- name: Run tests
run: uv run pytest tests/ -v --cov=src --cov-report=xml
- name: Upload coverage
uses: codecov/codecov-action@v4
with:
files: coverage.xml
fail_ci_if_error: false
name: Release
on:
push:
tags:
- "v*.*.*"
permissions:
contents: write
id-token: write # Required for trusted publishing
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install uv
uses: astral-sh/setup-uv@v4
- name: Set up Python
run: uv python install 3.11
- name: Build package
run: uv build
- name: Upload artifacts
uses: actions/upload-artifact@v4
with:
name: dist
path: dist/
# Option 1: Trusted Publishing (Recommended)
publish-pypi:
needs: build
runs-on: ubuntu-latest
environment:
name: pypi
url: https://pypi.org/p/your-package
steps:
- name: Download artifacts
uses: actions/download-artifact@v4
with:
name: dist
path: dist/
- name: Publish to PyPI
uses: pypa/gh-action-pypi-publish@release/v1
# No token needed with trusted publishing!
# Option 2: Token-based Publishing (Alternative)
# publish-pypi:
# needs: build
# runs-on: ubuntu-latest
# steps:
# - name: Download artifacts
# uses: actions/download-artifact@v4
# with:
# name: dist
# path: dist/
#
# - name: Publish to PyPI
# uses: pypa/gh-action-pypi-publish@release/v1
# with:
# password: ${{ secrets.PYPI_API_TOKEN }}
github-release:
needs: [build, publish-pypi]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Download artifacts
uses: actions/download-artifact@v4
with:
name: dist
path: dist/
- name: Create GitHub Release
uses: softprops/action-gh-release@v2
with:
files: dist/*
generate_release_notes: true
stages:
- lint
- test
- build
- publish
variables:
UV_CACHE_DIR: "$CI_PROJECT_DIR/.uv-cache"
PIP_CACHE_DIR: "$CI_PROJECT_DIR/.pip-cache"
default:
image: python:3.11-slim
before_script:
- pip install uv
- uv sync --all-extras
cache:
key: "${CI_JOB_NAME}"
paths:
- .uv-cache/
- .pip-cache/
- .venv/
lint:
stage: lint
script:
- uv run ruff check src/ tests/
- uv run ruff format --check src/ tests/
- uv run ty check src/ tests/
test:
stage: test
parallel:
matrix:
- PYTHON_VERSION: ["3.11", "3.12", "3.13"]
image: python:${PYTHON_VERSION}-slim
script:
- uv run pytest tests/ -v --cov=src --cov-report=xml --junitxml=report.xml
coverage: '/TOTAL.*\s+(\d+%)/'
artifacts:
reports:
junit: report.xml
coverage_report:
coverage_format: cobertura
path: coverage.xml
build:
stage: build
script:
- uv build
artifacts:
paths:
- dist/
expire_in: 1 week
# Publish to PyPI on tags
publish:pypi:
stage: publish
rules:
- if: $CI_COMMIT_TAG =~ /^v\d+\.\d+\.\d+$/
script:
- uv publish --token $PYPI_TOKEN
environment:
name: pypi
url: https://pypi.org/project/your-package
# Publish to GitLab Package Registry on tags
publish:gitlab:
stage: publish
rules:
- if: $CI_COMMIT_TAG =~ /^v\d+\.\d+\.\d+$/
script:
- |
TWINE_PASSWORD=${CI_JOB_TOKEN} \
TWINE_USERNAME=gitlab-ci-token \
uv publish --publish-url ${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/packages/pypi
environment:
name: gitlab-registry
Go to PyPI → Your Project → Publishing
Add GitHub Publisher:
your-usernameyour-reporelease.ymlpypi (optional but recommended)Create GitHub Environment:
pypiIf trusted publishing isn't available:
Create PyPI Token:
Add to Repository Secrets:
PYPI_API_TOKENPYPI_TOKENUpdate version in pyproject.toml before tagging:
[project]
version = "1.2.3"
Using hatch-vcs:
[build-system]
requires = ["hatchling", "hatch-vcs"]
build-backend = "hatchling.build"
[project]
dynamic = ["version"]
[tool.hatch.version]
source = "vcs"
[tool.hatch.build.hooks.vcs]
version-file = "src/my_package/_version.py"
# 1. Update CHANGELOG.md
# 2. Commit changes
git add -A
git commit -m "Prepare release v1.2.3"
# 3. Create annotated tag
git tag -a v1.2.3 -m "Release v1.2.3"
# 4. Push with tags
git push origin main --tags
publish-testpypi:
needs: build
runs-on: ubuntu-latest
environment:
name: testpypi
url: https://test.pypi.org/p/your-package
steps:
- uses: actions/download-artifact@v4
with:
name: dist
path: dist/
- uses: pypa/gh-action-pypi-publish@release/v1
with:
repository-url: https://test.pypi.org/legacy/
# Build
uv build
# Upload to TestPyPI
uv publish --publish-url https://test.pypi.org/legacy/ --token $TESTPYPI_TOKEN
# Test install
uv pip install --index-url https://test.pypi.org/simple/ your-package
your-package/
├── pyproject.toml # Package metadata and build config
├── README.md # Required by PyPI
├── LICENSE # Required for distribution
├── src/
│ └── your_package/
│ ├── __init__.py
│ └── py.typed # PEP 561 marker
└── .github/
└── workflows/
├── ci.yml
└── release.yml
- [ ] [build-system] with requires and build-backend
- [ ] [project] with name, version, description
- [ ] readme = "README.md"
- [ ] license specified
- [ ] requires-python = ">=3.11"
- [ ] authors with name and email
- [ ] classifiers (Development Status, License, Python versions)
- [ ] dependencies list
- [ ] [project.urls] with Documentation, Issues, Source
- [ ] [project.scripts] if CLI tool
# Check package metadata
uv run python -m build --no-isolation
uvx twine check dist/*
# Verify token
echo $PYPI_TOKEN | head -c 10
# Check package name availability
curl https://pypi.org/pypi/your-package/json
PyPI doesn't allow re-uploading the same version. Increment version and create new tag.
development
When an application needs to store config, data, cache, or state files. When designing where user-specific files should live. When code writes to ~/.appname or hardcoded home paths. When implementing cross-platform file storage with platformdirs.
testing
Enforce mandatory pre-action verification checkpoints to prevent pattern-matching from overriding explicit reasoning. Use this skill when about to execute implementation actions (Bash, Write, Edit) to verify hypothesis-action alignment. Blocks execution when hypothesis unverified or action targets different system than hypothesis identified. Critical for preventing cognitive dissonance where correct diagnosis leads to wrong implementation.
tools
Reference guide for the Twelve-Factor App methodology — 15 principles (12 original + 3 modern extensions) for building portable, resilient, cloud-native applications. Use when evaluating application architecture, designing cloud-native services, reviewing codebases for methodology compliance, advising on configuration, scaling, observability, security, and deployment patterns. Incorporates the 2025 open-source community evolution and cloud-native reinterpretations of each factor.
tools
Converts user-facing documentation (how-to guides, tutorials, API references, examples) in any format — Markdown, PDF, DOCX, PPTX, XLSX, AsciiDoc, RST, HTML, Jupyter notebooks, man pages, TOML/YAML/JSON configs, and plain text — into Claude Code skill directories with SKILL.md plus thematically grouped references/*.md files. Use when given a docs directory or mixed-format documentation to transform into an AI skill. Uses MCP file-reader server for binary formats.