Skip to content

feat: initial commit #1

feat: initial commit

feat: initial commit #1

# .github/workflows/release-python.yml
# See https://docs.github.com/en/actions/reference/workflow-syntax-for-github-actions
name: Release Python Package
on:
push:
tags:
# Trigger on SemVer tags. Commitizen configured in pyproject.toml (Area 12)
# uses PEP 440 which is SemVer compatible.
- "v[0-9]+.[0-9]+.[0-9]+"
- "v[0-9]+.[0-9]+.[0-9]+-*" # Include pre-release tags
# Allow workflow to be run manually from the Actions tab for a specific tag
workflow_dispatch:
inputs:
tag:
description: 'Git tag to build and release (e.g., v1.2.3). Must already exist.'
required: true # User must provide a tag when manually dispatching
jobs:
# Job 1: Build the package and publish to TestPyPI
build_and_testpypi:
name: Build & Publish to TestPyPI
# Run on a consistent, standard build environment
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
ref: ${{ github.event_name == 'push' && github.ref || github.event.inputs.tag }}
- name: Set up uv
uses: astral-sh/setup-uv@v6
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version-file: .python-version
- name: Upload built package artifacts
# Upload packages so the publish job can access them.
uses: actions/upload-artifact@v4
with:
name: distribution-packages # Name the artifact
path: dist/ # Path to the built sdist/wheel files
retention-days: 7 # Keep built artifacts for 7 days
- name: Download built package artifacts
uses: actions/download-artifact@v4
with:
name: distribution-packages-{{ github.event.inputs.tag }}
path: dist/
# --- Publish to TestPyPI Step ---
# This step runs within the same job after build.
- name: Publish to TestPyPI
# Execute the Task Automation publish session for TestPyPI.
# This calls uv publish dist/* with TestPyPI credentials/config (Topic 10).
env:
# TestPyPI credentials stored as secrets in GitHub Settings -> Secrets
TWINE_USERNAME: __token__ # Standard username when using API tokens
TWINE_PASSWORD: ${{ secrets.TESTPYPI_API_TOKEN }}{% endraw } # Use GitHub Encrypted Secret
# Optional: If uv publish requires different config for repository URL, pass TWINE_REPOSITORY or similar
run: uvx nox -s publish-package -- --repository testpypi # Call the publish-package session, passing repository arg
# --- Get Changelog Content for Release Notes ---
# Use a standard action to extract changelog content.
# This action requires a standard CHANGELOG.md format.
- name: Get Release Notes from Changelog
id: changelog
uses: simple-changelog/action@v3 # Action to parse CHANGELOG.md
with:
path: CHANGELOG.md # Path to your CHANGELOG.md
tag: { "${{ github.event_name == 'push' && github.ref_name || github.event.inputs.tag }}" } # Pass the tag name
# Define outputs from this job that other jobs (like create_github_release) can use.
outputs:
changelog_body:
description: "Release notes body extracted from CHANGELOG.md"
value: {% raw %}${{ steps.changelog.outputs.changes }} # Output the extracted changelog body

Check failure on line 82 in .github/workflows/release-python.yml

View workflow run for this annotation

GitHub Actions / .github/workflows/release-python.yml

Invalid workflow file

You have an error in your yaml syntax on line 82
# Job 2: Publish to Production PyPI
# This job runs only if Job 1 completes successfully (implicit dependency)
# and only on tag push events (NOT manual dispatch for production).
publish_pypi:
name: Publish to Production PyPI
runs-on: ubuntu-latest
# This job explicitly depends on build_and_testpypi completing successfully
needs: build_and_testpypi
# Only run on tag push events, NOT on manual dispatch for the final PyPI publish
if: { "github.event_name == 'push' && startsWith(github.ref, 'refs/tags/v')" }
steps:
- name: Download package artifacts
uses: actions/download-artifact@v4
with:
name: distribution-packages
path: dist/
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version-file: .python-version
- name: Set up uv
uses: astral-sh/setup-uv@v6
# --- Publish to Production PyPI Step ---
- name: Publish to PyPI
# Execute the Task Automation publish session for Production PyPI.
# Calls uv publish dist/* which defaults to pypi.org (Topic 10).
# Configure Production PyPI credentials securely.
env:
# Production PyPI credentials stored as secrets in GitHub Settings -> Secrets
TWINE_USERNAME: __token__
TWINE_PASSWORD: ${{ secrets.PYPI_API_TOKEN }} # Use GitHub Encrypted Secret
# Optional: TWINE_REPOSITORY if publishing to a custom production index
run: uvx nox -s publish-package # Call the publish-package session (defaults to pypi.org)
# Job 3: Create GitHub Release (Runs regardless of PyPI publish success, relies on build job for info/artifacts)
create_github_release:
name: Create GitHub Release
runs-on: ubuntu-latest
# Needs the build job (which includes getting changelog)
needs: build_and_testpypi
# Only run this job if triggered by a tag push
if: (github.event_name == 'push' && startsWith(github.ref, 'refs/tags/v')
steps:
- name: Download package artifacts # Get built artifacts for release assets
uses: actions/download-artifact@v4
with:
name: distribution-packages
- name: Get tag name
id: get_tag
run: echo "tag=${{ github.ref_name }}" >> $GITHUB_OUTPUT
- name: Create GitHub Release
# Uses a standard action to create a release in GitHub based on the tag.
uses: softprops/action-gh-release@v2
with:
# The Git tag the release is associated with
tag_name: ${{ steps.get_tag.outputs.tag }}
# The name of the release (often the same as the tag)
name: Release ${{ steps.get_tag.outputs.tag }}
# The body of the release notes - access the output from the 'build_and_testpypi' job
body: ${{ needs.build_and_testpypi.outputs.changelog_body }} # Access changelog body from dependent job output
files: dist/* # Attach built sdist and wheel files as release assets
# Optional: Mark as a draft release for manual review before publishing
# draft: true
# Optional: Mark as a pre-release for tags containing hyphens (e.g., v1.0.0-rc1)
prerelease: ${{ contains(steps.get_tag.outputs.tag, '-') }} # Checks if tag contains hyphen (e.g. v1.0.0-rc.1)