タグを打ったら回る:GitHub Actionsで“ゆるく”CHANGELOGを自動生成してPRで積む(git-cliff)
個人開発や小規模OSSだと、CHANGELOGを手で書くのってだいたい続かない。
でも「面倒だから」という理由でCHANGELOGが無いままになるより、機械生成でも“だいぶマシ”な履歴が毎回残る方が、あとで効きます。
この記事は、GitHub Actionsで タグ(バージョン)を打った瞬間だけ git-cliff を回して CHANGELOG.md を生成し、その差分を PRとして自動作成してmainに積む、という軽量運用の紹介です。
この記事でやること / やらないこと
やること:
-
v*.*.*のタグをpushしたときだけ(=タグ発火) -
git-cliffでCHANGELOG.mdを生成 - 差分を PRとして自動作成してmainに積む
やらないこと:
- Release本文(リリースノート)を毎回きれいに書く運用
- Conventional Commits強制など、“ログを整えること自体が目的”になりがちな重いルール
なぜ「タグ発火」がポイントなのか
CHANGELOG更新は「バージョンを付けたとき」だけ起きてほしいです。
普段のpushのたびにCHANGELOGが動くと、
- 生成PRが乱立して邪魔
- “まだ出さない変更”まで出力されてノイズ
- 生成失敗がCIの足を引っ張る
みたいな面倒が増えがち。
タグは「ここをバージョンとして扱う」という明確な合図なので、ここに自動化を寄せるのが一番運用が軽くなります。
全体像(関係あるところだけ)
タグpushで走る最短ルートはこんな感じです。
- (前段)Windows/macOSの成果物をビルドしてartifact化
- publish-release:artifactをzip化して Release assets として公開
-
changelog-pr:
git-cliffでCHANGELOG.md生成 → PR作成
coverage/pages等は今回の主役じゃないので省略します(やってるけど“CHANGELOG自動化”の話とは別)。
“頑張らないRelease”の実態:成果物置き場としてのRelease
この構成だと、Releaseは「頑張って書くもの」というより 配布物(assets)を置く場所になります。
- 配りたいのはWindows/macOSのzip
- その置き場としてRelease assetsが便利
- なのでRelease本文を作り込むより、assetsを確実に載せるのを優先
ReleaseにCHANGELOGを反映しない理由(外部APIなしの軽量運用)
Release本文まで自動で綺麗にしたい気持ちはあります。ChatGPT等のAPIを使えば、差分の要約やテンプレ整形、そこからRelease本文への転記まで含めて自然に自動化できます。
ただ今回は、次の要件を優先しました。
- 外部APIに依存しない(APIキー管理を増やさない)
- Secretsを増やさない(壊れる要因を増やさない)
- 生成が失敗しても“配布”は止めない(成果物公開を最優先にする)
その結果、Releaseはassets中心の“雑運用”に割り切り、CHANGELOGはPRで確実に積む構成にしています。
(反映したくなったら、要約/転記を別レイヤーで足すのが現実的です)
実装:タグ発火でRelease assetsを公開する
今回の要はここで、タグpushのときだけ走る publish-release job が、成果物zipをRelease assetsへ載せます。
トリガー(タグ発火)
on:
push:
branches:
- main
tags:
- 'v*.*.*'
workflow_dispatch:
そしてRelease公開のjobはタグのときだけ。
publish-release:
if: github.event_name == 'push' && github.ref_type == 'tag'
Releaseが“生える”理由(この1ステップ)
- name: Publish GitHub Release assets
uses: softprops/action-gh-release@a06a81a03ee405af7f2048a818ed3f03bbf83c7b # v2.5.0
with:
files: |
rogue-finder-windows-${{ github.ref_name }}.zip
rogue-finder-macos-${{ github.ref_name }}.zip
tag_name: ${{ github.ref_name }}
name: ${{ github.ref_name }}
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
ここが「artifactsをpublishするためにReleaseが作られてる」ポイントです。
Release本文を頑張ってないのにReleaseが存在するのは、assetsを載せる都合でこのステップが Release作成/更新を兼ねているから、というわけです。
本題:タグを打ったらCHANGELOGを生成してPRを作る
PR方式にした理由
PR方式にしてよかった点は2つあります。
1) 再生成が容易(タグ付け直しでリカバリできる)
出力が気に入らない・生成が失敗した、みたいなときに「手で直す」より、タグを打ち直して再生成できる方が圧倒的に楽です。
2) 運用が安全
mainに直書きせず、PRで差分が見えるので、レビュー/修正/破棄が簡単です。「機械が書いたものをそのまま本流へ」は心理的にも事故りやすいので、PRを挟むのがちょうどいい。
実装(changelog-pr job)
タグのときだけ git-cliff を実行して CHANGELOG.md を生成し、PRを切ります。
changelog-pr:
name: Update Changelog
runs-on: ubuntu-latest
needs:
- publish-release
if: github.event_name == 'push' && github.ref_type == 'tag'
env:
CHANGELOG_TOKEN: ${{ secrets.CHANGELOG_TOKEN }}
Secretsが無いときはスキップ。個人開発だと「とりあえず動く」ことが大事なので、この逃げ道があると気が楽です。
- name: Skip when CHANGELOG_TOKEN is missing
if: env.CHANGELOG_TOKEN == ''
run: |
echo "CHANGELOG_TOKEN secret is not configured; skipping changelog PR job."
exit 0
履歴とタグが必要なので fetch-depth: 0。
- name: Checkout
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1
with:
fetch-depth: 0
git-cliff を入れて生成。
- name: Install git-cliff
uses: taiki-e/install-action@93ceae2e597c99cd0cbe22fe4c781b198c42e93e
- name: Generate changelog
run: git cliff -c cliff.toml -o CHANGELOG.md
最後にPR作成。
- name: Create changelog PR
uses: peter-evans/create-pull-request@c5a7806660adbe173f04e3e038b0ccdcd758773c # v6.1.0
with:
token: ${{ env.CHANGELOG_TOKEN }}
commit-message: "docs: update changelog for ${{ github.ref_name }}"
branch: chore/changelog/${{ github.ref_name }}
base: main
title: "docs: update changelog for ${{ github.ref_name }}"
body: |
Automated changelog update for `${{ github.ref_name }}`.
Triggered from tag `${{ github.ref }}`.
add-paths: |
CHANGELOG.md
ここまでで「タグを打つ → CHANGELOG更新PRが生える」が完成です。
git-cliff のデメリット(正直セクション)
git-cliff は機械生成なので、入力(git log / PRタイトル)が荒いと出力も荒れます。
- 試行錯誤コミットが大量
- コミットメッセージが「wip」「fix」「tmp」だらけ
- PRタイトルが雑
みたいな運用だと、CHANGELOGが“読める情報”になりづらいです。
対策:squash merge で“素材”を整える
この手の自動生成は 1 PR = 1 変更のまとまり に寄せると一気に読みやすくなります。
「行数を減らす」というより、履歴の意味の粒度を整えるのが効きます。
(個人開発でも、merge方法をsquash寄りにするだけで体感が変わります)
それでもこの方式を推す理由(= ないよりだいぶマシ)
手書きCHANGELOGが更新されずに“空”になるより、多少雑でも毎回積み上がる方が役に立ちます。
- 完璧な運用は続かない
- でも「タグを打ったら勝手にPRが出る」なら続く
- 改善したくなったら、squash運用や
cliff.tomlを育てればいい
この順番が、個人/小規模にはちょうどいいです。
まとめ
- タグを打った瞬間だけ自動化を動かす(普段の開発を邪魔しない)
- Releaseは成果物置き場として割り切り、CHANGELOGはPRで担保
- PR方式は 再生成が楽(タグ付け直しでリカバリできる)
「CHANGELOGなしよりだいぶマシ」を、仕組みで継続できる形にする。
そのための“ゆるい自動化”としておすすめです。
参考
執筆時点での実物はこちら