Release Har Skill
Universal release automation skill. Works with any project.
Quick Reference
- "release" →
/release-har - "bump version" →
/release-har patch - "minor release" →
/release-har minor - "preview only" →
/release-har --dry-run
References
| Document | 内容 | |----------|------| | references/release-notes-template.md | GitHub Release Notes テンプレート(4セクション構造) | | references/changelog-format.md | CHANGELOG.md フォーマット(Keep a Changelog 準拠) | | .claude/rules/github-release.md | Release Notes フォーマットルール(正本) |
Branch Policy
単独開発プロジェクトでは main への直接 push を許容する。
- CI が
push: branches: [main]で全検証を実行するため、PR なしでも品質ゲートは機能する release.ymlがv*タグ push 時に GitHub Release の存在を保証するセーフティネットとして動作する- force push(
--force/--force-with-lease)は禁止
共同開発者がいるプロジェクトでは、PR 経由のマージに切り替えること。
Execution Flow
Pre-flight: 事前チェック(必須)
リリース開始前に以下を確認する。失敗した場合はリリースを停止し修正を促す。
# 1. gh コマンドの存在確認
if ! command -v gh &>/dev/null; then
echo "⚠️ gh コマンドが見つかりません。GitHub Release の作成はスキップします。"
GH_AVAILABLE=false
else
GH_AVAILABLE=true
fi
# 2. 未コミット変更の確認
if ! git diff --quiet || ! git diff --cached --quiet; then
echo "❌ 未コミットの変更があります。コミットまたはスタッシュ後にリリースしてください。"
git status --short
exit 1
fi
# 3. バージョンファイル同期確認(VERSION と plugin.json が存在する場合)
if [ -f "VERSION" ] && [ -f ".claude-plugin/plugin.json" ]; then
V_VERSION=$(cat VERSION | tr -d '[:space:]')
V_PLUGIN=$(grep '"version"' .claude-plugin/plugin.json | sed 's/.*"version": "\([^"]*\)".*/\1/')
if [ "$V_VERSION" != "$V_PLUGIN" ]; then
echo "❌ バージョン不一致: VERSION=$V_VERSION, plugin.json=$V_PLUGIN"
echo " 修正: ./scripts/sync-version.sh sync"
exit 1
fi
fi
| チェック | 失敗時の動作 | |----------|-------------| | gh コマンド存在 | 警告のみ・続行(GitHub Release のみスキップ) | | 未コミット変更 | 停止(コミットまたはスタッシュを促す) | | バージョンファイル同期 | 停止(sync-version.sh sync を促す) |
Step 1: 変更分析
以下を並列取得する。
# 前タグを取得
PREV_TAG=$(git describe --tags --abbrev=0 HEAD~1 2>/dev/null \
|| git tag --sort=-v:refname | head -1 2>/dev/null \
|| echo "")
# 構造化コミットログ(フォーマット: {hash}|{subject}|{author}|{date})
if [ -n "$PREV_TAG" ]; then
LOG=$(git log --format="%h|%s|%an|%ad" --date=short "${PREV_TAG}..HEAD")
else
LOG=$(git log --format="%h|%s|%an|%ad" --date=short --all | head -20)
fi
# OWNER/REPO 取得(gh 優先 → git remote フォールバック)
if command -v gh &>/dev/null; then
REPO_FULL=$(gh repo view --json nameWithOwner -q '.nameWithOwner' 2>/dev/null || echo "")
fi
if [ -z "${REPO_FULL:-}" ]; then
REMOTE_URL=$(git remote get-url origin 2>/dev/null || echo "")
REPO_FULL=$(echo "$REMOTE_URL" \
| sed -E 's|https://github\.com/||; s|git@github\.com:||; s|\.git$||')
fi
Conventional Commits 分類
| Prefix | CHANGELOG カテゴリ |
|--------|-------------------|
| feat: / feat(...): | Added |
| fix: / fix(...): | Fixed |
| docs: / perf: / refactor: / test: / chore: | Changed |
| その他 / 分類不能 | Changed |
BREAKING CHANGE 検出: feat!: / fix!: 等の ! 付きタイプ、または本文に BREAKING CHANGE: を含むコミット。
Conventional Commits を使っていないプロジェクトでは、Claude がコミットメッセージを意味的に判断して分類する。
変更分析サマリ表示
📊 変更分析サマリ (vPREV → vNEW候補)
━━━━━━━━━━━━━━━━━━━━━━━━━
- feat : N 件 → Added
- fix : M 件 → Fixed
- other : L 件 → Changed
- breaking : K 件 → Breaking Changes ⚠️
─────────────────────────────────
- contributors: X 名
- compare: https://github.com/{OWNER}/{REPO}/compare/{PREV_TAG}...HEAD
━━━━━━━━━━━━━━━━━━━━━━━━━
Step 2: SemVer 判定
Step 1 の分析結果に基づいてバージョンを提案する。
PREV_VERSION=${PREV_TAG#v} # "v1.2.3" → "1.2.3"
MAJOR=$(echo "$PREV_VERSION" | cut -d. -f1)
MINOR=$(echo "$PREV_VERSION" | cut -d. -f2)
PATCH=$(echo "$PREV_VERSION" | cut -d. -f3)
if [ "${BREAKING_COUNT:-0}" -ge 1 ]; then
SUGGESTED_VERSION="$((MAJOR+1)).0.0" # major
elif [ "${FEAT_COUNT:-0}" -ge 1 ]; then
SUGGESTED_VERSION="${MAJOR}.$((MINOR+1)).0" # minor
else
SUGGESTED_VERSION="${MAJOR}.${MINOR}.$((PATCH+1))" # patch
fi
表示例: 📦 SemVer 判定: MINOR (1.2.3 → 1.3.0) 理由: feat: 3件, fix: 2件, breaking: 0件
| 引数 | 動作 |
|------|------|
| /release-har patch | 確認なしで PATCH 採用 |
| /release-har minor | 確認なしで MINOR 採用 |
| /release-har major | 確認なしで MAJOR 採用 |
| 引数なし | 自動判定結果を表示し、ユーザーに確認 |
0.x.y 初期開発段階: MAJOR=0 の場合は SemVer 2.0.0 §4 に従い、breaking change でも minor バンプ (0.x+1.0) または major (1.0.0) をユーザーに選択させる。
Step 3: diff 要約 & Release Notes 草稿生成
コミットメッセージだけでなく実際のコード差分を読み、Highlights と Before/After テーブルを生成する。
# 変更ファイルを確認(テスト・ロックファイルは低優先)
git diff --stat "${PREV_TAG}..HEAD"
# 重要ファイルの diff を読む(src/ 配下を優先)
git diff "${PREV_TAG}..HEAD" -- <重要ファイルパス> | head -100
Claude が生成するもの(最大3件):
- Highlights: ユーザー視点での価値(1-3文)
- Before / After テーブル: 変更前後の状態
テンプレート詳細: references/release-notes-template.md
Step 4: dry-run プレビュー(デフォルト前段)
本実行前に必ずプレビューを表示する(--dry-run なし通常実行でも同様)。
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
🔍 リリースプレビュー: v{PREV} → v{NEW}
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
📦 タグ: vX.Y.Z
📁 更新ファイル: CHANGELOG.md, VERSION, package.json(存在する場合)
📄 CHANGELOG エントリ(全文):
{CHANGELOG エントリ}
🧹 Documentation Cleanup:
CHANGELOG: {正規化対象 N 件}(日付フォーマット、セクション見出し等)
README: {更新対象 M 件}(バージョン参照、機能一覧等)
📝 GitHub Release Notes(全文):
{4セクション構造の Release Notes}
🔗 Compare URL: {COMPARE_URL}
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
この内容で実行しますか? (yes / no / 修正指示)
| 回答 | 動作 |
|------|------|
| yes | Step 5 以降の本実行へ |
| no | 中止 |
| 修正指示 | Release Notes を修正して再プレビュー |
--dry-run オプション時: プレビュー後に終了(本実行なし)。
Step 5: CHANGELOG 更新(存在する場合)
CHANGELOG.md があれば更新する。フォーマット詳細: references/changelog-format.md
## [X.Y.Z] - YYYY-MM-DD
### 🎯 What's Changed for You
**{one-line バリュー要約}**
| Before | After |
|--------|-------|
| {旧状態} | {新状態} |
### Added
- **{Feature}**: {description}
### Fixed
- **{Fix}**: {description}
CHANGELOG_ja.md が存在する場合は同内容を日本語で更新する。
CHANGELOG が存在しない場合はスキップ。
Step 5.5: Documentation Cleanup(既存ドキュメント整備)
リリースのタイミングで、既存ドキュメントの品質も整える。新規エントリの追加だけでなく、過去の汚れも修正する。
CHANGELOG 既存エントリの正規化
過去エントリが Keep a Changelog 1.1.0 に準拠していない場合、正規化する。
| チェック項目 | 修正例 |
|-------------|--------|
| 日付フォーマット | 2026/02/23 → 2026-02-23 (ISO 8601) |
| セクション見出し | ### New Features → ### Added |
| 空セクション | 内容のない見出しを削除 |
| リンク切れ | Compare URL のタグ名修正 |
| マークダウン構文 | テーブル崩れ、リスト記法の統一 |
CHANGELOG_ja.md が存在する場合、同等の整備を実施する。
README の更新
| チェック項目 | 修正内容 | |-------------|---------| | バージョン番号 | バッジ、インストール例、参照を新バージョンに更新 | | 機能一覧 | 実態と乖離している記述を修正 | | コマンド/API 例 | 廃止・変更されたものを更新 | | リンク切れ | 存在しないファイルへのリンクを修正 |
判断基準: 明らかに古い・壊れている箇所のみ修正する。意図的なスタイルの違いは尊重する。README が存在しない場合はスキップ。
Step 6: バージョンファイル更新
プロジェクトに応じてバージョンを更新する。
| ファイル | 更新方法 |
|---------|---------|
| VERSION | ファイル内容を直接書き換え |
| package.json | "version": "X.Y.Z" を更新 |
| pyproject.toml | version = "X.Y.Z" を更新 |
| Cargo.toml | version = "X.Y.Z" を更新 |
| .claude-plugin/plugin.json | ./scripts/sync-version.sh sync を実行 |
該当ファイルが存在しない場合はスキップ。
Node.js プロジェクト: npm version patch --no-git-tag-version も利用可。
Step 7: コミット & タグ
# 変更対象ファイルのみ明示的に追加(git add -A は使用しない)
git add CHANGELOG.md README.md VERSION package.json # 実際に変更したファイルのみ
# コミット(変更がある場合のみ)
git commit -m "chore: release vX.Y.Z"
# タグ作成
git tag -a vX.Y.Z -m "Release vX.Y.Z"
Step 8: Push
git push origin $(git branch --show-current)
git push origin vX.Y.Z
Step 9: GitHub Release(オプション)
ユーザー確認後に GitHub Release を作成する。Release Notes は英語必須。
gh release create vX.Y.Z \
--title "vX.Y.Z - {release title}" \
--notes "$(cat <<'EOF'
## What's Changed
**{one-line バリュー要約}**
### Before / After
| Before | After |
|--------|-------|
| {旧状態} | {新状態} |
---
## Highlights
- **{Feature}**: {description}
## Notable Changes
### Added
- **{feature}**: {description}
### Fixed
- **{fix}**: {description}
## Full Changelog
**Full Changelog**: ${COMPARE_URL}
---
Generated with [Claude Code](https://claude.com/claude-code)
EOF
)"
フォーマットルール: .claude/rules/github-release.md テンプレート詳細: references/release-notes-template.md
必須事項:
- Release Notes は英語
- Before/After テーブルは省略不可
Generated with [Claude Code](https://claude.com/claude-code)フッターは省略不可- Breaking Changes がない場合はそのセクションを省略
- Highlights は最大3件
Step 10: X (Twitter) 告知文生成(--announce 指定時のみ)
/release-har --announce で実行した場合、GitHub Release 作成後に X 向け告知文を自動生成する。
生成ロジック
Step 3(diff 要約)で生成した Highlights のうち最も重要な1〜2点を1行ずつに圧縮し、280文字以内の告知文を作成する。
フォーマット
🚀 v{VERSION} released!
{Highlights から抽出した1行要約(日本語または英語、プロジェクトの言語に合わせる)}
{2行目(任意)}
{GitHub Release URL}
例:
🚀 v1.3.0 released!
Pre-flight checks + Claude diff summarization で配信品質が向上。
SemVer 自動判定と dry-run プレビューで事故を防止。
https://github.com/OWNER/REPO/releases/tag/v1.3.0
制約
| 制約 | 値 | |------|-----| | 最大文字数 | 280文字(X の制限) | | 絵文字 | 最小限(🚀 のみ推奨) | | リンク | 必須(GitHub Release URL) | | 言語 | プロジェクトの主要言語に合わせる |
生成後、そのままコピーできる形式でユーザーに提示する。投稿は Claude では行わない(手動コピー&ペースト)。
Options
| Option | Description |
|--------|-------------|
| patch | パッチバージョンを自動インクリメント |
| minor | マイナーバージョンを自動インクリメント |
| major | メジャーバージョンを自動インクリメント |
| --dry-run | プレビューのみ(ファイル変更・コミット・タグ・push なし) |
| --announce | リリース後に X(旧 Twitter)向け告知文を生成 |
Related Skills
x-release-harness- Harness plugin 専用リリース(ローカルのみ)verify- リリース前の検証