mirror of
https://github.com/jpawlowski/hass.tibber_prices.git
synced 2026-03-29 21:03:40 +00:00
feat(ci): add manifest sync and version validation to release workflow
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.
This commit is contained in:
parent
ddc718aabd
commit
d7a145d678
1 changed files with 171 additions and 2 deletions
173
.github/workflows/release.yml
vendored
173
.github/workflows/release.yml
vendored
|
|
@ -6,17 +6,86 @@ on:
|
|||
- 'v*.*.*' # Triggers on version tags like v1.0.0, v2.1.3, etc.
|
||||
|
||||
permissions:
|
||||
contents: write # Needed to create/update releases
|
||||
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
|
||||
|
|
@ -25,6 +94,78 @@ jobs:
|
|||
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
|
||||
|
|
@ -44,12 +185,30 @@ jobs:
|
|||
# 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: Create GitHub Release
|
||||
} >> $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 }}
|
||||
|
|
@ -65,3 +224,13 @@ jobs:
|
|||
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
|
||||
|
|
|
|||
Loading…
Reference in a new issue