Skip to content

chore: release v4.7.2 (#149) #10

chore: release v4.7.2 (#149)

chore: release v4.7.2 (#149) #10

Workflow file for this run

name: Release
# Publishes a GitHub Release when a v* tag is pushed (HACS reads GitHub
# releases). Every release is published as a PRE-RELEASE (and off "latest") so a
# new version is never served to the default / HACS channel before it has been
# tested — promote it to a full release later (step 4).
#
# Release flow:
# 1. bin/release.sh <version> -> opens the chore/release PR (bumps manifest)
# 2. merge the PR
# 3. git tag v<version> && git push <remote> v<version> -> triggers this workflow
# 4. test the pre-release, then promote it to the latest full release:
# gh release edit v<version> --prerelease=false --latest=true
# 5. roll main forward to the next minor for development:
# bin/bump-dev.sh (opens a PR; merge it)
#
# This workflow does NOT bump main itself. main is protected (PR-only + required
# checks), so a direct push from the workflow is always rejected — the dev-cycle
# bump is done as a normal PR via bin/bump-dev.sh (step 5) instead.
on:
push:
tags: ['v*']
permissions:
contents: write
jobs:
publish:
runs-on: ubuntu-latest
name: Publish GitHub Release
steps:
- uses: actions/checkout@v5
- name: Extract and validate version from tag
id: version
env:
REF: ${{ github.ref }}
run: |
VERSION="${REF#refs/tags/v}"
# Reject off-spec tags (the same semver contract bin/release.sh
# enforces), so a hand-pushed bad tag can't slip through.
bin/bump-version.sh --validate "$VERSION"
echo "version=$VERSION" >> "$GITHUB_OUTPUT"
# Whether the tag itself is a semver pre-release (-alpha/-beta/-rc).
# The GitHub Release is always published as a pre-release regardless
# (see below); this output only gates whether a missing CHANGELOG
# section is fatal (a -alpha/-beta/-rc tag may legitimately have none).
if [[ "$VERSION" == *-* ]]; then
echo "prerelease=true" >> "$GITHUB_OUTPUT"
else
echo "prerelease=false" >> "$GITHUB_OUTPUT"
fi
- name: Validate manifest version matches tag
env:
VERSION: ${{ steps.version.outputs.version }}
run: |
MANIFEST_VER=$(python3 -c "import json; print(json.load(open('custom_components/cover_time_based/manifest.json'))['version'])")
if [ "$VERSION" != "$MANIFEST_VER" ]; then
echo "::error::Tag v$VERSION does not match manifest.json version $MANIFEST_VER"
exit 1
fi
- name: Build release notes from CHANGELOG
id: notes
env:
VERSION: ${{ steps.version.outputs.version }}
PRERELEASE: ${{ steps.version.outputs.prerelease }}
run: |
# Use the hand-written, user-facing CHANGELOG section as the release
# notes. changelog-section.sh exits 0 (found), 1 (no section for this
# version), or >=2 (its own error, e.g. CHANGELOG.md missing):
# - found -> use the section as the release body
# - exit 1, pre-release -> auto-generated notes (-alpha/-beta/-rc may
# legitimately have no entry yet)
# - exit 1, final tag -> fail: a shipped release must have notes
# (matches the repo's block-on-drift posture)
# - exit >=2 -> a real error; fail regardless of tag
rc=0
bin/changelog-section.sh "$VERSION" > release-notes.md || rc=$?
if [ "$rc" -eq 0 ]; then
echo "found=true" >> "$GITHUB_OUTPUT"
elif [ "$rc" -eq 1 ] && [ "$PRERELEASE" = "true" ]; then
echo "No CHANGELOG.md section for pre-release $VERSION; using auto-generated notes."
echo "found=false" >> "$GITHUB_OUTPUT"
elif [ "$rc" -eq 1 ]; then
echo "::error::No CHANGELOG.md section for final release $VERSION — add the entry before tagging."
exit 1
else
echo "::error::changelog-section.sh failed (exit $rc) for $VERSION — see its message above."
exit "$rc"
fi
- name: Create GitHub Release
uses: softprops/action-gh-release@v3
with:
# The CHANGELOG section when present, otherwise GitHub's auto-generated
# notes (see the previous step).
body_path: ${{ steps.notes.outputs.found == 'true' && 'release-notes.md' || '' }}
generate_release_notes: ${{ steps.notes.outputs.found != 'true' }}
# Every release is created as a pre-release and off "latest", so a new
# version is never pushed straight to users on the default / HACS
# channel. Test it, then promote to the full latest release with:
# gh release edit v<version> --prerelease=false --latest=true
prerelease: true
make_latest: false