1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

タグを打ったら回る:GitHub Actionsで“ゆるく”CHANGELOGを自動生成してPRで積む(git-cliff)

Posted at

タグを打ったら回る:GitHub Actionsで“ゆるく”CHANGELOGを自動生成してPRで積む(git-cliff)

個人開発や小規模OSSだと、CHANGELOGを手で書くのってだいたい続かない。
でも「面倒だから」という理由でCHANGELOGが無いままになるより、機械生成でも“だいぶマシ”な履歴が毎回残る方が、あとで効きます。

この記事は、GitHub Actionsで タグ(バージョン)を打った瞬間だけ git-cliff を回して CHANGELOG.md を生成し、その差分を PRとして自動作成してmainに積む、という軽量運用の紹介です。


この記事でやること / やらないこと

やること:

  • v*.*.* のタグをpushしたときだけ(=タグ発火
  • git-cliffCHANGELOG.md を生成
  • 差分を PRとして自動作成してmainに積む

やらないこと:

  • Release本文(リリースノート)を毎回きれいに書く運用
  • Conventional Commits強制など、“ログを整えること自体が目的”になりがちな重いルール

なぜ「タグ発火」がポイントなのか

CHANGELOG更新は「バージョンを付けたとき」だけ起きてほしいです。

普段のpushのたびにCHANGELOGが動くと、

  • 生成PRが乱立して邪魔
  • “まだ出さない変更”まで出力されてノイズ
  • 生成失敗がCIの足を引っ張る

みたいな面倒が増えがち。

タグは「ここをバージョンとして扱う」という明確な合図なので、ここに自動化を寄せるのが一番運用が軽くなります。


全体像(関係あるところだけ)

タグpushで走る最短ルートはこんな感じです。

  1. (前段)Windows/macOSの成果物をビルドしてartifact化
  2. publish-release:artifactをzip化して Release assets として公開
  3. changelog-prgit-cliffCHANGELOG.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なしよりだいぶマシ」を、仕組みで継続できる形にする。
そのための“ゆるい自動化”としておすすめです。

参考

執筆時点での実物はこちら

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?