TL;DR;
- masterへのマージをリリースとしたので、このタイミングでタグを付けたくなった。
- 手動でやるのは面倒なので、GitHub Actionsで実現した。
前提
- 機能開発をfeature、開発時の統合をdevelop、リリースをmasterブランチで管理している(GitFlowをイメージして貰えれば良い)。
- マージにはGitHubのプルリクエストでを利用
- developからmasterへプルリクエスト
作業フロー
- リリースのタイミングでdevelopからmasterへプルリクエストを生成する
- プルリクのタイトルをバージョン名にする
- 「プルリクのタイトル」=「バージョン名」=「タグ名」となる
- プリリクをマージする
- マージのタイミングで先頭のコミットにタグが付けられる
実現方法
GitHub Actionsを動かすために、以下の2ファイルを配置する。
name: add version tag
on:
pull_request:
branches:
- master
types: [closed]
jobs:
release:
name: add tag
runs-on: ubuntu-latest
if: github.event.pull_request.merged == true
steps:
- name: checkout
uses: actions/checkout@v1
- name: add tag
env:
GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}}
TAG: ${{github.event.pull_request.title}}
REPO: ${{github.repository}}
COMMIT: ${{github.sha}}
run: ./.github/scripts/add-tag.sh
※2020/2/4修正
タグを付けるコミットを ${{github.sha}}l
としていましたが、これだとマージコミットが指定され、マージ元(developブランチ)でタグが見えないので、 ${{github.event.pull_request.head.sha}}
に変更。
参照: Event Types & Payloads # PullRequestEvent
# Add tag to GitHub
curl -s -X POST "https://api.github.com/repos/${REPO}/git/refs" \
-H "Authorization: token $GITHUB_TOKEN" \
-d @- << EOS
{
"ref": "refs/tags/${TAG}",
"sha": "${COMMIT}"
}
EOS
解説
いくつかポイントになる部分の説明を書いておきます。
コード(というか設定ファイル)を見て理解した人は読む必要ありません。
まず、tag-version.ymlはGitHub Actionsのジョブを定義したファイルです。
この部分でmasterブランチへのプルリクがcloseされたタイミングで動くように指定します。
on:
pull_request:
branches:
- master
types: [closed]
ただし、これだとマージ以外の理由でcloseされた場合にも動いてしまうので、このようにしてマージされた場合だけに限定しておきます。
GitHubのCommunity Forumの投稿を参考にしました。
if: github.event.pull_request.merged == true
ここでは、タグを付けるのに使う情報を環境変数にセットします。
secrets.GITHUB_TOKEN
はデフォルトで入っているsecrets情報で、後でタグを付けるGitHub APIを呼び出すのに使います。
github.event.pull_request.title
でプルリクのタイトルを取得し、これをタグ名として使います。
env:
GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}}
TAG: ${{github.event.pull_request.title}}
REPO: ${{github.repository}}
COMMIT: ${{github.sha}}
最終的に、ここでadd-tag.shを実行します。
run: ./.github/scripts/add-tag.sh
add-tag.sh
ではGitHub APIのCreate a referenceを使ってタグを付けています。
GitHub APIドキュメント(Create a reference)
なお、軽量タグではなく、メッセージ付きのタグを付けたい場合はCreate a tag objectを使うと良さそうです。
GitHub APIドキュメント(Create a tag object)
If you want to create a lightweight tag, you only have to create the tag reference - this call would be unnecessary.
とある通り、軽量タグの場合はCreate a Referenceで完結します。