Fix styling #10
Workflow file for this run
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: 'Generate Release Note' | |
| on: | |
| push: | |
| tags: | |
| - '[0-9]+.[0-9]+.[0-9]+' # Triggers for tags like 1.0.0, 2.1.3, etc. | |
| - 'v[0-9]+.[0-9]+.[0-9]+' # Triggers for tags like v1.0.0, v2.1.3, etc. | |
| permissions: | |
| contents: write | |
| pull-requests: read | |
| jobs: | |
| check-release-needed: | |
| runs-on: ubuntu-latest | |
| outputs: | |
| should-create-release: ${{ steps.check.outputs.should-create-release }} | |
| current-tag: ${{ steps.check.outputs.current-tag }} | |
| latest-tag: ${{ steps.check.outputs.latest-tag }} | |
| clean-version: ${{ steps.check.outputs.clean-version }} | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v5 | |
| with: | |
| fetch-depth: 0 | |
| token: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Check if release notes generation is needed | |
| id: check | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| run: | | |
| CURRENT_TAG="${{ github.ref_name }}" | |
| echo "Current tag: $CURRENT_TAG" | |
| # Remove 'v' prefix if present for version comparison | |
| CLEAN_VERSION="${CURRENT_TAG#v}" | |
| echo "Clean version: $CLEAN_VERSION" | |
| # Check if any release (including draft) already exists for this tag | |
| EXISTING_RELEASE=$(gh release view "$CURRENT_TAG" --json isDraft,tagName 2>/dev/null || echo "") | |
| if [[ -n "$EXISTING_RELEASE" ]]; then | |
| echo "Release (draft or published) already exists for tag: $CURRENT_TAG" | |
| echo "should-create-release=false" >> $GITHUB_OUTPUT | |
| exit 0 | |
| fi | |
| # Parse version components | |
| IFS='.' read -r MAJOR MINOR PATCH <<< "$CLEAN_VERSION" | |
| if [[ -z "$MAJOR" || -z "$MINOR" || -z "$PATCH" ]]; then | |
| echo "Invalid version format: $CLEAN_VERSION" | |
| echo "should-create-release=false" >> $GITHUB_OUTPUT | |
| exit 0 | |
| fi | |
| # Find the latest tag with same major.minor but lower patch version | |
| LATEST_TAG="" | |
| # Get all tags, filter by pattern, and find the latest one before current | |
| ALL_TAGS=$(git tag --list | grep -E "^v?${MAJOR}\.${MINOR}\.[0-9]+$" | sed 's/^v//' | sort -V) | |
| for tag in $ALL_TAGS; do | |
| IFS='.' read -r tag_major tag_minor tag_patch <<< "$tag" | |
| if [[ "$tag_patch" -lt "$PATCH" ]]; then | |
| LATEST_TAG="$tag" | |
| fi | |
| done | |
| # Add 'v' prefix back if original tag had it | |
| if [[ "$CURRENT_TAG" == v* ]] && [[ -n "$LATEST_TAG" ]]; then | |
| LATEST_TAG="v$LATEST_TAG" | |
| fi | |
| echo "Latest tag found: $LATEST_TAG" | |
| echo "should-create-release=true" >> $GITHUB_OUTPUT | |
| echo "current-tag=$CURRENT_TAG" >> $GITHUB_OUTPUT | |
| echo "latest-tag=$LATEST_TAG" >> $GITHUB_OUTPUT | |
| echo "clean-version=$CLEAN_VERSION" >> $GITHUB_OUTPUT | |
| generate-release-notes: | |
| needs: check-release-needed | |
| if: needs.check-release-needed.outputs.should-create-release == 'true' | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v5 | |
| with: | |
| fetch-depth: 0 | |
| token: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Generate release notes content | |
| id: generate-notes | |
| run: | | |
| CURRENT_TAG="${{ needs.check-release-needed.outputs.current-tag }}" | |
| LATEST_TAG="${{ needs.check-release-needed.outputs.latest-tag }}" | |
| CLEAN_VERSION="${{ needs.check-release-needed.outputs.clean-version }}" | |
| echo "Generating release notes for: $CURRENT_TAG" | |
| echo "Previous tag: $LATEST_TAG" | |
| # Get commits between tags | |
| if [[ -z "$LATEST_TAG" ]]; then | |
| echo "No previous tag found, getting all commits" | |
| COMMITS=$(git log --pretty=format:"%s|||%H" --reverse) | |
| else | |
| echo "Getting commits since: $LATEST_TAG" | |
| COMMITS=$(git log ${LATEST_TAG}..HEAD --pretty=format:"%s|||%H" --reverse) | |
| fi | |
| # Initialize categories | |
| BREAKING_CHANGES="" | |
| NEW_FEATURES="" | |
| DOCUMENTATION="" | |
| BUG_FIXES="" | |
| OTHER_CHANGES="" | |
| # Process each commit | |
| while IFS= read -r commit_line; do | |
| if [[ -z "$commit_line" ]]; then | |
| continue | |
| fi | |
| # Split commit message and hash | |
| COMMIT_MSG="${commit_line%|||*}" | |
| COMMIT_HASH="${commit_line#*|||}" | |
| SHORT_HASH="${COMMIT_HASH:0:7}" | |
| # Skip excluded commit patterns | |
| if echo "$COMMIT_MSG" | grep -qiE "^(Create |Update |Fix styling|wip|Merge branch)"; then | |
| continue | |
| fi | |
| # Skip dependabot merge requests | |
| if echo "$COMMIT_MSG" | grep -qiE "Merge pull request.*dependabot/github_actions"; then | |
| continue | |
| fi | |
| # Handle merge pull request commits - get PR title | |
| if echo "$COMMIT_MSG" | grep -qiE "^Merge pull request #[0-9]+"; then | |
| PR_NUMBER=$(echo "$COMMIT_MSG" | grep -oE "#[0-9]+" | sed 's/#//') | |
| if [[ -n "$PR_NUMBER" ]]; then | |
| # Try to get PR title using GitHub CLI | |
| PR_TITLE=$(gh pr view "$PR_NUMBER" --json title --jq '.title' 2>/dev/null || echo "") | |
| if [[ -n "$PR_TITLE" ]]; then | |
| COMMIT_MSG="$PR_TITLE" | |
| fi | |
| fi | |
| fi | |
| # Format commit for release notes | |
| FORMATTED_COMMIT="- $COMMIT_MSG ($SHORT_HASH)" | |
| # Categorize commits | |
| if echo "$COMMIT_MSG" | grep -qiE "(BREAKING CHANGE|breaking:|!:)"; then | |
| BREAKING_CHANGES="$BREAKING_CHANGES$FORMATTED_COMMIT"$'\n' | |
| elif echo "$COMMIT_MSG" | grep -qiE "^(feat|feature):|Merge.*feature/|Add.*feature"; then | |
| NEW_FEATURES="$NEW_FEATURES$FORMATTED_COMMIT"$'\n' | |
| elif echo "$COMMIT_MSG" | grep -qiE "^docs?:|documentation|readme|Update.*\.md"; then | |
| DOCUMENTATION="$DOCUMENTATION$FORMATTED_COMMIT"$'\n' | |
| elif echo "$COMMIT_MSG" | grep -qiE "^(fix|bugfix):|Fix "; then | |
| BUG_FIXES="$BUG_FIXES$FORMATTED_COMMIT"$'\n' | |
| else | |
| OTHER_CHANGES="$OTHER_CHANGES$FORMATTED_COMMIT"$'\n' | |
| fi | |
| done <<< "$COMMITS" | |
| # Build release notes | |
| RELEASE_NOTES="## What's Changed in $CURRENT_TAG"$'\n\n' | |
| if [[ -n "$BREAKING_CHANGES" ]]; then | |
| RELEASE_NOTES="$RELEASE_NOTES### ⚠️ Breaking changes"$'\n'"$BREAKING_CHANGES"$'\n' | |
| fi | |
| if [[ -n "$NEW_FEATURES" ]]; then | |
| RELEASE_NOTES="$RELEASE_NOTES### 🚀 New features"$'\n'"$NEW_FEATURES"$'\n' | |
| fi | |
| if [[ -n "$DOCUMENTATION" ]]; then | |
| RELEASE_NOTES="$RELEASE_NOTES### 📘 Documentation updates"$'\n'"$DOCUMENTATION"$'\n' | |
| fi | |
| if [[ -n "$BUG_FIXES" ]]; then | |
| RELEASE_NOTES="$RELEASE_NOTES### 🐛 Bug fixes"$'\n'"$BUG_FIXES"$'\n' | |
| fi | |
| if [[ -n "$OTHER_CHANGES" ]]; then | |
| RELEASE_NOTES="$RELEASE_NOTES### 🔧 Other Changes"$'\n'"$OTHER_CHANGES"$'\n' | |
| fi | |
| RELEASE_NOTES="$RELEASE_NOTES""**Full Changelog**: https://github.com/${{ github.repository }}/compare/${LATEST_TAG}...${CURRENT_TAG}"$'\n' | |
| # Save to output (properly escape for GitHub Actions) | |
| { | |
| echo "notes<<EOF" | |
| echo "$RELEASE_NOTES" | |
| echo "EOF" | |
| } >> $GITHUB_OUTPUT | |
| - name: Create draft release | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| run: | | |
| CURRENT_TAG="${{ needs.check-release-needed.outputs.current-tag }}" | |
| gh release create "$CURRENT_TAG" \ | |
| --title "$CURRENT_TAG" \ | |
| --notes "${{ steps.generate-notes.outputs.notes }}" \ | |
| --draft \ | |
| --latest | |
| echo "Draft release created successfully for $CURRENT_TAG" |