feat(ci): auto release PR on push to main #9
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: | |
| push: | |
| branches: [main] | |
| permissions: | |
| contents: write | |
| pull-requests: write | |
| jobs: | |
| release-pr: | |
| name: Create or update release PR | |
| runs-on: ubuntu-latest | |
| # Skip release commits to avoid infinite loops | |
| if: "!startsWith(github.event.head_commit.message, 'chore(release):')" | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v4 | |
| with: | |
| fetch-depth: 0 | |
| - name: Determine next version | |
| id: next | |
| run: | | |
| set -euo pipefail | |
| # Get current version from version.go | |
| CURRENT=$(sed -n 's/^const Version = "\(.*\)"/\1/p' version.go) | |
| echo "current=$CURRENT" >> $GITHUB_OUTPUT | |
| # Use git-cliff to calculate the bumped version | |
| pip install git-cliff >/dev/null 2>&1 || true | |
| NEXT=$(git cliff --bumped-version 2>/dev/null | sed 's/^v//') | |
| if [ -z "$NEXT" ] || [ "$NEXT" = "$CURRENT" ]; then | |
| echo "No version bump needed" | |
| echo "bump=false" >> $GITHUB_OUTPUT | |
| exit 0 | |
| fi | |
| echo "version=$NEXT" >> $GITHUB_OUTPUT | |
| echo "tag=v$NEXT" >> $GITHUB_OUTPUT | |
| echo "bump=true" >> $GITHUB_OUTPUT | |
| echo "Bumping $CURRENT -> $NEXT" | |
| - name: Update version.go | |
| if: steps.next.outputs.bump == 'true' | |
| run: | | |
| VERSION="${{ steps.next.outputs.version }}" | |
| sed -i "s/const Version = \".*\"/const Version = \"$VERSION\"/" version.go | |
| - name: Generate changelog | |
| if: steps.next.outputs.bump == 'true' | |
| uses: orhun/git-cliff-action@v4 | |
| with: | |
| config: cliff.toml | |
| args: --tag ${{ steps.next.outputs.tag }} | |
| env: | |
| OUTPUT: CHANGELOG.md | |
| - name: Create release PR | |
| if: steps.next.outputs.bump == 'true' | |
| uses: peter-evans/create-pull-request@v6 | |
| with: | |
| token: ${{ secrets.GITHUB_TOKEN }} | |
| base: main | |
| commit-message: "chore(release): bump version to ${{ steps.next.outputs.version }}" | |
| branch: release/next | |
| title: "chore(release): v${{ steps.next.outputs.version }}" | |
| body: | | |
| ## Release `v${{ steps.next.outputs.version }}` | |
| Automated release preparation. | |
| ### Changes | |
| - Update `version.go` to `${{ steps.next.outputs.version }}` | |
| - Refresh `CHANGELOG.md` | |
| ### After merge | |
| A GitHub Release with tag `v${{ steps.next.outputs.version }}` will be created automatically. | |
| add-paths: | | |
| version.go | |
| CHANGELOG.md | |
| labels: release | |
| publish-release: | |
| name: Publish GitHub release | |
| runs-on: ubuntu-latest | |
| # Only run on release commits (merged release PR) | |
| if: startsWith(github.event.head_commit.message, 'chore(release):') | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v4 | |
| with: | |
| fetch-depth: 0 | |
| - name: Extract version | |
| id: release | |
| run: | | |
| set -euo pipefail | |
| VERSION=$(sed -n 's/^const Version = "\(.*\)"/\1/p' version.go) | |
| if [ -z "$VERSION" ]; then | |
| echo "Unable to determine version" >&2 | |
| exit 1 | |
| fi | |
| echo "version=$VERSION" >> $GITHUB_OUTPUT | |
| echo "tag=v$VERSION" >> $GITHUB_OUTPUT | |
| - name: Configure git | |
| run: | | |
| git config user.name "github-actions[bot]" | |
| git config user.email "github-actions[bot]@users.noreply.github.com" | |
| - name: Create and push tag | |
| run: | | |
| TAG="${{ steps.release.outputs.tag }}" | |
| git tag -a "$TAG" -m "Release $TAG" | |
| git push origin "$TAG" | |
| - name: Get previous tag | |
| id: prev_tag | |
| run: | | |
| PREV_TAG=$(git describe --tags --abbrev=0 HEAD^ 2>/dev/null || echo "") | |
| echo "tag=$PREV_TAG" >> $GITHUB_OUTPUT | |
| - name: Generate release notes | |
| id: changelog | |
| uses: orhun/git-cliff-action@v4 | |
| with: | |
| config: cliff.toml | |
| args: >- | |
| ${{ steps.prev_tag.outputs.tag && format('{0}..{1}', steps.prev_tag.outputs.tag, steps.release.outputs.tag) || steps.release.outputs.tag }} | |
| env: | |
| OUTPUT: /tmp/RELEASE_CHANGELOG.md | |
| - name: Create GitHub Release | |
| uses: softprops/action-gh-release@v2 | |
| with: | |
| tag_name: ${{ steps.release.outputs.tag }} | |
| body: ${{ steps.changelog.outputs.content }} | |
| draft: false | |
| prerelease: false | |
| generate_release_notes: false | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} |