Contracts
github-release-workflow.yml
Contract: GitHub Actions Workflow for PyPI Publish
name: Publish Release
on:
push:
tags:
- 'v*.*.*'
jobs:
release:
runs-on: ubuntu-latest
permissions:
contents: read
id-token: write
steps:
- name: Check out repository
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.11'
- name: Install tooling
run: |
python -m pip install --upgrade pip
pip install build==1.* twine==5.* tomli==2.* pytest
- name: Run tests
run: python -m pytest
- name: Validate release metadata
run: python scripts/release/validate_release.py --tag "${GITHUB_REF_NAME}"
- name: Build distributions
run: python -m build
- name: Publish to PyPI
uses: pypa/gh-action-pypi-publish@release/v1
with:
password: ${{ secrets.PYPI_API_TOKEN }}
verbose: true
- name: Record artifact checksums
if: success()
run: |
sha256sum dist/* > dist/SHA256SUMS.txt
cat dist/SHA256SUMS.txt
Acceptance Criteria
- Workflow MUST exit prior to upload when tests fail, metadata validation fails, or version mismatches are detected.
- Tag triggers MUST be limited to semantic versions prefixed with
v. PYPI_API_TOKEN secret MUST be required; run fails with explicit error if missing.- Build artifacts MUST include both
.whl and .tar.gz files.
release-validation-cli.md
Contract: Release Validation Script
Command
python scripts/release/validate_release.py [--tag vX.Y.Z]
--tag (optional): Explicit semantic tag to validate against; defaults to the current GITHUB_REF_NAME in CI or derives from git history locally.- Repository files read:
pyproject.tomlCHANGELOG.md.git/refs/tags/* (for latest annotated tag when --tag omitted)
Outputs
- Exit code
0 when: pyproject.toml version matches the semantic tag (including v prefix).CHANGELOG.md contains a heading for the version and non-empty notes.pyproject.toml version is greater than the most recent published tag.- Exit code
1 when any validation fails. Script prints actionable errors: - Missing or malformed tag.
- Version mismatch between files.
- Changelog entry absent.
- Version regression relative to the latest git tag.
Side Effects
- No files are mutated.
- Standard output lists validation summary; standard error includes failure rationale.
Acceptance Criteria
- Script MUST run identically in local environments and CI.
- Error messages MUST guide the maintainer to fix version/changelog/tag alignment.
- All failures MUST prevent the publish job from advancing to upload.