Skip to content

initial commit

initial commit #1

Workflow file for this run

name: publish
on:
push:
tags:
- "v*"
branches:
- master
workflow_dispatch:
inputs:
dry_run:
description: "Skip actual PyPI publish"
required: false
default: "false"
type: choice
options:
- "true"
- "false"
permissions:
contents: write
jobs:
validate:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- uses: astral-sh/setup-uv@v5
with:
python-version: "3.12"
cache-dependency-glob: "uv.lock"
- name: Install dev dependencies
run: uv sync --extra dev
- name: ruff check
run: uv run ruff check .
- name: ruff format check
run: uv run ruff format --check .
- name: mypy
run: uv run mypy sourcery
- name: pytest
run: uv run pytest -q
- name: Version validation
if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/')
run: |
TAG_VERSION="${GITHUB_REF#refs/tags/v}"
TOML_VERSION=$(grep '^version = ' pyproject.toml | head -1 | sed 's/version = "\([^"]*\)"/\1/')
echo "Tag version: $TAG_VERSION"
echo "TOML version: $TOML_VERSION"
if [ "$TAG_VERSION" != "$TOML_VERSION" ]; then
echo "Error: Tag version ($TAG_VERSION) does not match pyproject.toml version ($TOML_VERSION)"
exit 1
fi
- name: Branch protection
if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/')
run: |
git branch -r --contains "${GITHUB_SHA}" | grep -q 'origin/master' || {
echo "Error: Tag must be on master branch"
exit 1
}
publish:
needs: validate
runs-on: ubuntu-latest
if: (github.event_name == 'push' && startsWith(github.ref, 'refs/tags/')) || github.event_name == 'workflow_dispatch'
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- uses: astral-sh/setup-uv@v5
with:
python-version: "3.12"
cache-dependency-glob: "uv.lock"
- name: Build
run: uv build
- name: Upload build artifacts
uses: actions/upload-artifact@v4
with:
name: dist
path: dist/
retention-days: 7
- name: Publish to PyPI
if: github.event_name != 'workflow_dispatch' || github.event.inputs.dry_run != 'true'
env:
PYPI_TOKEN: ${{ secrets.PYPI_TOKEN }}
run: uv publish --token "$PYPI_TOKEN"
- name: Create GitHub Release
if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/')
uses: softprops/action-gh-release@v2
with:
generate_release_notes: true
files: dist/*
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Build summary
run: |
DRY_RUN="${{ github.event.inputs.dry_run || 'false' }}"
if [ "$DRY_RUN" = "true" ]; then
echo "## Dry Run - Build completed (not published)" >> "$GITHUB_STEP_SUMMARY"
elif [ "${{ github.event_name }}" = "workflow_dispatch" ]; then
echo "## Manual Publish (no GitHub Release)" >> "$GITHUB_STEP_SUMMARY"
else
echo "## Published ${{ github.ref_name }}" >> "$GITHUB_STEP_SUMMARY"
fi
echo "" >> "$GITHUB_STEP_SUMMARY"
echo "### Files" >> "$GITHUB_STEP_SUMMARY"
echo '```' >> "$GITHUB_STEP_SUMMARY"
ls -lah dist/ >> "$GITHUB_STEP_SUMMARY"
echo '```' >> "$GITHUB_STEP_SUMMARY"
echo "" >> "$GITHUB_STEP_SUMMARY"
echo "### Hashes" >> "$GITHUB_STEP_SUMMARY"
echo '```' >> "$GITHUB_STEP_SUMMARY"
cd dist && sha256sum * >> "$GITHUB_STEP_SUMMARY"
echo '```' >> "$GITHUB_STEP_SUMMARY"