name: Version on: push: branches: - main permissions: contents: write jobs: version: name: Version outputs: new_tag: ${{ steps.bump.outputs.new_tag }} skip: ${{ steps.bump.outputs.skip }} 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 # No tags exist yet, create the initial v0.0.0 release echo "No existing tags found. Creating initial v0.0.0 release." echo "skip=false" >> "$GITHUB_OUTPUT" echo "new_tag=v0.0.0" >> "$GITHUB_OUTPUT" echo "initial=true" >> "$GITHUB_OUTPUT" exit 0 fi COMMITS=$(git log "${LATEST_TAG}..HEAD" --pretty=format:"%s" --no-merges) 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" echo "initial=false" >> "$GITHUB_OUTPUT" - name: Generate release notes if: steps.bump.outputs.skip == 'false' run: | if [ "${{ steps.bump.outputs.initial }}" = "true" ]; then echo "Initial release" > release_notes.txt else PREVIOUS_TAG="${{ steps.bump.outputs.previous_tag }}" git log "${PREVIOUS_TAG}..HEAD" --pretty=format:"- %s" --no-merges > release_notes.txt fi - 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 publish: name: Publish needs: version if: needs.version.outputs.skip != 'true' uses: ./.github/workflows/publish.yml with: version: ${{ needs.version.outputs.new_tag }}