Claudeで顧客向けリリースノートを書く — GitHubの自動生成を元に
GitHubが自動生成するPR一覧から、社内用語と課題番号を除いた顧客向けの案内を起こす手順です。release.ymlでの絞り込み、claude -pでの変換、対象顧客の切り分けまで扱います。
GitHubの「Generate release notes」が作るのは、マージされたPRの一覧です。開発者には役に立ちますが、顧客に送れる文面ではありません。PRタイトルには社内用語や課題番号が混ざり、顧客から見た影響も書かれていないからです。
この記事では、自動生成された一覧を材料にして、Claudeに顧客向けの案内を起こさせる流れを組みます。手順は4つです。
.github/release.ymlで、顧客に関係しないPRを一覧から先に落とす- 生成された本文をコマンドで取り出す
- 変換ルールを固定した状態でClaudeに渡す
- 対象顧客を決め、人が確認してから送る
自動生成の一覧には何が入るのか
自動生成されるのは、マージ済みPRの一覧、そのリリースに貢献した人の一覧、変更履歴全体へのリンクの3つです。手書きの代わりに「リリースの中身の概観」をすばやく作るための機能で、顧客への説明文を作る機能ではありません。
つまり、顧客向けに直す作業の入力は次のように決まります。
- PRタイトルがそのまま項目になる(タイトルの書き方が文面の質を決める)
- 貢献者のログイン名が並ぶ(顧客に見せる情報ではない)
- 変更履歴へのリンクが付く(開発リポジトリが非公開なら顧客は開けない)
リポジトリが非公開で顧客が閲覧権限を持たない場合、最後のリンクは案内文から外します。この判断はClaudeに任せず、変換ルールに明記しておくと抜けません。
release.ymlで顧客に関係しないPRを先に落とす
Claudeに渡す前の段階で、依存パッケージの更新や内部リファクタリングのPRを一覧から外せます。設定は .github/release.yml に書きます。使えるパラメータは次のとおりです。
| パラメータ | 役割 |
|---|---|
changelog.exclude.labels | 役割このラベルが付いたPRを一覧から除く |
changelog.exclude.authors | 役割このユーザー・ボットのPRを一覧から除く |
changelog.categories[*].title | 役割カテゴリの見出し(必須) |
changelog.categories[*].labels | 役割カテゴリに入れるラベル(必須)。* は残り全部を受ける |
changelog.categories[*].exclude.labels | 役割そのカテゴリからだけ除くラベル |
changelog.categories[*].exclude.authors | 役割そのカテゴリからだけ除くユーザー・ボット |
顧客向けの案内を前提に組むと、たとえば次のような設定になります。ラベル名はリポジトリごとに決めるもので、ここでは internal と customer-visible を使います。
# .github/release.yml
changelog:
exclude:
labels:
- internal
- ignore-for-release
authors:
- dependabot
categories:
- title: 新機能
labels:
- enhancement
- title: 不具合の修正
labels:
- bug
- title: 利用に影響する変更
labels:
- breaking-change
- customer-visible
- title: その他
labels:
- "*"ここで押さえたい点が2つあります。
ラベルのないPRは「その他」に流れます。 * を置いたカテゴリは、前のカテゴリに当てはまらなかったPRをすべて受けます。ラベルを付ける習慣がないリポジトリでは、一覧の大半がここに集まります。その場合はカテゴリ分けを諦めて、exclude.authors でボットのPRだけ分ける構成のほうが現実的です。
除外はラベル運用に依存します。 internal を付け忘れたPRは一覧に残ります。だからこそ、次の工程でClaudeにも「顧客に関係しない項目は落とし、落とした項目を別に列挙する」よう指示しておきます。二重に網を張る形です。
生成した本文をコマンドで取り出す
ブラウザの「Generate release notes」ボタンで作ったものをコピーしてもかまいません。繰り返し使うなら、REST APIで本文だけを取り出すほうが楽です。
POST /repos/{owner}/{repo}/releases/generate-notes は、リリースの名前と本文(Markdown)を返します。返された内容はどこにも保存されません。リリースを作る前の下書き用という位置づけです。主なパラメータは次のとおりです。
tag_name(必須): 今回のタグ。既存でも新規でもよいprevious_tag_name: 比較の起点にする前回のタグ。範囲を手動で決めたいときに使うtarget_commitish: タグがまだ無いときの対象ブランチconfiguration_file_path: 設定ファイルの場所。省略すると.github/release.yml(または.yaml)を使い、無ければ既定の設定になる
GitHub CLIの gh api を使うと、認証付きで呼べます。-f でパラメータを渡すとメソッドは自動でPOSTになります。
gh api repos/OWNER/REPO/releases/generate-notes \
-f tag_name=v1.4.0 \
-f previous_tag_name=v1.3.2 \
--jq .body > raw-notes.mdすでに公開済みのリリースから取り出すなら、gh release view の --json body が使えます。取得できるフィールドには body、name、tagName、publishedAt などがあります。
gh release view v1.4.0 --json body --jq .body > raw-notes.md変換ルールをファイルに固定してClaudeに渡す
毎回プロンプトを書き直すと、リリースごとに文面の調子が変わります。ルールを1つのファイルにまとめ、claude -p の --append-system-prompt-file で追加するのが安定します。-p は非対話で実行するフラグで、標準入力を受け取れます。
ルールファイルの例です。社内の事情に合わせて書き換えて使います。
# customer-notes-rules.md
あなたはSaaSの顧客向け更新案内の編集者です。入力はGitHubが自動生成したリリースノートです。
## 書き換えの規則
- PR番号、課題番号、ブランチ名、ログイン名、社内のコードネームは出さない
- 項目ごとに「顧客は何ができるようになるか」「何を変える必要があるか」の順で1〜2文にする
- 入力から読み取れない影響は推測しない。判断できない項目は末尾の「要確認」に理由つきで集める
- 顧客の操作や契約に関係しない項目(依存更新、内部リファクタリング、テスト)は本文に入れず、「除外した項目」に列挙する
- 敬体で書き、「最適化」「強化」のような中身のない形容は使わない
## 出力の構成
1. 件名案(1行)
2. 新機能
3. 不具合の修正
4. 利用に影響する変更(必要な操作を含む)
5. 要確認
6. 除外した項目実行は次の1行です。標準入力に流したテキストが、プロンプトの材料になります。
cat raw-notes.md | claude -p \
--append-system-prompt-file ./customer-notes-rules.md \
"この一覧を、規則に従って顧客向けの更新案内に書き換えて" \
> customer-notes.mdCIなどで毎回同じ結果を得たいときは --bare を足します。CLAUDE.md やフック、MCPサーバーの自動読み込みを省くので、誰の環境で動かしても同じ条件になります。ただし --bare ではサブスクリプションのログインを使わないため、ANTHROPIC_API_KEY の設定が前提です。手元で試すだけなら付けなくて構いません。
claude -p のオプション全般はclaude -pオプションとはで扱っています。
書き換えの一例
PRタイトルをそのまま使った状態と、規則に沿って書き換えた状態の差は、おおよそ次のようになります。以下は規則の効果を示すために作った例で、実際の出力はリポジトリの内容とルールの書き方で変わります。
PRタイトルから顧客向けの項目へ
自動生成された一覧
* PROJ-482 invoice-svc の N+1 を解消 by @dev-a in #1031
* feat: Sakura 基盤の CSV エクスポートに文字コード選択を追加 by @dev-b in #1040
顧客向けの項目
請求書一覧の表示が速くなりました。件数の多いアカウントで読み込みの待ち時間が短くなります。
CSVエクスポートで文字コードを選べるようになりました。Excelで文字化けする場合は、設定画面の「文字コード」で切り替えてください。
2つ目の項目にある「設定画面の『文字コード』」は、入力のPRタイトルには書かれていません。ここがClaudeに任せきれない部分です。画面上の名称や操作手順は、PRの説明文や仕様書を一緒に渡すか、人が補います。規則に「入力から読み取れない影響は推測しない」と入れているのは、この補完を勝手に作らせないためです。
影響する顧客を絞る
顧客向けの案内でもう1つ手間がかかるのが、「この変更は誰に関係するか」の切り分けです。PR一覧には顧客の情報が含まれないため、Claudeに対象を当てさせることはできません。代わりに、社内の対応表を一緒に渡し、「どの項目がどの区分に当たるか」を判定させます。
| 機能の領域 | 対象になる顧客の区分 |
|---|---|
| 請求書・支払い | 対象になる顧客の区分請求書機能を有効にしている全プラン |
| CSVエクスポート | 対象になる顧客の区分標準プラン以上 |
| API | 対象になる顧客の区分API連携を契約している顧客 |
| 管理者画面 | 対象になる顧客の区分管理者権限を持つ利用者のみ |
この表を audience.md として保存し、先ほどのコマンドに足します。
cat raw-notes.md | claude -p \
--append-system-prompt-file ./customer-notes-rules.md \
--append-system-prompt "$(cat audience.md)" \
"各項目の末尾に【対象:区分名】を付け、表に当てはまらない項目は【対象:要確認】にして" \
> customer-notes.md区分ごとに別の案内を送るなら、できあがった文面を区分で振り分けるだけで済みます。表に載っていない領域の変更は【対象:要確認】として残るので、担当者が判断する対象がはっきりします。表の内容はプランの改定のたびに古くなるため、リリースのたびに見直す前提で管理します。
送る前に人が見る場所
GitHubの手順にも、生成された内容が「入れたいものすべてと、入れたいものだけ」になっているか確認する工程があります。顧客向けに書き換えた後も、同じ確認が要ります。見る場所は次のとおりです。
- 数値や日付、プラン名が元のPRと合っているか
- 「要確認」に集められた項目の判断が済んでいるか
- 「除外した項目」の中に、顧客に影響するものが紛れていないか
- 必要な操作(設定変更、再ログインなど)が漏れていないか
- 変更履歴へのリンクなど、顧客が開けない参照が残っていないか
とくに3つ目は見落としやすい箇所です。内部リファクタリングに見えるPRが、実はAPIの応答形式を変えていることがあります。除外の判断をClaudeに任せたぶん、除外された一覧を人が一度は通読する運用にしておくと安全です。
GitHubのリリース本文と顧客向け文面は分けておく
gh release edit の --notes-file を使えば、既存リリースの本文をファイルの内容で置き換えられます。ただし、これはリリースページの本文を書き換える操作です。開発者向けの記録と顧客向けの案内は読み手が違うので、顧客向けの文面は customer-notes.md のまま、メールやお知らせ、ヘルプセンターなど顧客が実際に見る場所へ別に載せるほうが混ざりません。
公開リポジトリの場合は、リリース本文を顧客向けの文面で上書きすると、PR番号や貢献者の情報が消えて開発側の履歴としては不便になります。置き換えるかどうかは、リリースページを誰が読んでいるかで決めます。
タグが打たれたら自動で下書きまで進める
手順が固まったら、GitHub Actionsでタグの作成をきっかけに実行できます。実行基盤の設定や認証はGitHub Actionsのワークフロー作成をClaude Codeで進める手順に沿います。ここで決めておきたいのは、自動化の範囲です。
- 自動でやるのは「生成」と「下書きの保存」まで
- 顧客への送信は、人が確認してから手動で行う
ワークフローの出力は、プルリクエストのコメントや成果物として残し、承認者が見られる形にしておきます。顧客に届く文面を無人で送る構成は、「要確認」の項目が出たときに止められないので避けます。
障害や不具合のお詫びを含む案内は、通常のリリースとは文面の考え方が違います。その場合はClaudeで障害のお知らせ文とサポート想定問答を作るの手順が合います。新製品や大きな機能の発表文はClaudeでプレスリリースの文面を下書きする手順を参照してください。
つまずきやすい点
一覧が空、または少なすぎる。 previous_tag_name を省くと、起点のタグはGitHubが自動で選びます。意図した範囲にならないときは、前回のタグを明示します。
カテゴリが「その他」に偏る。PRにラベルが付いていません。ラベル運用が無いなら、カテゴリ分けはClaude側の規則(「新機能」「不具合」「その他」への分類)に任せたほうが早く済みます。
設定ファイルの場所が違う。省略時に読まれるのは .github/release.yml か .github/release.yaml です。別名で置いたときは configuration_file_path で指定します。
文面が毎回違う。ルールをプロンプト本文に直接書いていると、書き方のゆれがそのまま出ます。--append-system-prompt-file でファイルに固定し、そのファイルをリポジトリで管理すれば、変更履歴も残ります。
まとめ
GitHubの自動生成は「何がマージされたか」の整理までを担い、顧客への翻訳はその先の工程です。入口で release.yml により内部向けのPRを落とし、中間でルールを固定してClaudeに書き換えさせ、出口で人が対象顧客と数値を確かめる。この3段に分けると、各段の責任がはっきりします。
最初に手を付けるなら、customer-notes-rules.md を1本作るところが効きます。直近のリリースの一覧を1つ通してみると、規則に足りない禁止事項が数個見つかるはずです。それを足していくうちに、リリースごとの手直しが減ります。