From 9b6224e92891b7c94e08091f463f7213239c0ec1 Mon Sep 17 00:00:00 2001 From: Nicklas af Ekenstam Date: Wed, 15 Apr 2026 11:49:01 +0200 Subject: [PATCH] feat: Auto version bump on merge to main GitHub Action that runs on push to main: - Parses squash commit title for bump type (feat: -> minor, fix: -> patch) - Bumps __version__ in shipkit/__init__.py - Commits and tags (v0.1.14, etc.) - Skips its own commits to prevent infinite loops --- .github/workflows/version-bump.yml | 90 ++++++++++++++++++++++++++++++ 1 file changed, 90 insertions(+) create mode 100644 .github/workflows/version-bump.yml diff --git a/.github/workflows/version-bump.yml b/.github/workflows/version-bump.yml new file mode 100644 index 0000000..2924c48 --- /dev/null +++ b/.github/workflows/version-bump.yml @@ -0,0 +1,90 @@ +name: Version Bump + +on: + push: + branches: [main] + +# Prevent concurrent version bumps +concurrency: + group: version-bump + cancel-in-progress: false + +jobs: + bump: + runs-on: ubuntu-latest + # Skip if the commit was made by this action (prevent infinite loop) + if: "!startsWith(github.event.head_commit.message, 'v')" + + permissions: + contents: write + + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + token: ${{ secrets.GITHUB_TOKEN }} + + - name: Determine bump type from commit message + id: bump + run: | + MSG="${{ github.event.head_commit.message }}" + # Extract first line of squash commit message + FIRST_LINE=$(echo "$MSG" | head -1) + + if echo "$FIRST_LINE" | grep -qiE '^breaking[:(]|BREAKING CHANGE'; then + echo "type=major" >> "$GITHUB_OUTPUT" + elif echo "$FIRST_LINE" | grep -qiE '^feat[:(]'; then + echo "type=minor" >> "$GITHUB_OUTPUT" + else + echo "type=patch" >> "$GITHUB_OUTPUT" + fi + + echo "Commit: $FIRST_LINE" + echo "Bump type: $(cat "$GITHUB_OUTPUT" | grep type | cut -d= -f2)" + + - name: Read current version + id: current + run: | + VERSION=$(python3 -c " + import re + with open('shipkit/__init__.py') as f: + match = re.search(r'__version__ = \"(.+?)\"', f.read()) + print(match.group(1)) + ") + echo "version=$VERSION" >> "$GITHUB_OUTPUT" + echo "Current version: $VERSION" + + - name: Calculate new version + id: new + run: | + IFS='.' read -r MAJOR MINOR PATCH <<< "${{ steps.current.outputs.version }}" + BUMP="${{ steps.bump.outputs.type }}" + + if [ "$BUMP" = "major" ]; then + MAJOR=$((MAJOR + 1)) + MINOR=0 + PATCH=0 + elif [ "$BUMP" = "minor" ]; then + MINOR=$((MINOR + 1)) + PATCH=0 + else + PATCH=$((PATCH + 1)) + fi + + NEW_VERSION="$MAJOR.$MINOR.$PATCH" + echo "version=$NEW_VERSION" >> "$GITHUB_OUTPUT" + echo "New version: $NEW_VERSION ($BUMP bump)" + + - name: Update version in __init__.py + run: | + sed -i "s/__version__ = \".*\"/__version__ = \"${{ steps.new.outputs.version }}\"/" shipkit/__init__.py + cat shipkit/__init__.py + + - name: Commit and tag + run: | + git config user.name "github-actions[bot]" + git config user.email "github-actions[bot]@users.noreply.github.com" + git add shipkit/__init__.py + git commit -m "v${{ steps.new.outputs.version }}" + git tag "v${{ steps.new.outputs.version }}" + git push origin main --tags