Release #72
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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: β" |