Dashboard enhancement #205
This file contains 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: Versioning and Release Management | |
# Add workflow-level permissions | |
permissions: | |
contents: read # Base read permission for all jobs | |
pull-requests: write # Needed for creating PRs | |
issues: write # Needed for commenting on PRs | |
on: | |
push: | |
branches: [main, develop] | |
pull_request: | |
branches: [main, develop] | |
workflow_dispatch: | |
inputs: | |
version_type: | |
description: 'Version type (major, minor, patch)' | |
required: true | |
default: 'patch' | |
type: choice | |
options: | |
- major | |
- minor | |
- patch | |
force_version: | |
description: 'Force specific version (leave empty to auto-increment)' | |
required: false | |
type: string | |
skip_version_check: | |
description: 'Skip version consistency check' | |
required: false | |
default: false | |
type: boolean | |
jobs: | |
version-check: | |
runs-on: ubuntu-latest | |
permissions: | |
contents: read | |
# Skip this job if skip_version_check is true | |
if: ${{ github.event.inputs.skip_version_check != 'true' }} | |
steps: | |
- name: Checkout code | |
uses: actions/checkout@v4 | |
with: | |
fetch-depth: 0 | |
- name: Check version consistency | |
run: | | |
# Extract versions | |
CHANGELOG_VERSION=$(grep -o '\[[0-9]\+\.[0-9]\+\.[0-9]\+\]' CHANGELOG.md | head -1 | tr -d '[]') | |
README_VERSION=$(grep -o 'version-[0-9.]*-blue' README.md | cut -d'-' -f2) | |
echo "Found versions:" | |
echo "CHANGELOG.md: $CHANGELOG_VERSION" | |
echo "README.md: $README_VERSION" | |
# Check if versions are valid semver | |
if [[ ! $CHANGELOG_VERSION =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then | |
echo "❌ CHANGELOG.md version is not a valid semver: $CHANGELOG_VERSION" | |
exit 1 | |
fi | |
if [[ ! $README_VERSION =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then | |
echo "❌ README.md version is not a valid semver: $README_VERSION" | |
exit 1 | |
fi | |
# Compare major versions - allow different versions if major version is different | |
CHANGELOG_MAJOR=$(echo $CHANGELOG_VERSION | cut -d. -f1) | |
README_MAJOR=$(echo $README_VERSION | cut -d. -f1) | |
# Compare versions | |
if [ "$CHANGELOG_VERSION" != "$README_VERSION" ]; then | |
# If major versions are different, this might be an intentional version jump | |
if [ "$CHANGELOG_MAJOR" != "$README_MAJOR" ]; then | |
echo "⚠️ Major version difference detected ($CHANGELOG_VERSION vs $README_VERSION)" | |
echo "This may be an intentional version jump. Proceeding with caution." | |
# Check if README version is in CHANGELOG.md at all | |
if grep -q "\[$README_VERSION\]" CHANGELOG.md; then | |
echo "✅ README version $README_VERSION found in CHANGELOG.md" | |
exit 0 | |
else | |
echo "⚠️ README version $README_VERSION not found in CHANGELOG.md" | |
echo "This might be a mistake. Please ensure the version exists in CHANGELOG.md" | |
exit 1 | |
fi | |
else | |
echo "❌ Version mismatch found!" | |
echo "All versions must match CHANGELOG.md version: $CHANGELOG_VERSION" | |
exit 1 | |
fi | |
fi | |
echo "✅ All versions match: $CHANGELOG_VERSION" | |
- name: Verify changelog | |
run: | | |
if ! grep -q "## \[Unreleased\]" CHANGELOG.md; then | |
echo "❌ Error: CHANGELOG.md must contain an [Unreleased] section" | |
exit 1 | |
fi | |
echo "✅ CHANGELOG.md format verified" | |
version-bump: | |
needs: version-check | |
if: github.event_name == 'workflow_dispatch' | |
runs-on: ubuntu-latest | |
permissions: | |
contents: write | |
pull-requests: write | |
outputs: | |
new_version: ${{ steps.bump_version.outputs.new_version }} | |
steps: | |
- name: Checkout code | |
uses: actions/checkout@v4 | |
with: | |
fetch-depth: 0 | |
- name: Configure Git | |
run: | | |
git config --local user.email "github-actions[bot]@users.noreply.github.com" | |
git config --local user.name "github-actions[bot]" | |
- name: Update version | |
id: bump_version | |
run: | | |
VERSION_TYPE=${{ github.event.inputs.version_type }} | |
FORCE_VERSION="${{ github.event.inputs.force_version }}" | |
# Get current version from CHANGELOG.md | |
CURRENT_VERSION=$(grep -o '\[[0-9]\+\.[0-9]\+\.[0-9]\+\]' CHANGELOG.md | head -1 | tr -d '[]') | |
echo "Current version: $CURRENT_VERSION" | |
# Use forced version if provided | |
if [ -n "$FORCE_VERSION" ]; then | |
# Validate forced version is semver | |
if [[ ! $FORCE_VERSION =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then | |
echo "❌ Forced version is not a valid semver: $FORCE_VERSION" | |
exit 1 | |
fi | |
NEW_VERSION="$FORCE_VERSION" | |
echo "Using forced version: $NEW_VERSION" | |
else | |
# Calculate new version | |
IFS='.' read -r -a version_parts <<< "$CURRENT_VERSION" | |
major="${version_parts[0]}" | |
minor="${version_parts[1]}" | |
patch="${version_parts[2]}" | |
case $VERSION_TYPE in | |
major) | |
major=$((major + 1)) | |
minor=0 | |
patch=0 | |
;; | |
minor) | |
minor=$((minor + 1)) | |
patch=0 | |
;; | |
patch) | |
patch=$((patch + 1)) | |
;; | |
esac | |
NEW_VERSION="$major.$minor.$patch" | |
echo "Calculated new version: $NEW_VERSION" | |
fi | |
echo "new_version=${NEW_VERSION}" >> $GITHUB_OUTPUT | |
# Update README.md version badge | |
sed -i "s/version-[0-9.]*-blue/version-${NEW_VERSION}-blue/" README.md | |
# Update CHANGELOG.md | |
DATE=$(date +%Y-%m-%d) | |
sed -i "s/## \[Unreleased\]/## [Unreleased]\n\n## [$NEW_VERSION] - $DATE/" CHANGELOG.md | |
# Update version links in CHANGELOG.md | |
# First, check if we already have a link for the new version | |
if ! grep -q "\[$NEW_VERSION\]:" CHANGELOG.md; then | |
# Add new version link | |
if grep -q "\[Unreleased\]:" CHANGELOG.md; then | |
# Update existing links | |
sed -i "/\[Unreleased\]:/c\[Unreleased\]: https://github.com/${{ github.repository }}/compare/v$NEW_VERSION...HEAD" CHANGELOG.md | |
# Find the previous version link | |
PREV_VERSION_LINE=$(grep -n "\[[0-9]\+\.[0-9]\+\.[0-9]\+\]:" CHANGELOG.md | head -1) | |
PREV_VERSION_NUM=$(echo $PREV_VERSION_LINE | cut -d: -f1) | |
PREV_VERSION=$(echo $PREV_VERSION_LINE | grep -o "\[[0-9]\+\.[0-9]\+\.[0-9]\+\]:" | tr -d '[]' | tr -d ':') | |
# Insert new version link after Unreleased link | |
sed -i "/\[Unreleased\]:/a\[$NEW_VERSION\]: https://github.com/${{ github.repository }}/compare/v$PREV_VERSION...v$NEW_VERSION" CHANGELOG.md | |
else | |
# Add links if they don't exist | |
echo "" >> CHANGELOG.md | |
echo "[Unreleased]: https://github.com/${{ github.repository }}/compare/v$NEW_VERSION...HEAD" >> CHANGELOG.md | |
echo "[$NEW_VERSION]: https://github.com/${{ github.repository }}/releases/tag/v$NEW_VERSION" >> CHANGELOG.md | |
fi | |
fi | |
- name: Create Pull Request | |
uses: peter-evans/create-pull-request@v5 | |
with: | |
title: '🔖 chore(release): prepare release ${{ steps.bump_version.outputs.new_version }}' | |
body: | | |
# 🚀 Release Preparation v${{ steps.bump_version.outputs.new_version }} | |
## 📝 Changes | |
- Version bump in CHANGELOG.md | |
- Updated version badge in README.md | |
- Updated version links | |
## ✅ Checklist | |
- [ ] Review version numbers | |
- [ ] Review CHANGELOG.md | |
- [ ] Review documentation updates | |
Please review the changes and merge if everything looks correct. | |
branch: release/v${{ steps.bump_version.outputs.new_version }} | |
base: main | |
labels: release | |
commit-message: 'chore(release): prepare release ${{ steps.bump_version.outputs.new_version }}' | |
create-release: | |
needs: version-bump | |
if: github.event_name == 'push' && github.ref == 'refs/heads/main' | |
runs-on: ubuntu-latest | |
permissions: | |
contents: write | |
steps: | |
- name: Create Release | |
uses: actions/create-release@v1 | |
env: | |
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
with: | |
tag_name: v${{ needs.version-bump.outputs.new_version }} | |
release_name: Release v${{ needs.version-bump.outputs.new_version }} | |
body: | | |
See [CHANGELOG.md](CHANGELOG.md) for details. | |
draft: false | |
prerelease: false |