Skip to content

Release v0.2.1

Release v0.2.1 #15

Workflow file for this run

name: Changelog Sync
on:
release:
types: [published, edited]
workflow_dispatch:
inputs:
sync_all:
description: 'Sync all releases to changelog'
required: false
type: boolean
default: false
concurrency:
group: changelog-sync-${{ github.ref || 'workflow-dispatch' }}
cancel-in-progress: false
permissions:
contents: write
pull-requests: write
jobs:
sync-changelog:
name: Sync Changelog with Releases
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955
with:
token: ${{ secrets.GITHUB_TOKEN }}
fetch-depth: 0
- name: Setup Git
run: |
git config --local user.email "41898282+github-actions[bot]@users.noreply.github.com"
git config --local user.name "github-actions[bot]"
- name: Sync single release
if: github.event_name == 'release'
run: |
TAG_NAME="${{ github.event.release.tag_name }}"
RELEASE_NAME="${{ github.event.release.name }}"
RELEASE_BODY="${{ github.event.release.body }}"
RELEASE_DATE=$(date -u +"%Y-%m-%d")
VERSION=${TAG_NAME#v}
echo "Syncing release $TAG_NAME to changelog..."
# Check if this version already exists in changelog
if grep -q "## \[$VERSION\]" CHANGELOG.md; then
echo "Version $VERSION already exists in changelog, updating..."
# Extract the current entry and replace it
python3 << 'EOF'
import re
import sys
tag_name = "$TAG_NAME"
version = "$VERSION"
release_date = "$RELEASE_DATE"
release_body = """$RELEASE_BODY"""
# Read current changelog
with open('CHANGELOG.md', 'r') as f:
content = f.read()
# Parse release body to extract sections
sections = {}
current_section = None
lines = release_body.split('\n')
for line in lines:
line = line.strip()
if line.startswith('### '):
# Extract section name (remove emoji and ###)
section_match = re.match(r'### [^A-Za-z]*([A-Za-z][^$]*)', line)
if section_match:
current_section = section_match.group(1).strip()
sections[current_section] = []
elif line.startswith('- ') and current_section:
sections[current_section].append(line)
# Create changelog entry
changelog_entry = f"## [{version}] - {release_date}\n\n"
# Map sections to changelog format
section_mapping = {
'Added': 'Added',
'Fixed': 'Fixed',
'Changed': 'Changed',
'Performance': 'Performance',
'Documentation': 'Documentation',
'Style': 'Style',
'Refactor': 'Refactor',
'Tests': 'Tests',
'Maintenance': 'Maintenance',
'Breaking Changes': 'Breaking Changes'
}
for section_name, changelog_section in section_mapping.items():
if section_name in sections and sections[section_name]:
changelog_entry += f"### {changelog_section}\n"
for item in sections[section_name]:
changelog_entry += f"{item}\n"
changelog_entry += "\n"
# Extract '### 📝 Commit Summary' section content and append as '### Commits'
commit_summary_content = []
in_commit_summary = False
for line in lines:
stripped = line.strip()
if stripped.startswith('### ') and 'Commit Summary' in stripped:
in_commit_summary = True
continue
elif stripped.startswith('### ') and in_commit_summary:
break
elif in_commit_summary and stripped:
commit_summary_content.append(line)
if commit_summary_content:
changelog_entry += "### Commits\n"
changelog_entry += "\n".join(commit_summary_content) + "\n\n"
# Find and replace the existing entry or add new one
version_pattern = rf"## \[{re.escape(version)}\]..*?(?=## \[|\Z)"
if re.search(version_pattern, content, re.DOTALL):
# Replace existing entry
content = re.sub(version_pattern, changelog_entry.rstrip() + "\n\n", content, flags=re.DOTALL)
else:
# Add new entry after [Unreleased]
unreleased_pattern = r"(## \[Unreleased\].*?\n\n)"
if re.search(unreleased_pattern, content, re.DOTALL):
content = re.sub(unreleased_pattern, r"\1" + changelog_entry, content, flags=re.DOTALL)
else:
# Insert after the header
header_end = content.find('\n## ')
if header_end != -1:
content = content[:header_end] + "\n\n" + changelog_entry + content[header_end:]
# Write updated changelog
with open('CHANGELOG.md', 'w') as f:
f.write(content)
print(f"Updated changelog for version {version}")
EOF
else
echo "Adding new version $VERSION to changelog..."
# Add new entry after [Unreleased] section
python3 << 'EOF'
import re
tag_name = "$TAG_NAME"
version = "$VERSION"
release_date = "$RELEASE_DATE"
release_body = """$RELEASE_BODY"""
# Read current changelog
with open('CHANGELOG.md', 'r') as f:
content = f.read()
# Create new changelog entry (similar logic as above)
changelog_entry = f"## [{version}] - {release_date}\n\n### Added\n- Release {version}\n\n"
# Insert after [Unreleased]
unreleased_pattern = r"(## \[Unreleased\].*?\n\n)"
if re.search(unreleased_pattern, content, re.DOTALL):
content = re.sub(unreleased_pattern, r"\1" + changelog_entry, content, flags=re.DOTALL)
else:
# Insert at the beginning of versions
header_end = content.find('\n## [')
if header_end != -1:
content = content[:header_end] + "\n\n" + changelog_entry + content[header_end:]
with open('CHANGELOG.md', 'w') as f:
f.write(content)
print(f"Added changelog entry for version {version}")
EOF
fi
- name: Sync all releases
if: github.event_name == 'workflow_dispatch' && github.event.inputs.sync_all == 'true'
run: |
echo "Syncing all releases to changelog..."
# Get all releases
gh release list --limit 50 --json tagName,name,body,publishedAt | jq -r '.[] | "\(.tagName)|\(.publishedAt)|\(.body)"' > releases.txt
# Process each release
while IFS='|' read -r tag_name published_at body; do
if [[ "$tag_name" =~ ^v[0-9]+\.[0-9]+\.[0-9]+.*$ ]]; then
version=${tag_name#v}
release_date=$(date -d "$published_at" +"%Y-%m-%d" 2>/dev/null || date -u +"%Y-%m-%d")
echo "Processing release $tag_name..."
# Check if version exists in changelog
if ! grep -q "## \[$version\]" CHANGELOG.md; then
echo "Adding $version to changelog..."
# Add basic entry (detailed sync will happen on next release event)
python3 << 'EOF'
import re
version = "$version"
release_date = "$release_date"
with open('CHANGELOG.md', 'r') as f:
content = f.read()
changelog_entry = f"## [{version}] - {release_date}\n\n### Changed\n- Release {version}\n\n"
# Insert in chronological order
lines = content.split('\n')
new_lines = []
inserted = False
for line in lines:
if line.startswith('## [') and not inserted and not line.startswith('## [Unreleased]'):
# Check if we should insert before this version
match = re.match(r'## \[([^\]]+)\]', line)
if match:
existing_version = match.group(1)
# Simple version comparison (may need improvement for complex versions)
if version > existing_version:
new_lines.extend(changelog_entry.split('\n'))
inserted = True
new_lines.append(line)
if not inserted:
# Add at the end before any existing versions
for i, line in enumerate(new_lines):
if line.startswith('## [') and not line.startswith('## [Unreleased]'):
new_lines.insert(i, '')
new_lines.insert(i, changelog_entry.strip())
break
with open('CHANGELOG.md', 'w') as f:
f.write('\n'.join(new_lines))
EOF
fi
fi
done < releases.txt
rm -f releases.txt
- name: Commit changes
run: |
if ! git diff --quiet CHANGELOG.md; then
git add CHANGELOG.md
if [ "${{ github.event_name }}" = "release" ]; then
git commit -m "docs: sync changelog with release ${{ github.event.release.tag_name }} [skip ci]"
else
git commit -m "docs: sync changelog with all releases [skip ci]"
fi
git push
echo "✅ Changelog synchronized with releases!"
else
echo "ℹ️ No changes needed in changelog"
fi
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
update-release-descriptions:
name: Update Release Descriptions
runs-on: ubuntu-latest
needs: sync-changelog
if: github.event_name == 'workflow_dispatch' && github.event.inputs.sync_all == 'true'
steps:
- name: Checkout code
uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955
- name: Update all release descriptions
run: |
echo "Updating all release descriptions with enhanced format..."
# Get releases that might need updating
gh release list --limit 20 --json tagName,body | jq -r '.[] | select(.body | length < 500 or (contains("### 📦 Assets") | not)) | .tagName' > releases_to_update.txt
while read -r tag_name; do
if [[ "$tag_name" =~ ^v[0-9]+\.[0-9]+\.[0-9]+.*$ ]]; then
echo "Triggering enhanced release workflow for $tag_name..."
# Trigger the enhanced-release workflow
gh workflow run enhanced-release.yml -f tag="$tag_name"
# Wait a bit to avoid rate limiting
sleep 5
fi
done < releases_to_update.txt
rm -f releases_to_update.txt
echo "✅ Triggered enhanced release updates for outdated releases"
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}