prepare-release について
prepare-release は Cherry Studio のリリース準備スキルです。バージョンを検証し、変更から二言語のリリースノートを作成して関連ファイルを更新し、ブランチと CI/CD の手順を開始します。
主な機能
- 01更新種別または指定バージョンの解析
- 02コミット収集と二言語ノート作成
- 03リリースメタデータの更新
- 04リリースブランチ作成と CI/CD 起動
- 05リリース状態とバージョン順序の検証
活用シーン
- 01Cherry Studio のパッチまたはマイナーリリース準備
- 02英語と中国語のリリースノート作成
- 03リリースブランチからビルドと公開を開始
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ cherryhq/ cherry-studio --skill prepare-releaseインストール後、Claude Code で/prepare-releaseを入力して読み込まれたか確認します。
詳細
リリースの準備
Cherry のリリースワークフローを自動化します: 変更の収集 → バイリンガルのリリースノート生成 → ファイルの更新 → リリースブランチの作成 → CI/CD。
引数
ユーザーのメッセージからバージョンの意図を解析します。次のいずれかの形式を受け付けます:
- バージョン種別の指定:
patch、minor、major - 正確なバージョン: ビルドメタデータなしの厳密な
x.y.zまたはx.y.z-<prerelease>(例:1.8.0、1.8.0-beta.1、1.8.0-rc.1) - 自然言語: 「ベータリリースを準備して」「1.8.0-rc.2 にバージョンを上げて」など。
バージョンが指定されていない場合は patch が既定です。ファイルを編集する前に、解決されたターゲットバージョンを必ずユーザーにそのまま伝えてください。
--dry-run: プレビューのみ。リリースブランチは作成しません。
ワークフロー
ステップ 1: バージョンの決定
- 対話的なローカル実行では、
origin/mainとすべてのタグを取得し、チェックアウトがクリーンなmainであり、正確にorigin/mainと一致することを確認します:
いずれかのチェックが失敗した場合は、ファイルを編集する前に停止します。これにより、任意の、または古いチェックアウトからリリースブランチが作成されるのを防ぎます。 GitHub Actions では、ワークフローの凍結された dispatch SHA を使用し、チェックアウトの検証はワークフローに任せます。後から取得したgit fetch origin refs/heads/main:refs/remotes/origin/main --tags test "$(git branch --show-current)" = main test -z "$(git status --porcelain)" test "$(git rev-parse HEAD)" = "$(git rev-parse origin/main)"origin/mainの head を取得したり比較したりしないでください。 package.jsonから現在のバージョンを読み取ります。そのリリースがその後撤回された場合でも、バージョン increment にはこれを使用します。撤回されたバージョンを再利用しないでください。- タグが厳密な
v<semver>である、公開済みでドラフトではない最新の GitHub Release を、リリースノートのベースラインとして選択します。semver でないプレビューリリースとドラフトは決してベースラインになりません:
公開済みのリリースが存在しない場合、またはそのタグが見つからない場合(gh release list --limit 1000 --json isDraft,publishedAt,tagName --jq '[.[] | select(.isDraft == false and (.tagName | test("^v(0|[1-9][0-9]*)\\.(0|[1-9][0-9]*)\\.(0|[1-9][0-9]*)(-[0-9A-Za-z-]+(\\.[0-9A-Za-z-]+)*)?$")))] | sort_by(.publishedAt) | last | .tagName // empty'git rev-parse --verify refs/tags/{baseline-tag})は停止します。semverを使用して、そのバージョンと現在のパッケージバージョンを比較します: main が遅れている場合は停止し、最新の Post Release メタデータがマージされることを必須とします。main が進んでいる場合は、リリースノートには公開済みのベースラインを、バージョン increment にはパッケージバージョンを使用して準備を許可します。たとえば、2.1.1 を撤回した後、main が 2.1.1 で公開済みのベースラインが 2.1.0 の場合、2.1.2 を準備し、2.1.0 以降の変更を含めます。 GitHub Actions では、これらのチェックを繰り返さずに、ワークフローが提供するベースラインタグと収集ベースを使用します。 - 引数に基づいて新しいバージョンを計算します:
patch/minor/major: 現在のバージョンから increment します。- 正確なバージョンは
^(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)(-[0-9A-Za-z-]+(\.[0-9A-Za-z-]+)*)?$に一致し、semver.validを通過する必要があります。+build.1のようなビルドメタデータは受け付けられません。 - どちらの場合も、semver の優先順位に従って、結果が現在のバージョンより厳密に大きいことを必須とします。同等のバージョンとダウングレードは拒否します。
ステップ 2: コミットを収集する
- リリースノートの収集ベースは、パッケージのバージョンではなく、ステップ 1 で選択した公開済みベースラインから決定します:
- ベースラインタグが
HEADの祖先である場合は、そのタグを使用します。 - そうでない場合は、完全なメッセージに正確なマーカー
release-metadata-boundary: <baseline-tag>を含む最新のコミットを使用します。このマシンマーカーは Post Release プルリクエストの本文に追加され、必須のスカッシュマージを経ても残ります。 - マシンマーカーが存在する前に作成されたメタデータプルリクエストについては、
chore(release): sync <baseline-tag> metadataに完全に一致するサブジェクト、またはそのサブジェクトの直後に GitHub のスカッシュサフィックス(#<PR-number>)のみが続くものを受け入れます。 - タグが祖先ではなく、そのメタデータ同期コミットが存在しない場合はエラーで停止します。そうしないと、すでにリリース済みのホットフィックスが再び含まれる可能性があります。
- ベースラインタグが
- そのベース以降のすべてのコミットを一覧表示します:
git log <collection-base>..HEAD --format="%H %s" --no-merges - 各コミットについて、完全な本文を取得します:
git log <hash> -1 --format="%B" - 各コミット本文から
```release-noteコードブロック内の内容を抽出します。 - タイトルから conventional commit のタイプ(
feat、fix、refactor、perf、docsなど)を抽出します。 - 以下のコミットは単独のリリースノート候補としてスキップしますが、ステップ 3 で候補を最終コードと突き合わせる際には、その影響を引き続き調査します:
🤖 Daily Auto I18Nで始まるタイトルMergeで始まるタイトルchore(deps)で始まるタイトルchore: releaseで始まるタイトルchore(release)で始まるタイトル- release-note ブロックが
NONEと記載されているコミット
ステップ 3: バイリンガルのリリースノートを生成する
公開済みベースラインに対する最終的なユーザーに見える変更から、英語と中国語の両方でリリースノートを生成します。コミットのタイトルと release-note ブロックは候補の説明であり、変更が出荷されることの証明ではありません。
下書きの前に正味の変更を突き合わせます:
git diff --name-status <baseline-tag> <release-head>を調査し、両方のエンドポイントで関連するパッチとコードを読みます。<release-head>はリリース準備前のソースHEADです(CI における凍結されたディスパッチ SHA)。three-dot のマージベース差分ではなく、2 つのエンドポイントのツリーを比較します。収集ベースはコミットを発見するためのものにすぎません。公開済みタグと異なる場合は、そのコミット範囲から漏れているユーザーに見える差分も調査します。- 候補をユーザーに見える挙動ごとにグループ化し、ステップ 2 で除外したコミットも含めて、関連するパッチを時系列順に追跡します。コードから明示的なリバート、手動での取り消し、置き換え、部分的な巻き戻し、再導入を検出します。コミットの文言や一致するハッシュだけに頼ってはいけません。
- このサイクル中に導入され、完全に元に戻された変更は省略します。その一時的な変更のみに対処した修正も含みます。部分的な巻き戻し、置き換え、再導入については、公開済みベースラインと異なる最終的な結果のみを、異なるユーザーに見える変更ごとに 1 回記述します。
- 巻き戻しによって公開済みベースラインにすでに存在していた挙動が削除または変更される場合は、その結果として生じるユーザーに見える削除または復元を記述します。すべてのリバートコミットを無差別に破棄しないでください。同じユーザーに見える挙動を保つ実装の書き直しは、それ自体ではリリースノートの項目を正当化しません。
- 提案された各項目をエンドポイントの差分と最終コードに対して検証し、英語版と中国語版が同じ結果を記述していることを確認します。主張された効果を裏付けられない場合は、それを省略し、リリースノートの主張を捏造するのではなく、準備サマリーでその不確実性を報告します。
推奨フォーマット:
Cherry Studio {version} - {Brief English Title}
✨ New Features
- [Component] Description
🐛 Bug Fixes
- [Component] Description
💄 Improvements
- [Component] Description
⚡ Performance
- [Component] Description
Cherry Studio {version} - {简短中文标题}
✨ 新功能
- [组件] 描述
🐛 问题修复
- [组件] 描述
💄 改进
- [组件] 描述
⚡ 性能优化
- [组件] 描述
言語マーカーは機械可読な契約です。各マーカーを 1 回ずつ含め、順序を保ち、空でない英語と中国語のセクションを提供してください。タイトルと周囲の説明文は提示上の選択であり、検証要件ではありません。 ルール:
- エントリがあるカテゴリのみを含めてください(空のカテゴリは省略します)。
- 残ったユーザーに見える変更はそれぞれ1回だけ適切なカテゴリに記載してください。関連するコミットはまとめ、キャンセルされた項目や置き換えられた項目は省略してください。
- 検証済みの最終的な結果と一致する場合に限り、
release-noteフィールドの文言、またはそれ以外の場合はコミットタイトルの文言を優先してください。 - コンポーネントタグは短くしてください:
[Chat]、[Models]、[Agent]、[MCP]、[Settings]、[Data]、[Build]など。 - 中国語の翻訳は自然なものにし、機械的な直訳にしないでください。
- コミットハッシュや PR 番号を含めないでください。
- 書く前に、
electron-builder.ymlにある既存のリリースノートをスタイルの参考として読んでください。
重要:ユーザー向けの内容のみ
リリースノートは開発者ではなくエンドユーザー向けです。ユーザーが気にしないものは除外してください:
- 除外 内部リファクタリング、コードのクリーンアップ、アーキテクチャの変更
- 除外 CI/CD、ビルドツール、テストインフラストラクチャの変更
- 除外 依存関係の更新(ユーザーに見える機能を追加する場合を除く)
- 除外 ドキュメントの更新
- 除外 開発者体験の改善
- 除外 ユーザーに見える影響のない技術的負債の修正
- 除外 過度に技術的な説明(例:「Redux ミドルウェアの競合状態を修正」)
含める ユーザーが気づく変更のみ:
- ユーザーが使える新機能
- ユーザーのワークフローに影響したバグ修正
- ユーザーが見てわかる UI/UX の改善
- ユーザーが体感できるパフォーマンスの改善
- セキュリティ修正(実装の詳細を含めず、簡略化して)
説明はシンプルで非技術的に:
- ❌「Redux の状態で部分的なツール応答ステータスを引き起こすストリーミングの競合状態を修正」
- ✅「中止時にツールのステータスが停止しない問題を修正」
- ❌「OpenAI 互換プロバイダー向けに reasoning_effort を reasoningEffort へ自動変換」
- ✅「一部のプロバイダーで深い思考モードが動作しない問題を修正」
ステップ 4:ファイルを更新する
package.json:"version"フィールドを新しいバージョンに更新します。electron-builder.yml:releaseInfo.releaseNotes: |の下の内容を生成されたノートに置き換えます。ブロックスカラーの内容に対して4スペースの YAML インデントを維持してください。resources/cherry-studio/release-history.json:手動で編集しないでください。ノートはelectron-builder.ymlとバイト単位で一致している必要があります。node scripts/release/sync-release-history.js --target-version {version}を実行します。これは安定版リリースのエントリを先頭に追加(または置き換え)、プレリリースではファイルを変更しません。GitHub Actions では、ワークフローが Claude のステップの後にこれを自身で実行します。- ソースメタデータを検証する:インタラクティブなローカル実行では、製品マニフェストを生成する前に
node scripts/release/validate-prepared-release.js --target-version {version}を実行し、変更されたパス、バージョンの順序、バイリンガルセクション、または安定版履歴を拒否した場合は停止します。GitHub Actions では、検証は Claude の後に実行されるワークフローステップに任せてください。 - 組み込みナレッジ:インタラクティブなローカル実行では、検証後に
pnpm build:builtin-knowledgeを実行します。これによりresources/builtin-agents/cherry-assistant/product-manifest.jsonが新しいパッケージバージョンで更新されます。生成されたマニフェストを手動で編集しないでください。GitHub Actions では、ジェネレーターを実行しないでください。ワークフローが最初に同じバリデーターを実行し、その後、信頼されたジェネレーターを自身で実行します。
ステップ 5:レビュー用に提示する
ユーザーに表示するもの:
- 新しいバージョン番号。
- 生成されたリリースノートの全文。
- どのファイルが変更されたかの概要。
--dry-run が指定された場合は、ここで停止します。
それ以外の場合は、ステップ 6 に進む前にユーザーに確認を求めてください。
ステップ 6: リリースブランチを作成する
- 対話形式のローカル実行では、ブランチを作成する直前にステップ 1 の項目 1〜3 を繰り返し、
HEAD:package.jsonから元のパッケージバージョンを読み取ります。公開済みのベースラインが、リリースノートの収集に使用したものと依然として一致していることを確認してください。一致していない場合は、続行する前にノートを再生成します。ステップ 4 でリリースメタデータを意図的に準備し検証済みであるため、ステップ 1 のクリーンなワークツリーのアサーションをgit status --shortに置き換え、一覧表示されたすべてのパスが許可された 4 つのリリースメタデータファイルのいずれかでない限り停止します。その後、署名済みで DCO に準拠したリリースコミットを作成してプッシュします:git fetch origin refs/heads/main:refs/remotes/origin/main --tags test "$(git branch --show-current)" = main test "$(git rev-parse HEAD)" = "$(git rev-parse origin/main)" test "$(node -p "require('./package.json').version")" = "{version}" CURRENT_VERSION="$(git show HEAD:package.json | jq -r .version)" LATEST_PUBLISHED="$(gh release list --limit 1000 --json isDraft,publishedAt,tagName --jq '[.[] | select(.isDraft == false and (.tagName | test("^v(0|[1-9][0-9]*)\\.(0|[1-9][0-9]*)\\.(0|[1-9][0-9]*)(-[0-9A-Za-z-]+(\\.[0-9A-Za-z-]+)*)?$")))] | sort_by(.publishedAt) | last | .tagName // empty')" test "$LATEST_PUBLISHED" = "{baseline-tag}" git rev-parse --verify "refs/tags/$LATEST_PUBLISHED" node -e "const semver = require('semver'); process.exit(semver.gte(process.argv[1], process.argv[2]) ? 0 : 1)" "$CURRENT_VERSION" "${LATEST_PUBLISHED#v}" REPO="$(gh repo view --json nameWithOwner --jq .nameWithOwner)" gh api --paginate --slurp "repos/$REPO/releases?per_page=100" | TAG="v{version}" node scripts/release/validate-release-state.js prepare test -z "$(git ls-remote --heads origin refs/heads/release/v{version})" git status --short UNEXPECTED_RELEASE_PATHS="$(git status --porcelain | cut -c4- | grep -Ev '^(package\.json|electron-builder\.yml|resources/cherry-studio/release-history\.json|resources/builtin-agents/cherry-assistant/product-manifest\.json)$' || true)" test -z "$UNEXPECTED_RELEASE_PATHS" git checkout -b release/v{version} git add package.json electron-builder.yml resources/cherry-studio/release-history.json resources/builtin-agents/cherry-assistant/product-manifest.json git commit -S --signoff -m "chore(release): prepare v{version}" git cat-file commit HEAD | grep -q '^gpgsig ' git log -1 --format=%B | grep -q '^Signed-off-by: ' git push -u origin release/v{version} - GitHub Actions では、
package.jsonとelectron-builder.ymlを更新した後に停止します。一時的なヘルパーファイルとローカルの Git 操作は許可されます。ワークフローはこれら 2 つのファイル変更を抽出し、凍結されたソース SHA を復元し、それ以外はすべて破棄します。その後、リリース履歴を導出し、検証し、製品マニフェストを生成し、ブランチを作成し、GitHub の API を使用して署名済みで DCO に準拠したコミットを作成および検証します。Claude のステップからは決してプッシュしないでください。 - リリースブランチと次のステップを報告します。まだ PR は作成しないでください。まずこのブランチからリリースをビルドして公開する必要があります。
CI トリガーチェーン
- 新しい
release/v{version}コミットに対する CI のプッシュ実行が成功するのを待ちます。auto-release-build.ymlはその正確なライブブランチヘッドを再検証し、allを指定してrelease.ymlをディスパッチします。これにより macOS、Windows、Linux がビルドされ、ドラフトの GitHub Release が作成または更新されます。release.ymlを手動で使用するのは、失敗した全プラットフォームビルド、または変更されていないタグ付きコミットの 1 つのプラットフォームを再試行する場合だけにしてください。 - 単一のドラフトのセマンティックバージョンリリースがアクティブな間、
backport-release-fixes.ymlはmainから最初にマージされたhotfix: <description>またはhotfix(<kebab-case-scope>): <description>PR に対してバックポート PR を開き、任意のバイリンガルリリースノートを適用し、その後、連続するホットフィックスとソースマーカーを同じ開いたトピックブランチに追加します。これは各ソース PR のhotfixおよびバックポートステータスラベルを管理し、失敗をソース PR で報告します。mainをリリースブランチにマージしないでください。 - バックポート PR をレビューし、その CI を待ち、マージします。その結果生じたリリースブランチのプッシュが CI を通過すると、正確なヘッドの全プラットフォームドラフト再ビルドが自動的に開始されます。
- 正確なヘッドの全プラットフォームビルドが成功すると、
publish-release.ymlが開始されます。ドラフトを検査した後、releaseEnvironment のデプロイを承認します。その後、公開はリリース状態ロックを取得し、承認された実行、リリースブランチ、タグ、ドラフト、アーティファクト、オープン PR、および保留中のホットフィックスを再検証し、それらが依然として一致する場合にのみ公開します。ドラフトの本文には、バイリンガルのelectron-builder.ymlノートとそれに続く GitHub が生成した変更が含まれます。最後にフェッチされたmainSHA がホットフィックスのカットオフです。そのスナップショットの後にマージされたホットフィックスは次のリリースに属します。公開はpost-release.ymlをトリガーします。これは公開されたタグをソースとして使用し、リリースメタデータの差分のみを最新のmainに適用し、release-sync/v{version}のメタデータのみの PR を作成します。 - メタデータ PR は
package.json、electron-builder.yml、リリース履歴、および生成された製品マニフェストのみを同期します。これはci.ymlをトリガーします。CI が通過した後にのみマージしてください。 - メタデータ PR をスクワッシュマージするときは、コミットタイトルを正確に
chore(release): sync v{version} metadataに設定し、GitHub の任意の PR 番号サフィックスのみを付け、スクワッシュコミット本文の専用行にrelease-metadata-boundary: v{version}を保持して、次のリリースが境界を確実に見つけられるようにします。
制約事項
electron-builder.ymlを変更する前に、必ず読み込んで現在のフォーマットを理解してください。package.json、electron-builder.yml、resources/cherry-studio/release-history.json、および生成されたresources/builtin-agents/cherry-assistant/product-manifest.json以外の変更を保持しないでください。mainに直接プッシュしないでください。- GitHub Release が公開される前にリリースメタデータ PR を作成しないでください。この手順は
post-release.ymlが担当します。 - リリースブランチを作成する前に、生成されたリリースノートを必ずユーザーに提示してください(対話型ユーザーがいない CI で実行している場合を除く)。