おそらくはそれさえも平凡な日々

GitHubのリリースノート自動生成機能からCHANGELOG.mdを生成する

tl;dr

  • GitHubのリリースノート自動生成のAPIを用いてkeep a changelog形式のCHANGELOG.mdを出力するツールを作った
  • gh2changelog -all -unreleased とかで出力
    • 細かいオプションはヘルプ等を参照のこと
    • ghchに引数体系は近いです

本題

GitHubには、リリースノートを自動生成する機能がある。これは、リリース間でマージされたpull requestのタイトルを一覧し、リリース項目としてGitHub Releases上に出力してくれるものです。リポジトリ上に.github/release.yml設定ファイルを配置すれば、pull requestの作者やラベルを元にグルーピングしたり非表示にするといった出力内容のカスタマイズもできる。

このあたりの実際の運用方法については以下のBlog記事を参考にすると良いと思うし、僕も参考にさせてもらいました。

また、r7kamuraさんの記事にも書かれていますが、このリリースノートはAPIからMarkdownを得ることもできます。そして、このAPI出力を、keep a changelog形式に近いMarkdownに変換し、CHANGELOG.mdを出力するgh2changelogというツールを作った。これはtagpr を作る中の副産物で、別ツールとして切り出したものでもあります。

https://github.com/Songmu/gh2changelog

ちなみに、keep a changelog形式は、これもまたr7kamuraさんの記事に書かれていますが、Changelogのガイドラインとして2015年頃に提案され、受け入れられてポピュラーなフォーマットになったものです。参考リンクを載せておきます。

pull requestのタイトルをChangelogに転記するコンセプト

個人的にもともと、Changelogは作りたいが、書く手間をあまり取られたくない、しかしcommit messageを一覧してChangelogするのは粒度がマチマチで見づらくなるし、後から書き換えるのも煩雑になるで避けたい。なのでpull requestのタイトルを一覧してChangelogとするのは良い落とし所だと考えていました。

実際、そのコンセプトを実現するためにghch というツールを以前作り、今でも活用しています。ありがたいことに200 starsを超え、僕のOSSの中では代表的なものになっています。

そして、冒頭に書いたGitHub公式のリリースノート生成機能は去年追加されたのですが、これも既に書いたとおり、まさにpull requestのタイトルベースでChangelogを生成するものでした。

公式がそういう機能を出してきたのであれば乗るのが正道であり、そこで作ったのがgh2changelogです。なのでghchの一部機能の後継ツールでもあります。

.github/release.ymlでのカスタマイズも嬉しい点で、keep a changelog形式で提案されているAdd, Changed, Deprecatedといったタイプ別に、ラベルを用いたカテゴリ設定を記述すれば、理想的なCHANGELOG.mdを出力できます。

ちなみに、gh2changelogは敢えてのkeep a changelog形式決め打ちの出力であり、ghchはJSON出力もできて自由度が高いツールです。コンセプトが異なるため、完全にgh2changelogghchを置き換える訳ではありません。

CHANGELOG.md欲しい?

GitHub Releasesが熟れてきたし、そっちのリリースノートに更新内容が書いてあれば、もはやCHANGELOG.mdを配置する必要は無いし、むしろ二重管理になるのも困るという意見は正しいと思います。

なので、CHANGELOG.mdを配置するというのは僕個人のちょっとしたこだわりでしかないとも思います。ただ、以下のような利点から配置するようにしています。自動生成する分には二重管理の問題も解消されているので。

  • ある機能がいつ入ったのかを調べるときに一つのファイルにフラットに記述されていると検索性が高くて嬉しい
  • CPANやgem, tarball等にパッケージングする際にはChangelogを同梱したい

ということで、私同様にChangelogが好きな方は、一度gh2changelogをご利用いただけると嬉しいです。

created at
last modified at

2022-09-08T01:15:26+0900

comments powered by Disqus