Skip to content

Commit 4944d59

Browse files
GeneAIclaude
andcommitted
chore: Enhance release workflow with automatic PyPI publishing
Improvements to .github/workflows/release.yml: - Added package validation step (twine check) - Extract version from git tag automatically - Generate release notes from CHANGELOG.md (with fallback to git log) - Add full changelog link to release notes - Improved PyPI publishing with verbose output - Only publish to PyPI on tag push (not manual workflow_dispatch) - Added id-token permission for future trusted publishing support How it works: 1. Push a version tag: git tag v1.6.3 && git push origin v1.6.3 2. GitHub Actions automatically: - Builds the package - Validates with twine check - Creates GitHub release with changelog - Publishes to PyPI (if PYPI_API_TOKEN secret is set) Setup required: - Add PYPI_API_TOKEN to GitHub repository secrets 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
1 parent 2c92a46 commit 4944d59

1 file changed

Lines changed: 41 additions & 9 deletions

File tree

.github/workflows/release.yml

Lines changed: 41 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,12 @@ on:
77
workflow_dispatch:
88

99
jobs:
10-
create-release:
10+
build-and-release:
1111
runs-on: ubuntu-latest
1212
permissions:
1313
contents: write
14+
id-token: write # Required for trusted publishing
15+
1416
steps:
1517
- uses: actions/checkout@v4
1618
with:
@@ -29,27 +31,57 @@ jobs:
2931
- name: Build package
3032
run: python -m build
3133

32-
- name: Generate changelog
34+
- name: Validate package
35+
run: |
36+
twine check dist/*
37+
echo "✓ Package validation passed"
38+
39+
- name: Extract version from tag
40+
id: version
41+
run: |
42+
VERSION=${GITHUB_REF#refs/tags/v}
43+
echo "version=$VERSION" >> $GITHUB_OUTPUT
44+
echo "Releasing version: $VERSION"
45+
46+
- name: Generate release notes
3347
id: changelog
3448
run: |
35-
echo "## What's Changed" > RELEASE_NOTES.md
36-
git log $(git describe --tags --abbrev=0 HEAD^)..HEAD --pretty=format:"- %s (%h)" >> RELEASE_NOTES.md
49+
if [ -f CHANGELOG.md ]; then
50+
# Extract current version section from CHANGELOG.md
51+
VERSION=${{ steps.version.outputs.version }}
52+
awk "/## \[$VERSION\]/,/## \[/" CHANGELOG.md | head -n -1 > RELEASE_NOTES.md
53+
54+
# If extraction failed or is empty, use git log
55+
if [ ! -s RELEASE_NOTES.md ]; then
56+
echo "## What's Changed in v$VERSION" > RELEASE_NOTES.md
57+
git log $(git describe --tags --abbrev=0 HEAD^)..HEAD --pretty=format:"- %s (%h)" >> RELEASE_NOTES.md
58+
fi
59+
else
60+
echo "## What's Changed" > RELEASE_NOTES.md
61+
git log $(git describe --tags --abbrev=0 HEAD^)..HEAD --pretty=format:"- %s (%h)" >> RELEASE_NOTES.md
62+
fi
63+
64+
echo "" >> RELEASE_NOTES.md
65+
echo "---" >> RELEASE_NOTES.md
66+
echo "**Full Changelog**: https://github.com/${{ github.repository }}/compare/$(git describe --tags --abbrev=0 HEAD^)...v${{ steps.version.outputs.version }}" >> RELEASE_NOTES.md
3767
3868
- name: Create GitHub Release
3969
uses: softprops/action-gh-release@v1
4070
with:
4171
body_path: RELEASE_NOTES.md
42-
files: |
43-
dist/*
72+
files: dist/*
4473
draft: false
4574
prerelease: false
75+
generate_release_notes: true
4676
env:
4777
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
4878

49-
- name: Publish to PyPI (if token configured)
50-
if: ${{ secrets.PYPI_API_TOKEN != '' }}
79+
- name: Publish to PyPI
80+
if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/')
5181
env:
5282
TWINE_USERNAME: __token__
5383
TWINE_PASSWORD: ${{ secrets.PYPI_API_TOKEN }}
5484
run: |
55-
twine upload dist/*
85+
echo "📦 Publishing to PyPI..."
86+
twine upload dist/* --verbose
87+
echo "✅ Published to PyPI successfully!"

0 commit comments

Comments
 (0)