name: Version on: push: branches: - main permissions: contents: write jobs: version: name: Version runs-on: ubuntu-latest steps: - name: Checkout code uses: actions/checkout@v6 with: fetch-depth: 0 - name: Determine version bump id: bump run: | # Get the latest tag, default to v0.0.0 if none exists LATEST_TAG=$(git tag -l 'v*' --sort=-v:refname | head -n 1) if [ -z "$LATEST_TAG" ]; then LATEST_TAG="v0.0.0" COMMITS=$(git log --pretty=format:"%s" --no-merges) else COMMITS=$(git log "${LATEST_TAG}..HEAD" --pretty=format:"%s" --no-merges) fi echo "Latest tag: $LATEST_TAG" echo "Commits since last tag:" echo "$COMMITS" # Parse current version VERSION="${LATEST_TAG#v}" MAJOR=$(echo "$VERSION" | cut -d. -f1) MINOR=$(echo "$VERSION" | cut -d. -f2) PATCH=$(echo "$VERSION" | cut -d. -f3) # Determine bump type from conventional commits BUMP="none" if echo "$COMMITS" | grep -qiE "^[a-z]+(\(.+\))?!:|BREAKING CHANGE:"; then BUMP="major" elif echo "$COMMITS" | grep -qiE "^feat(\(.+\))?:"; then BUMP="minor" elif echo "$COMMITS" | grep -qiE "^(fix|perf|refactor|chore|docs|style|test|tests|build|ci)(\(.+\))?:"; then BUMP="patch" fi echo "Bump type: $BUMP" if [ "$BUMP" = "none" ]; then echo "skip=true" >> "$GITHUB_OUTPUT" exit 0 fi # Calculate new version case "$BUMP" in major) MAJOR=$((MAJOR + 1)) MINOR=0 PATCH=0 ;; minor) MINOR=$((MINOR + 1)) PATCH=0 ;; patch) PATCH=$((PATCH + 1)) ;; esac NEW_TAG="v${MAJOR}.${MINOR}.${PATCH}" echo "New version: $NEW_TAG" echo "skip=false" >> "$GITHUB_OUTPUT" echo "new_tag=$NEW_TAG" >> "$GITHUB_OUTPUT" echo "previous_tag=$LATEST_TAG" >> "$GITHUB_OUTPUT" - name: Generate release notes if: steps.bump.outputs.skip == 'false' id: notes run: | PREVIOUS_TAG="${{ steps.bump.outputs.previous_tag }}" if [ "$PREVIOUS_TAG" = "v0.0.0" ]; then NOTES=$(git log --pretty=format:"- %s" --no-merges) else NOTES=$(git log "${PREVIOUS_TAG}..HEAD" --pretty=format:"- %s" --no-merges) fi # Write notes to a file to preserve newlines echo "$NOTES" > release_notes.txt - name: Create tag and release if: steps.bump.outputs.skip == 'false' env: GH_TOKEN: ${{ github.token }} run: | NEW_TAG="${{ steps.bump.outputs.new_tag }}" git tag "$NEW_TAG" git push origin "$NEW_TAG" gh release create "$NEW_TAG" \ --title "$NEW_TAG" \ --notes-file release_notes.txt