経緯
現状では、Tagがpushされたタイミングで自動ビルド&リリースが走るようになっているのですが、その際にリリースの説明にCHANGELOG.md
の差分を表示したいと思い作ってみることにしました。
サンプル
前提条件として、Releaseに上げているときのTagがv*
である必要があります。
また、Release以外のときにTagが追加された場合や、GitHub Actions が実行されたタイミングでTagが無い場合では正常に動きません。(差分がTagが作成された地点からの差分になるため)
以下のサンプルはリポジトリ直下にCHANGELOG.md
があるのを想定したサンプルです。
on:
push:
tags:
- "v*"
jobs:
release:
runs-on: ubuntu-latest
steps:
- name: checkout
uses: actions/checkout@v2
with:
fetch-depth: 0
- name: Get diff from CHANGELOG
run: |
BEFORE=`git describe --tags v${GITHUB_REF#refs/*/v}^^`
echo 'CHANGELOG<<EOF' >> $GITHUB_ENV
git diff -u $BEFORE CHANGELOG.md | grep ^+ | grep -v ^+++ | sed s/^+// >> $GITHUB_ENV
echo 'EOF' >> $GITHUB_ENV
- name: Create release
uses: softprops/action-gh-release@v1
with:
tag_name: ${{ env.RELEASE_VERSION }}
name: Release ${{ env.RELEASE_VERSION }}
body: ${{ env.CHANGELOG }}
draft: false
prerelease: false
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
実際の動き方
最初の状態
まずCHANGELOG.md
はこのようになってます。
そしてTagも設定しておきます。
CHANGELOG.md を更新してコミット
このようにCHANGELOG.md
を2回のコミットにわけてTagv1.1.0
を付与してPushします。
すると
このように GitHub Actions が走り
CHANGELOG.md
の差分で追加されたところだけがReleaseのメッセージに表示されました。
躓いた点や解説
サンプルを元に躓いた点と解説などを書いていきます。
過去のタグやコミットログが取得出来ない
これは GitHub Actions にてチェックアウトする際に、最新分しかfetchしていないためです。
その為チェックアウト部分を下記のようにすることで解決できました。
- name: checkout
uses: actions/checkout@v2
with:
fetch-depth: 0
これでチェックアウト時にすべて fetch するようになりました。
現在のTagの1つ前のTagを取得する
これが以外と情報が少なくて手こずりました。
サンプルでは
BEFORE=`git describe --tags v${GITHUB_REF#refs/*/v}^^`
が該当する箇所です。
まず、${GITHUB_REF#refs/*/v}
で現在のTagを取得しています。ただこれはv*
の*
部分だけしか取得出来ないのでv${GITHUB_REF#refs/*/v}
にしています。
そしてgit describe
でTagを取得するのですがその際に現在のTagの後ろに^^
を付ける事で過去のTagを取得出来ました。
環境変数に複数行の出力結果を書き込む
まず、環境変数を出力する方法なんですが、これはドキュメントに書かれているように
run: echo "{name}={value}" >> $GITHUB_ENV
で環境変数を更新することが出来ます。
なので下記のように書いてみました。
echo 'CHANGELOG=`diff -u $BEFORE CHANGELOG.md | grep ^+ | grep -v ^+++ | sed s/^+//`' >> $GITHUB_ENV
しかし、このように書くと下記のようなエラーが出てしまい、複数行出力することが出来ませんでした。
Error: Unable to process file command 'env' successfully.
Error: Invalid environment variable format '
なので下記のようにしました。
echo 'CHANGELOG<<EOF' >> $GITHUB_ENV
git diff -u $BEFORE CHANGELOG.md | grep ^+ | grep -v ^+++ | sed s/^+// >> $GITHUB_ENV
echo 'EOF' >> $GITHUB_ENV
どうやらEOFが無いのが原因だったみたいです。
さいごに
これで自動リリース時に、前回リリース分のCHANGELOG.mdとの差分で追加された部分がリリースメッセージに表示されるようになりました。
CHANGELOGの生成も自動化することで、もっと手間を減らせると思います。
また、もっとよい方法など有れば教えていただければ幸いです。