hass.tibber_prices/scripts/prepare-release
Julian Pawlowski e08fd60070 feat(release): add automated release notes generation system
Implemented multi-backend release notes generation:

**Scripts:**
- prepare-release: Bump manifest.json + create tag (foolproof workflow)
- generate-release-notes: Parse conventional commits with 3 backends
  * GitHub Copilot CLI (AI-powered, smart grouping)
  * git-cliff (template-based, fast and reliable)
  * Manual grep/awk (fallback, always works)
- setup: Auto-install git-cliff via cargo in DevContainer

**GitHub Actions:**
- auto-tag.yml: Automatically create tag on manifest.json version bump
- release.yml: Generate release notes and create GitHub release on tag push
- release.yml: Button config for GitHub UI release notes generator

**Configuration:**
- cliff.toml: Smart filtering rules
  * Excludes: manifest bumps, dev-env changes, CI/CD changes
  * Includes: Dependency updates (relevant for users)
  * Groups by conventional commit type with emoji

**Workflow:**
1. Run `./scripts/prepare-release 0.3.0`
2. Push commit + tag: `git push origin main v0.3.0`
3. CI/CD automatically generates release notes and creates GitHub release

Impact: Maintainers can prepare professional releases with one command.
Release notes are automatically generated from conventional commits with
intelligent filtering and categorization.
2025-11-09 14:25:15 +00:00

146 lines
4.7 KiB
Bash
Executable file

#!/usr/bin/env bash
# script/prepare-release: Prepare a new release by bumping version and creating tag
#
# This script:
# 1. Validates the version format (X.Y.Z)
# 2. Updates custom_components/tibber_prices/manifest.json
# 3. Commits the change with conventional commit format
# 4. Creates an annotated git tag
# 5. Shows you what will be pushed (you decide when to push)
#
# Usage:
# ./scripts/prepare-release VERSION
# ./scripts/prepare-release 0.3.0
# ./scripts/prepare-release 1.0.0
set -euo pipefail
# Colors
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color
cd "$(dirname "$0")/.."
# Check if we have uncommitted changes
if ! git diff-index --quiet HEAD --; then
echo -e "${RED}❌ Error: You have uncommitted changes.${NC}"
echo "Please commit or stash them first."
exit 1
fi
# Parse version argument
VERSION="${1:-}"
if [[ -z "$VERSION" ]]; then
echo -e "${RED}❌ Error: No version specified.${NC}"
echo ""
echo "Usage: $0 VERSION"
echo ""
echo "Examples:"
echo " $0 0.3.0 # Bump to version 0.3.0"
echo " $0 1.0.0 # Bump to version 1.0.0"
exit 1
fi
# Strip 'v' prefix if present
VERSION="${VERSION#v}"
# Validate version format (X.Y.Z)
if ! echo "$VERSION" | grep -qE '^[0-9]+\.[0-9]+\.[0-9]+$'; then
echo -e "${RED}❌ Error: Invalid version format: $VERSION${NC}"
echo "Expected format: X.Y.Z (e.g., 0.3.0, 1.0.0)"
exit 1
fi
TAG="v$VERSION"
MANIFEST="custom_components/tibber_prices/manifest.json"
# Check if manifest.json exists
if [[ ! -f "$MANIFEST" ]]; then
echo -e "${RED}❌ Error: Manifest file not found: $MANIFEST${NC}"
exit 1
fi
# Check if tag already exists (locally or remotely)
if git rev-parse "$TAG" >/dev/null 2>&1; then
echo -e "${RED}❌ Error: Tag $TAG already exists locally!${NC}"
echo "To remove it: git tag -d $TAG"
exit 1
fi
if git ls-remote --tags origin | grep -q "refs/tags/$TAG"; then
echo -e "${RED}❌ Error: Tag $TAG already exists on remote!${NC}"
exit 1
fi
# Get current version
CURRENT_VERSION=$(jq -r '.version' "$MANIFEST")
echo -e "${BLUE}Current version: ${CURRENT_VERSION}${NC}"
echo -e "${BLUE}New version: ${VERSION}${NC}"
echo ""
# Update manifest.json
echo -e "${YELLOW}📝 Updating $MANIFEST...${NC}"
if ! command -v jq >/dev/null 2>&1; then
echo -e "${RED}❌ Error: jq is not installed${NC}"
echo "Please install jq: apt-get install jq (or brew install jq)"
exit 1
fi
# Create backup
cp "$MANIFEST" "$MANIFEST.backup"
# Update version with jq
if ! jq ".version = \"$VERSION\"" "$MANIFEST" > "$MANIFEST.tmp"; then
echo -e "${RED}❌ Error: Failed to update manifest.json${NC}"
mv "$MANIFEST.backup" "$MANIFEST"
exit 1
fi
mv "$MANIFEST.tmp" "$MANIFEST"
rm "$MANIFEST.backup"
echo -e "${GREEN}✓ Updated manifest.json${NC}"
# Stage and commit
echo -e "${YELLOW}📦 Creating commit...${NC}"
git add "$MANIFEST"
git commit -m "chore(release): bump version to $VERSION"
echo -e "${GREEN}✓ Created commit${NC}"
# Create annotated tag
echo -e "${YELLOW}🏷️ Creating tag $TAG...${NC}"
git tag -a "$TAG" -m "chore(release): version $VERSION"
echo -e "${GREEN}✓ Created tag $TAG${NC}"
# Show preview
echo ""
echo -e "${GREEN}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
echo -e "${GREEN}✅ Release $VERSION prepared successfully!${NC}"
echo -e "${GREEN}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
echo ""
echo -e "${BLUE}Review the changes:${NC}"
git log -1 --stat
echo ""
echo -e "${BLUE}Review the tag:${NC}"
git show "$TAG" --no-patch
echo ""
echo -e "${GREEN}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
echo -e "${YELLOW}Next steps:${NC}"
echo ""
echo -e " ${GREEN}✓ To push and trigger release:${NC}"
echo -e " git push origin main $TAG"
echo ""
echo -e " ${RED}✗ To abort and undo:${NC}"
echo -e " git reset --hard HEAD~1 # Undo commit"
echo -e " git tag -d $TAG # Delete tag"
echo ""
echo -e "${BLUE}What happens after push:${NC}"
echo " 1. Both commit and tag are pushed to GitHub"
echo " 2. CI/CD detects the new tag"
echo " 3. Release notes are generated automatically"
echo " 4. GitHub release is created"
echo -e "${GREEN}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"