mirror of
https://github.com/jpawlowski/hass.tibber_prices.git
synced 2026-03-30 05:13:40 +00:00
Implemented automatic manifest.json synchronization and semantic versioning validation in the release workflow. Auto-Sync Manifest (sync-manifest job): - Extracts version from Git tag (v*.*.*) - Compares with manifest.json version - Auto-updates manifest.json if mismatch detected - Commits changes back to main branch - Sets outputs (updated, version) for downstream jobs - Prevents HACS version mismatches and conflicts with auto-tag.yml Version Check Warning System (version_check step): - Analyzes commits between tags for breaking changes, features, fixes - Applies semantic versioning rules (pre-1.0 and post-1.0) - Detects inappropriate version bumps: - Features with only PATCH bump → suggests MINOR - Breaking changes with only MINOR bump → suggests MAJOR (post-1.0) - Breaking changes with only PATCH bump → suggests MINOR (pre-1.0) - Shows warnings in GitHub Step Summary (prominent) - Appends warnings to release notes body - Provides fix instructions but doesn't fail workflow - Updates final summary with version check status Workflow changes: - release-notes job now depends on sync-manifest - Checks out main branch to get updated manifest if synced - Summary shows manifest sync status and version check result Impact: Prevents manual version tag issues, maintains manifest consistency, and warns about semantic versioning violations without blocking releases. Fully transparent workflow with clear guidance.
236 lines
9.7 KiB
YAML
236 lines
9.7 KiB
YAML
name: Generate Release Notes
|
|
|
|
on:
|
|
push:
|
|
tags:
|
|
- 'v*.*.*' # Triggers on version tags like v1.0.0, v2.1.3, etc.
|
|
|
|
permissions:
|
|
contents: write # Needed to create/update releases and push commits
|
|
|
|
jobs:
|
|
sync-manifest:
|
|
name: Sync manifest.json with tag version
|
|
runs-on: ubuntu-latest
|
|
outputs:
|
|
updated: ${{ steps.update.outputs.updated }}
|
|
version: ${{ steps.tag.outputs.version }}
|
|
steps:
|
|
- name: Checkout repository
|
|
uses: actions/checkout@v5
|
|
with:
|
|
fetch-depth: 0
|
|
token: ${{ secrets.GITHUB_TOKEN }}
|
|
|
|
- name: Extract version from tag
|
|
id: tag
|
|
run: |
|
|
TAG_VERSION="${GITHUB_REF#refs/tags/v}"
|
|
echo "version=$TAG_VERSION" >> $GITHUB_OUTPUT
|
|
echo "Tag version: v$TAG_VERSION"
|
|
|
|
- name: Check manifest.json version
|
|
id: manifest
|
|
run: |
|
|
MANIFEST_VERSION=$(grep -o '"version": "[^"]*"' custom_components/tibber_prices/manifest.json | cut -d'"' -f4)
|
|
echo "version=$MANIFEST_VERSION" >> $GITHUB_OUTPUT
|
|
echo "Manifest version: $MANIFEST_VERSION"
|
|
|
|
- name: Update manifest.json if needed
|
|
id: update
|
|
run: |
|
|
TAG_VERSION="${{ steps.tag.outputs.version }}"
|
|
MANIFEST_VERSION="${{ steps.manifest.outputs.version }}"
|
|
|
|
if [ "$TAG_VERSION" != "$MANIFEST_VERSION" ]; then
|
|
echo "::notice::Version mismatch detected - auto-syncing"
|
|
echo " Tag: v$TAG_VERSION"
|
|
echo " Manifest: $MANIFEST_VERSION"
|
|
|
|
# Update manifest.json
|
|
sed -i "s/\"version\": \".*\"/\"version\": \"$TAG_VERSION\"/" custom_components/tibber_prices/manifest.json
|
|
|
|
# Verify update
|
|
NEW_VERSION=$(grep -o '"version": "[^"]*"' custom_components/tibber_prices/manifest.json | cut -d'"' -f4)
|
|
if [ "$NEW_VERSION" = "$TAG_VERSION" ]; then
|
|
echo "✓ Successfully updated manifest.json to $TAG_VERSION"
|
|
echo "updated=true" >> $GITHUB_OUTPUT
|
|
else
|
|
echo "::error::Failed to update manifest.json"
|
|
exit 1
|
|
fi
|
|
else
|
|
echo "✓ Versions match - no update needed"
|
|
echo "updated=false" >> $GITHUB_OUTPUT
|
|
fi
|
|
|
|
- name: Commit and push manifest.json update
|
|
if: steps.update.outputs.updated == 'true'
|
|
run: |
|
|
git config user.name "github-actions[bot]"
|
|
git config user.email "github-actions[bot]@users.noreply.github.com"
|
|
|
|
git add custom_components/tibber_prices/manifest.json
|
|
git commit -m "chore(release): sync manifest.json with tag v${{ steps.tag.outputs.version }}"
|
|
|
|
# Push to main branch
|
|
git push origin HEAD:main
|
|
|
|
release-notes:
|
|
name: Generate and publish release notes
|
|
runs-on: ubuntu-latest
|
|
needs: sync-manifest # Wait for manifest sync to complete
|
|
steps:
|
|
- name: Checkout repository
|
|
uses: actions/checkout@v5
|
|
with:
|
|
fetch-depth: 0 # Fetch all history for git-cliff
|
|
ref: main # Use updated main branch if manifest was synced
|
|
|
|
- name: Get previous tag
|
|
id: previoustag
|
|
run: |
|
|
PREVIOUS_TAG=$(git describe --tags --abbrev=0 HEAD^ 2>/dev/null || echo "")
|
|
echo "previous_tag=${PREVIOUS_TAG}" >> $GITHUB_OUTPUT
|
|
echo "Previous tag: ${PREVIOUS_TAG}"
|
|
|
|
- name: Check version appropriateness
|
|
id: version_check
|
|
run: |
|
|
TAG_VERSION="${GITHUB_REF#refs/tags/v}"
|
|
PREV_TAG="${{ steps.previoustag.outputs.previous_tag }}"
|
|
|
|
if [ -z "$PREV_TAG" ]; then
|
|
echo "warning=" >> $GITHUB_OUTPUT
|
|
exit 0
|
|
fi
|
|
|
|
# Analyze commits between tags
|
|
COMMITS=$(git log ${PREV_TAG}..HEAD --format="%s" --no-merges)
|
|
BREAKING=$(echo "$COMMITS" | grep -cE "^[^:]+!:|^[^:]+: .+BREAKING CHANGE" || true)
|
|
FEAT=$(echo "$COMMITS" | grep -cE "^feat(\(.+\))?:" || true)
|
|
FIX=$(echo "$COMMITS" | grep -cE "^fix(\(.+\))?:" || true)
|
|
|
|
# Parse versions
|
|
PREV_VERSION="${PREV_TAG#v}"
|
|
IFS='.' read -r PREV_MAJOR PREV_MINOR PREV_PATCH <<< "$PREV_VERSION"
|
|
IFS='.' read -r MAJOR MINOR PATCH <<< "$TAG_VERSION"
|
|
|
|
WARNING=""
|
|
SUGGESTION=""
|
|
|
|
# Pre-1.0 version rules (0.x.y)
|
|
if [ "$MAJOR" -eq 0 ]; then
|
|
if [ $BREAKING -gt 0 ] && [ "$MINOR" = "$PREV_MINOR" ]; then
|
|
WARNING="⚠️ **Version Warning**: $BREAKING breaking change(s) detected, but only PATCH version bumped."
|
|
SUGGESTION="In pre-1.0 (0.x.y), breaking changes should bump MINOR version. Consider **v0.$((MINOR + 1)).0** instead of v$TAG_VERSION"
|
|
elif [ $FEAT -gt 0 ] && [ "$MINOR" = "$PREV_MINOR" ] && [ "$PATCH" != "$PREV_PATCH" ]; then
|
|
WARNING="⚠️ **Version Warning**: $FEAT new feature(s) detected, but only PATCH version bumped."
|
|
SUGGESTION="New features should bump MINOR version. Consider **v0.$((MINOR + 1)).0** instead of v$TAG_VERSION"
|
|
fi
|
|
else
|
|
# Post-1.0 version rules (x.y.z)
|
|
if [ $BREAKING -gt 0 ] && [ "$MAJOR" = "$PREV_MAJOR" ]; then
|
|
WARNING="⚠️ **Version Warning**: $BREAKING breaking change(s) detected, but MAJOR version not bumped."
|
|
SUGGESTION="Breaking changes require MAJOR version bump. Consider **v$((MAJOR + 1)).0.0** instead of v$TAG_VERSION"
|
|
elif [ $FEAT -gt 0 ] && [ "$MINOR" = "$PREV_MINOR" ] && [ "$PATCH" != "$PREV_PATCH" ]; then
|
|
WARNING="⚠️ **Version Warning**: $FEAT new feature(s) detected, but only PATCH version bumped."
|
|
SUGGESTION="New features should bump MINOR version. Consider **v$MAJOR.$((MINOR + 1)).0** instead of v$TAG_VERSION"
|
|
fi
|
|
fi
|
|
|
|
# Output warning message
|
|
if [ -n "$WARNING" ]; then
|
|
echo "$WARNING"
|
|
echo "$SUGGESTION"
|
|
echo ""
|
|
echo "Commits analyzed: Breaking=$BREAKING, Features=$FEAT, Fixes=$FIX"
|
|
|
|
# Set output for later steps (using heredoc for multi-line)
|
|
{
|
|
echo "warning<<EOF"
|
|
echo "$WARNING"
|
|
echo ""
|
|
echo "$SUGGESTION"
|
|
echo ""
|
|
echo "**Commits analyzed:** Breaking=$BREAKING, Features=$FEAT, Fixes=$FIX"
|
|
echo ""
|
|
echo "**To fix:**"
|
|
echo "1. Delete the tag: \`git tag -d v$TAG_VERSION && git push origin :refs/tags/v$TAG_VERSION\`"
|
|
echo "2. Run locally: \`./scripts/suggest-version\`"
|
|
echo "3. Create correct tag: \`./scripts/prepare-release X.Y.Z\`"
|
|
echo "EOF"
|
|
} >> $GITHUB_OUTPUT
|
|
else
|
|
echo "✓ Version bump looks appropriate for the changes"
|
|
echo "warning=" >> $GITHUB_OUTPUT
|
|
fi
|
|
|
|
- name: Install git-cliff
|
|
run: |
|
|
wget https://github.com/orhun/git-cliff/releases/download/v2.4.0/git-cliff-2.4.0-x86_64-unknown-linux-gnu.tar.gz
|
|
tar -xzf git-cliff-2.4.0-x86_64-unknown-linux-gnu.tar.gz
|
|
sudo mv git-cliff-2.4.0/git-cliff /usr/local/bin/
|
|
git-cliff --version
|
|
|
|
- name: Generate release notes
|
|
id: release_notes
|
|
run: |
|
|
FROM_TAG="${{ steps.previoustag.outputs.previous_tag }}"
|
|
TO_TAG="${GITHUB_REF#refs/tags/}"
|
|
|
|
echo "Generating release notes from ${FROM_TAG} to ${TO_TAG}"
|
|
|
|
# Use our script with git-cliff backend (AI disabled in CI)
|
|
# git-cliff will handle filtering via cliff.toml
|
|
USE_AI=false ./scripts/generate-release-notes "${FROM_TAG}" "${TO_TAG}" > release-notes.md
|
|
|
|
# Append version warning if present
|
|
WARNING="${{ steps.version_check.outputs.warning }}"
|
|
if [ -n "$WARNING" ]; then
|
|
echo "" >> release-notes.md
|
|
echo "---" >> release-notes.md
|
|
echo "" >> release-notes.md
|
|
echo "$WARNING" >> release-notes.md
|
|
fi
|
|
|
|
# Output for GitHub Actions
|
|
{
|
|
echo 'notes<<EOF'
|
|
cat release-notes.md
|
|
echo EOF
|
|
} >> $GITHUB_OUTPUT
|
|
|
|
- name: Version Check Summary
|
|
if: steps.version_check.outputs.warning != ''
|
|
run: |
|
|
echo "### ⚠️ Version Mismatch Detected" >> $GITHUB_STEP_SUMMARY
|
|
echo "" >> $GITHUB_STEP_SUMMARY
|
|
echo "${{ steps.version_check.outputs.warning }}" >> $GITHUB_STEP_SUMMARY
|
|
|
|
- name: Create GitHub Release
|
|
uses: softprops/action-gh-release@v2
|
|
with:
|
|
body: ${{ steps.release_notes.outputs.notes }}
|
|
draft: false
|
|
prerelease: false
|
|
generate_release_notes: false # We provide our own
|
|
env:
|
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
|
|
- name: Summary
|
|
run: |
|
|
echo "✅ Release notes generated and published!" >> $GITHUB_STEP_SUMMARY
|
|
echo "" >> $GITHUB_STEP_SUMMARY
|
|
echo "**Tag:** ${GITHUB_REF#refs/tags/}" >> $GITHUB_STEP_SUMMARY
|
|
echo "**Previous tag:** ${{ steps.previoustag.outputs.previous_tag }}" >> $GITHUB_STEP_SUMMARY
|
|
if [[ "${{ needs.sync-manifest.outputs.updated }}" == "true" ]]; then
|
|
echo "**Manifest sync:** Updated manifest.json to version ${{ needs.sync-manifest.outputs.version }}" >> $GITHUB_STEP_SUMMARY
|
|
else
|
|
echo "**Manifest sync:** No update needed (version already matches)" >> $GITHUB_STEP_SUMMARY
|
|
fi
|
|
if [ -n "${{ steps.version_check.outputs.warning }}" ]; then
|
|
echo "**Version check:** ⚠️ Warning detected (see release notes)" >> $GITHUB_STEP_SUMMARY
|
|
else
|
|
echo "**Version check:** ✓ Version appropriate for changes" >> $GITHUB_STEP_SUMMARY
|
|
fi
|