【Elixir】Mix projectにrelease drafterを導入してversion管理を快適に回す
GitHubのリリースノートとタグ管理をするツールにrelease-drafterというものがあります。
内容については以下の記事が分かりやすいです。
この記事ではrelease-drafterをElixirのMixプロジェクトに導入してイイ感じにリリースの管理をする流れを解説してみます。
Goal
画像のように v<major>:<minor>:<patch>
の命名で、FeatureやBugfixでカテゴライズされたリリースノートが生成できるようになるのがゴールです。
以下に検証したリポジトリを置いておきます。何らか参考になれば幸いです。
構築手順
リポジトリを作成済みの状態を前提とします。
labelの作成
- バージョニングに使うラベル(major, minor, patch)
- PRをカテゴライズするラベル(e.g. feature, bugfix, chore... etc)
を用意します。名前や色は自由に設定可能です。GitHub cliを使うとサクッとラベルを作成できます。
$ gh label create major
$ gh label create minor
$ gh label create patch
$ gh label create feature
$ gh label create bugfix
VERSIONファイルの作成・参照
projectのrootにversion番号だけ記載したVERSIONというファイルを作成し、 mix.exs
ではそのファイルを読み込むようにします。外部ファイルに切り出すことで他のシェルスクリプトから読み出すなど扱いやすくなります。
ciの内容をアレンジして、mix.exs
を直で書き換えるというのでも良いと思います。
$ echo -n "0.0.1" > VERSION
0.0.1
- version: "0.1.0",
+ version: File.read!("VERSION"),
release-drafterの設定ファイルの追加
.github/release-drafter.yml
に作成する作成するリリースの設定を記述します。この辺はREADMEを参照してプロジェクトごとにアレンジしましょう。
例.
- tag名とリリース名は
v<major><minor><patch>
とする- e.g.
v1.0.0
- e.g.
- 「Feature」と「Bug Fixes」で分類する
- major, minor, patchというラベルを元に次versionを決定する
name-template: 'v$RESOLVED_VERSION'
tag-template: 'v$RESOLVED_VERSION'
template: |
## Changes
$CHANGES
categories:
- title: '🚀 Features'
labels:
- 'feature'
- title: '🐛 Bug Fixes'
labels:
- 'bugfix'
version-resolver:
major:
labels:
- 'major'
minor:
labels:
- 'minor'
patch:
labels:
- 'patch'
default: patch
release-drafter workflowファイルの追加
draftリリースを作成するworkflowを用意します。PR経由でmainブランチにpushされた際に動作するようにします。
name: Release Drafter
on:
push:
branches:
- main
permissions:
contents: read
jobs:
update_release_draft:
permissions:
contents: write
pull-requests: write
runs-on: ubuntu-latest
steps:
- uses: release-drafter/release-drafter@v5
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
VERSIONファイルを修正後、tagを作り直すworkflowの追加
release-drafterで次バージョンの決定とリリースの作成までは行えるのですが、VERSIONファイルの更新は行えないため、VERSIONファイルの書き換えは別で行う必要があります。
リリースを参照して手動で書き換えるのは手間なので、リリースをdraftから公開したタイミングで以下の作業を行うworkflowを追加します。
- 公開されたリリースのtagを元にVERSIONファイルを更新
- botによって自動commit
- 最新リリースバージョンのタグが新たに作成したcommitを向くようにtagを削除、再作成
- 再作成したタグを紐づけてリリースを公開
name: Bump Version
on:
release:
types: [released]
jobs:
dispatch:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: get latest release
uses: actions/github-script@v6
id: latest-release
with:
script: |
const release = await github.rest.repos.getLatestRelease({
owner: context.repo.owner,
repo: context.repo.repo
});
return release.data;
- name: delete tag
run: |
TAG_NAME=${{ fromJson(steps.latest-release.outputs.result).tag_name}}
git tag -d $TAG_NAME
git push --delete origin $TAG_NAME
- name: create bump version commit
run: |
set -ex
TAG_NAME=${{ fromJson(steps.latest-release.outputs.result).tag_name}}
echo -n $TAG_NAME | sed -e "s/v//" > VERSION
git config user.name github-actions[bot]
git config user.email 41898282+github-actions[bot]@users.noreply.github.com
git add VERSION
git commit -m "bump version"
git push origin HEAD:main
git tag $TAG_NAME
git push origin $TAG_NAME
- name: update release
uses: actions/github-script@v6
env:
RELEASE_ID: ${{ fromJson(steps.latest-release.outputs.result).id}}
TAG_NAME: ${{ fromJson(steps.latest-release.outputs.result).tag_name}}
with:
script: |
const { RELEASE_ID, TAG_NAME } = process.env
await github.rest.repos.updateRelease({
owner: context.repo.owner,
repo: context.repo.repo,
release_id: RELEASE_ID,
draft: false,
tag_name: TAG_NAME
});
これでworkflowの設定回りは完了です。
実際に動かしてみる
リポジトリにpushしてworkflowを動せるようになったら、いくつかPRを作ってみます。
変更例.
- minorをつけたPRをmergeする → minorバージョンの上がったリリースのdraftが作成される
-
feature
ラベルをつけたPRをmergeする →🚀 Features
の配下にPRの内容が記述される
一通り変更が終わったら、リリース画面から「Publish Release」を実行するとbotによってVERSIONファイルを更新したcommitが作られ、そのcommitを指定したtagが作られていればOKです🎉
まとめ
Mix projectにrelease-drafterを導入する流れを解説しました。これをベースに
- Conventional Commitsに基づいてmajor, minor, patchのラベルの付与を自動化するworkflowを用意する
- カテゴリーをさらに細かくする(chore, dependencies, performance, ...)
といったアレンジもプロジェクトに合わせて可能だと思います。
Hexに公開するものであればmix hex.publish
を行う処理も追加してあげれば良い具合にバージョン管理ができると思います。
release-drafterを活用して良きリリースライフを🚀
Discussion