Skip to content

Release

Release #71

Workflow file for this run

name: Release
on:
workflow_dispatch:
concurrency: release
jobs:
release:
runs-on: ubuntu-latest
permissions:
contents: write # For git operations and GitHub releases
id-token: write # For PyPI OIDC publishing
attestations: write # For GitHub Attestations
steps:
- name: Checkout repository
uses: actions/checkout@v6
with:
fetch-depth: 0
- name: Install uv
uses: astral-sh/setup-uv@v7
- name: Set up Python
run: uv python install 3.12
- name: Set up Node.js
uses: actions/setup-node@v6
with:
node-version: 24
cache: npm
cache-dependency-path: package-lock.json
- name: Install dependencies
run: |
uv sync --all-packages
npm ci
- name: Get current version
id: version_info
run: |
CURRENT_VERSION=$(grep "^version = " pyproject.toml | sed 's/^version = "\([^"]*\)".*/\1/')
echo "current_version=$CURRENT_VERSION" >> $GITHUB_OUTPUT
- name: Show release plan
run: |
echo "πŸ“‹ RELEASE PLAN"
echo "Current Version: ${{ steps.version_info.outputs.current_version }}"
echo ""
echo "πŸ” Commits since last release:"
LAST_TAG=$(git describe --tags --abbrev=0 2>/dev/null || echo "")
if [ -n "$LAST_TAG" ]; then
git log ${LAST_TAG}..HEAD --oneline --pretty=format:"- %s (%h)"
else
echo "- No previous tags found"
fi
- name: Lint code
run: uv run poe lint
- name: Typecheck code
run: uv run poe typecheck
- name: Run tests
run: uv run poe test
- name: Semantic Release
id: semantic_release
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
echo "πŸš€ Running semantic release for alpha..."
# Configure git for commits
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
# Run semantic-release and capture the new version
# Use --prerelease to force alpha revision bumps on every release
SEMANTIC_OUTPUT=$(uv run semantic-release version --prerelease --no-push 2>&1)
SEMANTIC_EXIT_CODE=$?
echo "$SEMANTIC_OUTPUT"
if [ $SEMANTIC_EXIT_CODE -ne 0 ]; then
echo "Error: semantic-release failed with exit code $SEMANTIC_EXIT_CODE"
exit 1
fi
# Extract the version from "The next version is: X.Y.Z!" line
RELEASED_VERSION=$(echo "$SEMANTIC_OUTPUT" | grep "The next version is:" | sed 's/.*The next version is: \([^ !]*\).*/\1/')
echo "Released version: $RELEASED_VERSION"
# Make version available to subsequent steps
echo "version=$RELEASED_VERSION" >> $GITHUB_OUTPUT
# Sync inter-package dependency versions
echo "πŸ”„ Syncing inter-package dependency versions..."
python .github/scripts/sync-versions.py "$RELEASED_VERSION"
# Update lock file with new dependency versions
echo "πŸ”’ Updating lock file..."
uv sync --all-packages
# Check if there are changes to commit
if ! git diff --quiet; then
echo "πŸ“ Amending semantic-release commit with synced dependencies..."
git add .
git commit --amend --no-edit
# Update the tag to point to the amended commit
# Delete the old tag first, then create it again at the amended commit
git tag -d "v$RELEASED_VERSION"
git tag "v$RELEASED_VERSION"
else
echo "βœ“ No dependency version changes needed"
fi
# Push commit and tags
echo "⬆️ Pushing changes to remote..."
git push origin main --tags --force-with-lease
- name: Get released version
id: released_version
run: |
# Use the version from semantic-release step
RELEASED_VERSION="${{ steps.semantic_release.outputs.version }}"
echo "version=$RELEASED_VERSION" >> $GITHUB_OUTPUT
echo "Released version: $RELEASED_VERSION"
- name: Build all packages
run: uv build --all-packages
- name: Show build artifacts
run: |
echo "πŸ“¦ Built artifacts:"
ls -la dist/
- name: Generate artifact attestation
uses: actions/attest-build-provenance@v3
with:
subject-path: |
dist/*.whl
dist/*.tar.gz
- name: Create GitHub Release
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
echo "πŸš€ Creating GitHub release..."
VERSION=${{ steps.released_version.outputs.version }}
CHANGELOG_CONTENT="$(sed -n '/^## v'$VERSION'/,/^## /p' CHANGELOG.md 2>/dev/null | sed '$d')"
if [ -z "$CHANGELOG_CONTENT" ]; then
CHANGELOG_CONTENT="Release v$VERSION"
fi
gh release create "v$VERSION" \
--title "Release v$VERSION" \
--notes "$CHANGELOG_CONTENT" \
dist/*.whl dist/*.tar.gz
- name: Publish to PyPI
uses: pypa/gh-action-pypi-publish@release/v1
- name: Release Summary
run: |
echo "πŸŽ‰ RELEASE COMPLETED"
echo "Released version: ${{ steps.released_version.outputs.version }}"
echo "Published to PyPI: βœ“"
echo "GitHub release created: βœ“"
echo "Changelog updated: βœ“"