Prepare Release #4
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: Prepare Release | |
| on: | |
| workflow_dispatch: | |
| inputs: | |
| version: | |
| description: 'Version number (e.g., 0.6.0)' | |
| required: true | |
| type: string | |
| permissions: | |
| contents: write | |
| pull-requests: write | |
| jobs: | |
| prepare: | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| with: | |
| fetch-depth: 0 | |
| - name: Validate version format | |
| run: | | |
| if ! echo "${{ inputs.version }}" | grep -qE '^[0-9]+\.[0-9]+\.[0-9]+$'; then | |
| echo "Error: Version must be in format X.Y.Z (e.g., 0.6.0)" | |
| exit 1 | |
| fi | |
| - name: Configure git | |
| run: | | |
| git config user.name "github-actions[bot]" | |
| git config user.email "github-actions[bot]@users.noreply.github.com" | |
| - name: Create release branch | |
| run: | | |
| VERSION="${{ inputs.version }}" | |
| # Delete remote branch if it exists from a previous attempt | |
| git push origin --delete "release/${VERSION}" 2>/dev/null || true | |
| git checkout -b "release/${VERSION}" | |
| - name: Update CHANGELOG.md | |
| env: | |
| GITHUB_REPOSITORY: ${{ github.repository }} | |
| run: | | |
| VERSION="${{ inputs.version }}" | |
| DATE=$(date +%Y-%m-%d) | |
| # Create the new Unreleased section template | |
| UNRELEASED_TEMPLATE=$(printf '%s\n\n%s\n\n%s\n\n%s\n\n%s\n\n' \ | |
| '## [Unreleased]' \ | |
| '### Added' \ | |
| '### Changed' \ | |
| '### Fixed' \ | |
| '### Removed') | |
| # Read the current changelog | |
| CHANGELOG=$(cat CHANGELOG.md) | |
| # Check if there's an existing Unreleased section | |
| if grep -q "^## \[Unreleased\]" CHANGELOG.md; then | |
| # Replace [Unreleased] with the new version and date | |
| # First, extract everything after the Unreleased header until the next ## section | |
| # Then insert the new Unreleased section at the top | |
| # Use awk to do the replacement | |
| awk -v version="$VERSION" -v date="$DATE" -v template="$UNRELEASED_TEMPLATE" ' | |
| /^## \[Unreleased\]/ { | |
| print template | |
| print "## [" version "] - " date | |
| next | |
| } | |
| { print } | |
| ' CHANGELOG.md > CHANGELOG.md.tmp | |
| mv CHANGELOG.md.tmp CHANGELOG.md | |
| else | |
| # No Unreleased section exists - insert new version after the header | |
| # Find the first ## line and insert before it | |
| awk -v version="$VERSION" -v date="$DATE" -v template="$UNRELEASED_TEMPLATE" ' | |
| BEGIN { inserted = 0 } | |
| /^## \[/ && !inserted { | |
| print template | |
| print "## [" version "] - " date | |
| print "" | |
| inserted = 1 | |
| } | |
| { print } | |
| ' CHANGELOG.md > CHANGELOG.md.tmp | |
| mv CHANGELOG.md.tmp CHANGELOG.md | |
| fi | |
| # Update the version links at the bottom of the CHANGELOG | |
| # Update the Unreleased link to compare from the new version | |
| sed -i "s|\[Unreleased\]: https://github.com/.*/compare/.*\.\.\.HEAD|[Unreleased]: https://github.com/${GITHUB_REPOSITORY}/compare/${VERSION}...HEAD|" CHANGELOG.md | |
| # Add the new version link if it doesn't exist (insert after Unreleased link) | |
| if ! grep -q "^\[${VERSION}\]:" CHANGELOG.md; then | |
| # Find the previous version from the changelog (first version after Unreleased) | |
| PREV_VERSION=$(grep -oP '^\[[\d.]+\]:' CHANGELOG.md | head -1 | tr -d '[]:' || echo "") | |
| if [ -n "$PREV_VERSION" ]; then | |
| VERSION_LINK="[${VERSION}]: https://github.com/${GITHUB_REPOSITORY}/releases/tag/${VERSION}" | |
| sed -i "/^\[Unreleased\]:/a ${VERSION_LINK}" CHANGELOG.md | |
| fi | |
| fi | |
| - name: Update pyproject.toml version | |
| run: | | |
| VERSION="${{ inputs.version }}" | |
| sed -i "s/^version = \".*\"/version = \"$VERSION\"/" pyproject.toml | |
| # Verify the change | |
| grep "^version = " pyproject.toml | |
| - name: Install uv | |
| uses: astral-sh/setup-uv@v4 | |
| with: | |
| version: "latest" | |
| - name: Set up Python | |
| uses: actions/setup-python@v5 | |
| with: | |
| python-version: "3.11" | |
| - name: Update lock file | |
| run: uv sync | |
| - name: Commit and push | |
| run: | | |
| VERSION="${{ inputs.version }}" | |
| git add CHANGELOG.md pyproject.toml uv.lock | |
| git commit -m "Release v${VERSION}" | |
| git push -u origin "release/${VERSION}" | |
| - name: Create Pull Request | |
| env: | |
| GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| run: | | |
| VERSION="${{ inputs.version }}" | |
| gh pr create \ | |
| --title "${VERSION}" \ | |
| --body "## Release v${VERSION} | |
| This PR prepares the release of version ${VERSION}. | |
| ### Changes | |
| - Updated version in pyproject.toml | |
| - Updated CHANGELOG.md | |
| - Updated uv.lock | |
| ### After Merge | |
| A GitHub Release will be automatically created when this PR is merged." \ | |
| --label "release" |