v2.1.0 のリリース準備をしていたとき、ふと「自分はどれくらい時間をリリースノート作成に使っているんだろう」と思いました。
Beautiful HD Wallpapers は iOS / Android 合わせて30カ国以上でユーザーがいるため、リリースノートは最低でも日本語・英語の2言語で書く必要があります。大きなリリースになると、修正内容をまとめる作業だけで1〜2時間かかることもあります。累計5,000万DLを超えたアプリとはいえ、1人で開発・運営しているので、この時間のロスは正直きついと感じていました。
そこで試したのが「git log から Gemini API を使ってリリースノートを自動生成する」という方法です。
なぜ git log なのか
コミットメッセージは、何を・なぜ変えたかを最も正確に記録した一次情報です。v2.1.0 の開発中、RecyclerView の IndexOutOfBoundsException クラッシュ、Glide 5.0.5 の coreLibraryDesugaringEnabled 対応、戻るボタンの広告ゲート再設計など、変更の意図はコミットメッセージに書いてありました。
これを Gemini API に渡してリリースノートに変換するのは、まとまった文脈を持つ構造化されたテキストを別の形式に変換するという作業なので、LLM が得意とする領域です。
公式ドキュメントには書いていませんが、コミットメッセージのように箇条書きの断片的なテキストでも、十分な量があれば Gemini API はユーザー向けの文章に適切に変換してくれます。実際に試して、この点は予想以上に精度が高かったです。
開発者向けの内部ログをユーザー向けの言葉に変換するプロセスは、以前なら自分の頭の中で手動でやっていたことです。「IndexOutOfBoundsException を防御的コピーで修正」という技術的な表現を「壁紙一覧の表示が安定しました」というユーザー向けの言葉に翻訳する作業は、毎回それなりの思考コストがかかります。それを Gemini に委ねることで、リリース作業のテンポが変わりました。
実装:Python スクリプト
スクリプト全体は50行以内でまとまります。git log でコミットメッセージを取得し、Gemini API に渡してJSON形式のリリースノートを返してもらうシンプルな構成です。
import subprocess
import os
import json
import google.generativeai as genai
genai.configure(api_key=os.environ["YOUR_GEMINI_API_KEY"])
model = genai.GenerativeModel("gemini-2.5-flash")
def get_git_log(from_tag: str, to_ref: str = "HEAD") -> str:
"""タグ間のコミットメッセージを取得する"""
result = subprocess.run(
["git", "log", f"{from_tag}..{to_ref}", "--pretty=format:%s%n%b", "--no-merges"],
capture_output=True,
text=True
)
return result.stdout.strip()
def generate_release_notes(commits: str, version: str) -> dict:
"""コミットログからリリースノートを生成する"""
prompt = f"""以下は Android アプリ v{version} のコミットメッセージ一覧です。
ユーザー向けのリリースノートを日本語と英語で生成してください。
条件:
- 技術的な内部実装の詳細は書かない(「壁紙一覧の表示が安定しました」のように体験ベースで)
- ユーザーが体験として感じられる変化のみを書く
- 箇条書き3〜5項目でまとめる
- 出力は JSON 形式で、キーは "ja" と "en" のみ
コミットメッセージ:
{commits}
JSONのみ出力してください(コードブロック不要):"""
response = model.generate_content(
prompt,
generation_config=genai.GenerationConfig(
response_mime_type="application/json"
)
)
return json.loads(response.text)
if __name__ == "__main__":
commits = get_git_log("v2.0.0")
notes = generate_release_notes(commits, "2.1.0")
print("=== 日本語 ===")
print(notes["ja"])
print("\n=== English ===")
print(notes["en"])ポイントは response_mime_type="application/json" の指定です。以前はプロンプトの書き方だけで JSON を強制しようとしていましたが、Markdown コードブロックが混入して json.loads() が失敗することがありました。この設定を追加してからはその問題がほぼなくなっています。Gemini 2.5 Flash を選んでいるのは、このような変換タスクには十分な品質があり、コストも抑えられるためです。
v2.1.0 での実際の出力
実際に試したコミットメッセージ群(約40件)から生成されたリリースノートの日本語版はこういった内容になりました。
・壁紙の読み込みで稀に発生していたクラッシュを修正しました
・Android 6.0 以降の端末での表示不具合を改善しました
・カテゴリ切り替え時のレスポンスが向上しました
・画面上部のスライドショーをよりスムーズに調整しました
・一部のアニメーション表示を最適化しました
手書きとの比較でいうと、「クラッシュを修正」という内容は自分でも同じように書きます。一方「Android 6.0 以降の端末での表示不具合」という言い方は、コミットメッセージには技術的な修正内容を英語で書いていましたが、Gemini がユーザー向けに適切に意訳してくれました。この変換精度は予想以上でした。
気になった点と対処
コミットメッセージの品質に依存する
コミットメッセージが雑だとリリースノートも雑になります。fix bug や update のような一行コミットが多いとほぼ変換できません。v2.1.0 では意識して変更の背景を書くようにしていたので、精度が出やすかった面があります。このスクリプトを使い始めてから、コミットメッセージを丁寧に書く習慣がついたのは副産物として良い効果でした。
技術用語の除去が不完全なケースがある
40件のコミットの中に1〜2件、クラス名のような技術用語がそのまま出力に残ることがありました。プロンプトに追加の制約を入れるか、出力後に正規表現で除去する後処理を加えるのが現実的です。私は現状、生成後に一度目視確認してから貼り付けるワークフローにしています。完全自動化するより、最後に人間の目が入る方が安心できると感じています。
コミット数が少ないと出力が薄くなる
バグフィックスのみの小さなリリースで3〜5件のコミットしかない場合、箇条書きが1〜2行になることがあります。この場合は複数リリース分のコミットをまとめて渡す方法が有効です。
モデル選定:Gemini 2.5 Flash で十分な理由
このスクリプトには Gemini 2.5 Flash を使っています。リリースノートの生成は、コミットメッセージという構造化された入力を、ユーザー向けの定型的な形式に変換するタスクです。深い推論よりも語彙の適切な選択と翻訳精度が求められるので、Flash で十分な精度が出ます。
Pro を使うとコストが5〜10倍に跳ね上がりますが、出力の品質差は体感ではほとんどありませんでした。個人開発のように月に何十本ものリリースをするわけではないので、今後もこの判断を維持するつもりです。コミット数が100件を超えるような大規模リリースでも、Flash のコンテキストウィンドウは問題なく対応できます。
今回のタスク規模では、API の呼び出し回数は1回で完結します。生成に数秒かかりますが、手書きで1〜2時間かけていたことを考えると大幅な改善です。2014年から個人開発を続ける中で感じてきた「小さな自動化の積み重ねが長期的な持続可能性を作る」という考え方の延長として、このツールもその一つです。
Play Store / App Store への連携と多言語化
生成されたリリースノートは、そのまま Google Play Console や App Store Connect の「新機能」欄にコピーして使えます。多言語対応まで自動化したい場合は、出力した日英テキストをさらに Gemini API で追加言語に翻訳するステップを繋げると30言語以上にも対応できます。この方法については Gemini API で iOS/Android アプリのメタデータを30言語自動生成した実装 で詳しく書いています。
次のリリースでは、GitHub Actions のワークフローに組み込んで、タグを切ったタイミングで自動的にリリースノートのドラフトを生成する仕組みにしようと考えています。個人開発者が1人で複数アプリを維持していく上で、こういった小さな自動化の積み重ねが開発リソースを守ることにつながります。
まず手元のリポジトリでスクリプトを動かしてみてください。直前のタグからのコミットを渡すだけで、すぐに結果が確認できます。
試してみると、自分のコミットメッセージがいかにユーザー向けの言葉に変換しにくいかに気づく場面があるかもしれません。それ自体が、日頃のコミット習慣を見直すきっかけになります。個人開発において、1人でコードを書き続けながら品質を保つことは、外部からの視点を取り入れる機会が少ないぶん難しさがあります。このような小さなツールが、間接的にコードとコミュニケーションの質を上げる助けになれば嬉しいです。同じ課題に取り組んでいる個人開発者の参考になれば幸いです。