Skip to content

Fix release workflow to checkout main branch to prevent push conflicts #6

Fix release workflow to checkout main branch to prevent push conflicts

Fix release workflow to checkout main branch to prevent push conflicts #6

name: Update CHANGELOG
on:
push:
branches:
- main
paths-ignore:
- 'CHANGELOG.md' # Don't trigger on CHANGELOG-only changes
permissions:
contents: write
jobs:
update-changelog:
name: Update CHANGELOG from commits
runs-on: ubuntu-latest
# Skip if commit message contains [skip ci] or is from github-actions bot
if: |
!contains(github.event.head_commit.message, '[skip ci]') &&
github.event.head_commit.author.name != 'github-actions[bot]'
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 0 # Full history needed
token: ${{ secrets.GITHUB_TOKEN }}
- name: Extract commits since last release
id: commits
run: |
# Find last version tag
PREV_TAG=$(git describe --tags --abbrev=0 --match "v[0-9]*" 2>/dev/null || echo "")
if [ -z "$PREV_TAG" ]; then
# No previous release, get all commits
COMMITS=$(git log --pretty=format:"%s" --no-merges)
else
# Get commits since last release
COMMITS=$(git log ${PREV_TAG}..HEAD --pretty=format:"%s" --no-merges)
fi
# Categorize commits
FIXED=""
ADDED=""
CHANGED=""
while IFS= read -r commit; do
# Skip empty lines and bot commits
[ -z "$commit" ] && continue
echo "$commit" | grep -q "skip ci" && continue
echo "$commit" | grep -q "Bump version" && continue
# Categorize by conventional commit prefix or keywords
if echo "$commit" | grep -qiE "^(fix|fixed|bugfix)"; then
FIXED="${FIXED}- ${commit#*: }\n"
elif echo "$commit" | grep -qiE "^(feat|add|added)"; then
ADDED="${ADDED}- ${commit#*: }\n"
elif echo "$commit" | grep -qiE "^(change|changed|update|refactor)"; then
CHANGED="${CHANGED}- ${commit#*: }\n"
else
# Default to Changed for uncategorized
CHANGED="${CHANGED}- ${commit}\n"
fi
done <<< "$COMMITS"
# Save to output
{
echo "fixed<<EOF"
echo -e "$FIXED"
echo "EOF"
echo "added<<EOF"
echo -e "$ADDED"
echo "EOF"
echo "changed<<EOF"
echo -e "$CHANGED"
echo "EOF"
} >> $GITHUB_OUTPUT
- name: Update CHANGELOG.md
run: |
# Check if there are any changes to add
if [ -z "${{ steps.commits.outputs.fixed }}${{ steps.commits.outputs.added }}${{ steps.commits.outputs.changed }}" ]; then
echo "No new commits to add to CHANGELOG"
exit 0
fi
# Create temporary file with new unreleased section
echo "## [Unreleased]" > /tmp/unreleased.txt
echo "" >> /tmp/unreleased.txt
# Add Fixed section if not empty
if [ -n "${{ steps.commits.outputs.fixed }}" ]; then
echo "### Fixed" >> /tmp/unreleased.txt
echo "${{ steps.commits.outputs.fixed }}" >> /tmp/unreleased.txt
fi
# Add Added section if not empty
if [ -n "${{ steps.commits.outputs.added }}" ]; then
echo "### Added" >> /tmp/unreleased.txt
echo "${{ steps.commits.outputs.added }}" >> /tmp/unreleased.txt
fi
# Add Changed section if not empty
if [ -n "${{ steps.commits.outputs.changed }}" ]; then
echo "### Changed" >> /tmp/unreleased.txt
echo "${{ steps.commits.outputs.changed }}" >> /tmp/unreleased.txt
fi
# Replace [Unreleased] section in CHANGELOG
# Find line number of [Unreleased]
UNRELEASED_LINE=$(grep -n "## \[Unreleased\]" CHANGELOG.md | cut -d: -f1 | head -1)
if [ -n "$UNRELEASED_LINE" ]; then
# Find next ## line (start of previous version)
NEXT_VERSION_LINE=$(tail -n +$((UNRELEASED_LINE + 1)) CHANGELOG.md | grep -n "^## \[" | head -1 | cut -d: -f1)
if [ -n "$NEXT_VERSION_LINE" ]; then
# Calculate absolute line number
NEXT_VERSION_LINE=$((UNRELEASED_LINE + NEXT_VERSION_LINE))
# Build new CHANGELOG
head -n $((UNRELEASED_LINE - 1)) CHANGELOG.md > /tmp/changelog_new.md
cat /tmp/unreleased.txt >> /tmp/changelog_new.md
tail -n +$NEXT_VERSION_LINE CHANGELOG.md >> /tmp/changelog_new.md
mv /tmp/changelog_new.md CHANGELOG.md
fi
fi
- name: Commit CHANGELOG changes
run: |
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
# Check if there are changes
if git diff --quiet CHANGELOG.md; then
echo "No changes to CHANGELOG.md"
exit 0
fi
git add CHANGELOG.md
git commit -m "Update CHANGELOG from recent commits [skip ci]"
git push origin main