"use strict";(globalThis.webpackChunkdocs_split_developer=globalThis.webpackChunkdocs_split_developer||[]).push([[8079],{3448:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>o,contentTitle:()=>a,default:()=>h,frontMatter:()=>l,metadata:()=>i,toc:()=>c});const i=JSON.parse('{"id":"release-management","title":"Release Notes Generation","description":"This project supports three ways to generate release notes from conventional commits, plus automatic version management.","source":"@site/docs/release-management.md","sourceDirName":".","slug":"/release-management","permalink":"/hass.tibber_prices/developer/release-management","draft":false,"unlisted":false,"editUrl":"https://github.com/jpawlowski/hass.tibber_prices/tree/main/docs/developer/docs/release-management.md","tags":[],"version":"current","lastUpdatedAt":1764985026000,"frontMatter":{"comments":false},"sidebar":"tutorialSidebar","previous":{"title":"Contributing Guide","permalink":"/hass.tibber_prices/developer/contributing"},"next":{"title":"Testing","permalink":"/hass.tibber_prices/developer/testing"}}');var t=s(4848),r=s(8453);const l={comments:!1},a="Release Notes Generation",o={},c=[{value:"\ud83d\ude80 Quick Start: Preparing a Release",id:"-quick-start-preparing-a-release",level:2},{value:"\ud83d\udccb Release Options",id:"-release-options",level:2},{value:"1. GitHub UI Button (Easiest)",id:"1-github-ui-button-easiest",level:3},{value:"2. Local Script (Intelligent)",id:"2-local-script-intelligent",level:3},{value:"Backend Priority",id:"backend-priority",level:4},{value:"Installing Optional Backends",id:"installing-optional-backends",level:4},{value:"3. CI/CD Automation",id:"3-cicd-automation",level:3},{value:"\ud83d\udcdd Output Format",id:"-output-format",level:2},{value:"\ud83c\udfaf When to Use Which",id:"-when-to-use-which",level:2},{value:"\ud83d\udd04 Complete Release Workflows",id:"-complete-release-workflows",level:2},{value:"Workflow A: Using Helper Script (Recommended)",id:"workflow-a-using-helper-script-recommended",level:3},{value:"Workflow B: Manual (with Auto-Tag Safety Net)",id:"workflow-b-manual-with-auto-tag-safety-net",level:3},{value:"Workflow C: Manual Tag (Old Way)",id:"workflow-c-manual-tag-old-way",level:3},{value:"\u2699\ufe0f Configuration Files",id:"\ufe0f-configuration-files",level:2},{value:"\ud83d\udee1\ufe0f Safety Features",id:"\ufe0f-safety-features",level:2},{value:"1. Version Validation",id:"1-version-validation",level:3},{value:"2. No Duplicate Tags",id:"2-no-duplicate-tags",level:3},{value:"3. Atomic Operations",id:"3-atomic-operations",level:3},{value:"4. Version Bumps Filtered",id:"4-version-bumps-filtered",level:3},{value:"5. Rollback Instructions",id:"5-rollback-instructions",level:3},{value:"\ud83d\udc1b Troubleshooting",id:"-troubleshooting",level:2},{value:"\ud83d\udd0d Format Requirements",id:"-format-requirements",level:2},{value:"\ud83d\udca1 Tips",id:"-tips",level:2}];function d(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",h4:"h4",header:"header",hr:"hr",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,r.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.header,{children:(0,t.jsx)(n.h1,{id:"release-notes-generation",children:"Release Notes Generation"})}),"\n",(0,t.jsxs)(n.p,{children:["This project supports ",(0,t.jsx)(n.strong,{children:"three ways"})," to generate release notes from conventional commits, plus ",(0,t.jsx)(n.strong,{children:"automatic version management"}),"."]}),"\n",(0,t.jsx)(n.h2,{id:"-quick-start-preparing-a-release",children:"\ud83d\ude80 Quick Start: Preparing a Release"}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.strong,{children:"Recommended workflow (automatic & foolproof):"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:'# 1. Use the helper script to prepare release\n./scripts/release/prepare 0.3.0\n\n# This will:\n# - Update manifest.json version to 0.3.0\n# - Create commit: "chore(release): bump version to 0.3.0"\n# - Create tag: v0.3.0\n# - Show you what will be pushed\n\n# 2. Review and push when ready\ngit push origin main v0.3.0\n\n# 3. CI/CD automatically:\n# - Detects the new tag\n# - Generates release notes (excluding version bump commit)\n# - Creates GitHub release\n'})}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.strong,{children:"If you forget to bump manifest.json:"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:'# Just edit manifest.json manually and commit\nvim custom_components/tibber_prices/manifest.json # "version": "0.3.0"\ngit commit -am "chore(release): bump version to 0.3.0"\ngit push\n\n# Auto-Tag workflow detects manifest.json change and creates tag automatically!\n# Then Release workflow kicks in and creates the GitHub release\n'})}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsx)(n.h2,{id:"-release-options",children:"\ud83d\udccb Release Options"}),"\n",(0,t.jsx)(n.h3,{id:"1-github-ui-button-easiest",children:"1. GitHub UI Button (Easiest)"}),"\n",(0,t.jsx)(n.p,{children:"Use GitHub's built-in release notes generator:"}),"\n",(0,t.jsxs)(n.ol,{children:["\n",(0,t.jsxs)(n.li,{children:["Go to ",(0,t.jsx)(n.a,{href:"https://github.com/jpawlowski/hass.tibber_prices/releases",children:"Releases"})]}),"\n",(0,t.jsx)(n.li,{children:'Click "Draft a new release"'}),"\n",(0,t.jsx)(n.li,{children:"Select your tag"}),"\n",(0,t.jsx)(n.li,{children:'Click "Generate release notes" button'}),"\n",(0,t.jsx)(n.li,{children:"Edit if needed and publish"}),"\n"]}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Uses:"})," ",(0,t.jsx)(n.code,{children:".github/release.yml"})," configuration\n",(0,t.jsx)(n.strong,{children:"Best for:"})," Quick releases, works with PRs that have labels\n",(0,t.jsx)(n.strong,{children:"Note:"}),' Direct commits appear in "Other Changes" category']}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsx)(n.h3,{id:"2-local-script-intelligent",children:"2. Local Script (Intelligent)"}),"\n",(0,t.jsxs)(n.p,{children:["Run ",(0,t.jsx)(n.code,{children:"./scripts/release/generate-notes"})," to parse conventional commits locally."]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.strong,{children:"Automatic backend detection:"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"# Generate from latest tag to HEAD\n./scripts/release/generate-notes\n\n# Generate between specific tags\n./scripts/release/generate-notes v1.0.0 v1.1.0\n\n# Generate from tag to HEAD\n./scripts/release/generate-notes v1.0.0 HEAD\n"})}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.strong,{children:"Force specific backend:"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"# Use AI (GitHub Copilot CLI)\nRELEASE_NOTES_BACKEND=copilot ./scripts/release/generate-notes\n\n# Use git-cliff (template-based)\nRELEASE_NOTES_BACKEND=git-cliff ./scripts/release/generate-notes\n\n# Use manual parsing (grep/awk fallback)\nRELEASE_NOTES_BACKEND=manual ./scripts/release/generate-notes\n"})}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Disable AI"})," (useful for CI/CD):"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"USE_AI=false ./scripts/release/generate-notes\n"})}),"\n",(0,t.jsx)(n.h4,{id:"backend-priority",children:"Backend Priority"}),"\n",(0,t.jsx)(n.p,{children:"The script automatically selects the best available backend:"}),"\n",(0,t.jsxs)(n.ol,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.strong,{children:"GitHub Copilot CLI"})," - AI-powered, context-aware (best quality)"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.strong,{children:"git-cliff"})," - Fast Rust tool with templates (reliable)"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.strong,{children:"Manual"})," - Simple grep/awk parsing (always works)"]}),"\n"]}),"\n",(0,t.jsxs)(n.p,{children:["In CI/CD (",(0,t.jsx)(n.code,{children:"$CI"})," or ",(0,t.jsx)(n.code,{children:"$GITHUB_ACTIONS"}),"), AI is automatically disabled."]}),"\n",(0,t.jsx)(n.h4,{id:"installing-optional-backends",children:"Installing Optional Backends"}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.strong,{children:"In DevContainer (automatic):"})}),"\n",(0,t.jsx)(n.p,{children:"git-cliff is automatically installed when the DevContainer is built:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.strong,{children:"Rust toolchain"}),": Installed via ",(0,t.jsx)(n.code,{children:"ghcr.io/devcontainers/features/rust:1"})," (minimal profile)"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.strong,{children:"git-cliff"}),": Installed via cargo in ",(0,t.jsx)(n.code,{children:"scripts/setup/setup"})]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:'Simply rebuild the container (VS Code: "Dev Containers: Rebuild Container") and git-cliff will be available.'}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.strong,{children:"Manual installation (outside DevContainer):"})}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"git-cliff"})," (template-based):"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"# See: https://git-cliff.org/docs/installation\n\n# macOS\nbrew install git-cliff\n\n# Cargo (all platforms)\ncargo install git-cliff\n\n# Manual binary download\nwget https://github.com/orhun/git-cliff/releases/latest/download/git-cliff-x86_64-unknown-linux-gnu.tar.gz\ntar -xzf git-cliff-*.tar.gz\nsudo mv git-cliff-*/git-cliff /usr/local/bin/\n"})}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsx)(n.h3,{id:"3-cicd-automation",children:"3. CI/CD Automation"}),"\n",(0,t.jsx)(n.p,{children:"Automatic release notes on tag push."}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Workflow:"})," ",(0,t.jsx)(n.code,{children:".github/workflows/release.yml"})]}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Triggers:"})," Version tags (",(0,t.jsx)(n.code,{children:"v1.0.0"}),", ",(0,t.jsx)(n.code,{children:"v2.1.3"}),", etc.)"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"# Create and push a tag to trigger automatic release\ngit tag v1.0.0\ngit push origin v1.0.0\n\n# GitHub Actions will:\n# 1. Detect the new tag\n# 2. Generate release notes using git-cliff\n# 3. Create a GitHub release automatically\n"})}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Backend:"})," Uses ",(0,t.jsx)(n.code,{children:"git-cliff"})," (AI disabled in CI for reliability)"]}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsx)(n.h2,{id:"-output-format",children:"\ud83d\udcdd Output Format"}),"\n",(0,t.jsx)(n.p,{children:"All methods produce GitHub-flavored Markdown with emoji categories:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-markdown",children:"## \ud83c\udf89 New Features\n\n- **scope**: Description ([abc1234](link-to-commit))\n\n## \ud83d\udc1b Bug Fixes\n\n- **scope**: Description ([def5678](link-to-commit))\n\n## \ud83d\udcda Documentation\n\n- **scope**: Description ([ghi9012](link-to-commit))\n\n## \ud83d\udd27 Maintenance & Refactoring\n\n- **scope**: Description ([jkl3456](link-to-commit))\n\n## \ud83e\uddea Testing\n\n- **scope**: Description ([mno7890](link-to-commit))\n"})}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsx)(n.h2,{id:"-when-to-use-which",children:"\ud83c\udfaf When to Use Which"}),"\n",(0,t.jsxs)(n.table,{children:[(0,t.jsx)(n.thead,{children:(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.th,{children:"Method"}),(0,t.jsx)(n.th,{children:"Use Case"}),(0,t.jsx)(n.th,{children:"Pros"}),(0,t.jsx)(n.th,{children:"Cons"})]})}),(0,t.jsxs)(n.tbody,{children:[(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.strong,{children:"Helper Script"})}),(0,t.jsx)(n.td,{children:"Normal releases"}),(0,t.jsx)(n.td,{children:"Foolproof, automatic"}),(0,t.jsx)(n.td,{children:"Requires script"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.strong,{children:"Auto-Tag Workflow"})}),(0,t.jsx)(n.td,{children:"Forgot script"}),(0,t.jsx)(n.td,{children:"Safety net, automatic tagging"}),(0,t.jsx)(n.td,{children:"Still need manifest bump"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.strong,{children:"GitHub Button"})}),(0,t.jsx)(n.td,{children:"Manual quick release"}),(0,t.jsx)(n.td,{children:"Easy, no script"}),(0,t.jsx)(n.td,{children:"Limited categorization"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.strong,{children:"Local Script"})}),(0,t.jsx)(n.td,{children:"Testing release notes"}),(0,t.jsx)(n.td,{children:"Preview before release"}),(0,t.jsx)(n.td,{children:"Manual process"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.strong,{children:"CI/CD"})}),(0,t.jsx)(n.td,{children:"After tag push"}),(0,t.jsx)(n.td,{children:"Fully automatic"}),(0,t.jsx)(n.td,{children:"Needs tag first"})]})]})]}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsx)(n.h2,{id:"-complete-release-workflows",children:"\ud83d\udd04 Complete Release Workflows"}),"\n",(0,t.jsx)(n.h3,{id:"workflow-a-using-helper-script-recommended",children:"Workflow A: Using Helper Script (Recommended)"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"# Step 1: Prepare release (all-in-one)\n./scripts/release/prepare 0.3.0\n\n# Step 2: Review changes\ngit log -1 --stat\ngit show v0.3.0\n\n# Step 3: Push when ready\ngit push origin main v0.3.0\n\n# Done! CI/CD creates the release automatically\n"})}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.strong,{children:"What happens:"})}),"\n",(0,t.jsxs)(n.ol,{children:["\n",(0,t.jsx)(n.li,{children:"Script bumps manifest.json \u2192 commits \u2192 creates tag locally"}),"\n",(0,t.jsx)(n.li,{children:"You push commit + tag together"}),"\n",(0,t.jsx)(n.li,{children:"Release workflow sees tag \u2192 generates notes \u2192 creates release"}),"\n"]}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsx)(n.h3,{id:"workflow-b-manual-with-auto-tag-safety-net",children:"Workflow B: Manual (with Auto-Tag Safety Net)"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:'# Step 1: Bump version manually\nvim custom_components/tibber_prices/manifest.json\n# Change: "version": "0.3.0"\n\n# Step 2: Commit\ngit commit -am "chore(release): bump version to 0.3.0"\ngit push\n\n# Step 3: Wait for Auto-Tag workflow\n# GitHub Actions automatically creates v0.3.0 tag\n# Then Release workflow creates the release\n'})}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.strong,{children:"What happens:"})}),"\n",(0,t.jsxs)(n.ol,{children:["\n",(0,t.jsx)(n.li,{children:"You push manifest.json change"}),"\n",(0,t.jsx)(n.li,{children:"Auto-Tag workflow detects change \u2192 creates tag automatically"}),"\n",(0,t.jsx)(n.li,{children:"Release workflow sees new tag \u2192 creates release"}),"\n"]}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsx)(n.h3,{id:"workflow-c-manual-tag-old-way",children:"Workflow C: Manual Tag (Old Way)"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:'# Step 1: Bump version\nvim custom_components/tibber_prices/manifest.json\ngit commit -am "chore(release): bump version to 0.3.0"\n\n# Step 2: Create tag manually\ngit tag v0.3.0\ngit push origin main v0.3.0\n\n# Release workflow creates release\n'})}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.strong,{children:"What happens:"})}),"\n",(0,t.jsxs)(n.ol,{children:["\n",(0,t.jsx)(n.li,{children:"You create and push tag manually"}),"\n",(0,t.jsx)(n.li,{children:"Release workflow creates release"}),"\n",(0,t.jsx)(n.li,{children:"Auto-Tag workflow skips (tag already exists)"}),"\n"]}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsx)(n.h2,{id:"\ufe0f-configuration-files",children:"\u2699\ufe0f Configuration Files"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"scripts/release/prepare"})," - Helper script to bump version + create tag"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:".github/workflows/auto-tag.yml"})," - Automatic tag creation on manifest.json change"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:".github/workflows/release.yml"})," - Automatic release on tag push"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:".github/release.yml"})," - GitHub UI button configuration"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"cliff.toml"})," - git-cliff template (filters out version bumps)"]}),"\n"]}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsx)(n.h2,{id:"\ufe0f-safety-features",children:"\ud83d\udee1\ufe0f Safety Features"}),"\n",(0,t.jsxs)(n.h3,{id:"1-version-validation",children:["1. ",(0,t.jsx)(n.strong,{children:"Version Validation"})]}),"\n",(0,t.jsx)(n.p,{children:"Both helper script and auto-tag workflow validate version format (X.Y.Z)."}),"\n",(0,t.jsxs)(n.h3,{id:"2-no-duplicate-tags",children:["2. ",(0,t.jsx)(n.strong,{children:"No Duplicate Tags"})]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"Helper script checks if tag exists (local + remote)"}),"\n",(0,t.jsx)(n.li,{children:"Auto-tag workflow checks if tag exists before creating"}),"\n"]}),"\n",(0,t.jsxs)(n.h3,{id:"3-atomic-operations",children:["3. ",(0,t.jsx)(n.strong,{children:"Atomic Operations"})]}),"\n",(0,t.jsx)(n.p,{children:"Helper script creates commit + tag locally. You decide when to push."}),"\n",(0,t.jsxs)(n.h3,{id:"4-version-bumps-filtered",children:["4. ",(0,t.jsx)(n.strong,{children:"Version Bumps Filtered"})]}),"\n",(0,t.jsxs)(n.p,{children:["Release notes automatically exclude ",(0,t.jsx)(n.code,{children:"chore(release): bump version"})," commits."]}),"\n",(0,t.jsxs)(n.h3,{id:"5-rollback-instructions",children:["5. ",(0,t.jsx)(n.strong,{children:"Rollback Instructions"})]}),"\n",(0,t.jsx)(n.p,{children:"Helper script shows how to undo if you change your mind."}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsx)(n.h2,{id:"-troubleshooting",children:"\ud83d\udc1b Troubleshooting"}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.strong,{children:'"Tag already exists" error:'})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"# Local tag\ngit tag -d v0.3.0\n\n# Remote tag (only if you need to recreate)\ngit push origin :refs/tags/v0.3.0\n"})}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.strong,{children:"Manifest version doesn't match tag:"})}),"\n",(0,t.jsx)(n.p,{children:"This shouldn't happen with the new workflows, but if it does:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:'# 1. Fix manifest.json\nvim custom_components/tibber_prices/manifest.json\n\n# 2. Amend the commit\ngit commit --amend -am "chore(release): bump version to 0.3.0"\n\n# 3. Move the tag\ngit tag -f v0.3.0\ngit push -f origin main v0.3.0\n'})}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.strong,{children:"Auto-tag didn't create tag:"})}),"\n",(0,t.jsx)(n.p,{children:"Check workflow runs in GitHub Actions. Common causes:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"Tag already exists remotely"}),"\n",(0,t.jsx)(n.li,{children:"Invalid version format in manifest.json"}),"\n",(0,t.jsx)(n.li,{children:"manifest.json not in the commit that was pushed"}),"\n"]}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsx)(n.h2,{id:"-format-requirements",children:"\ud83d\udd0d Format Requirements"}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"HACS:"})," No specific format required, uses GitHub releases as-is\n",(0,t.jsx)(n.strong,{children:"Home Assistant:"})," No specific format required for custom integrations\n",(0,t.jsx)(n.strong,{children:"Markdown:"})," Standard GitHub-flavored Markdown supported\n",(0,t.jsx)(n.strong,{children:"HTML:"})," Can include ",(0,t.jsx)(n.code,{children:""})," tags if needed"]}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsx)(n.h2,{id:"-tips",children:"\ud83d\udca1 Tips"}),"\n",(0,t.jsxs)(n.ol,{children:["\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Conventional Commits:"})," Use proper commit format for best results:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:"feat(scope): Add new feature\n\nDetailed description of what changed.\n\nImpact: Users can now do X and Y.\n"})}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Impact Section:"})," Add ",(0,t.jsx)(n.code,{children:"Impact:"})," in commit body for user-friendly descriptions"]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Test Locally:"})," Run ",(0,t.jsx)(n.code,{children:"./scripts/release/generate-notes"})," before creating release"]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"AI vs Template:"})," GitHub Copilot CLI provides better descriptions, git-cliff is faster and more reliable"]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"CI/CD:"})," Tag push triggers automatic release - no manual intervention needed"]}),"\n"]}),"\n"]})]})}function h(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(d,{...e})}):d(e)}}}]);