はじめに
Gitのブランチ運用はGitflowやGitHub Flowが有名ですが、プロジェクトによって様々なブランチの運用方法があると思います。
ブランチが多くなると管理が複雑になってきて、事故が起こる可能性が増えます。特に、私はいつかマージ先を間違えてしまいそうだなーと思っていました。
そこで、特定のprefixを持つブランチのみマージを許可するやり方を教わったので、こちらにまとめたいと思います。
実現方法
- GitHub Actions上でDanger JSを使用し、プルリクエストのhead branch(変更を加えた取り込みたいブランチ)名をチェックし、適切なブランチ名でなければCIを失敗させる。
- GitHubのブランチ保護ルールで、マージ時にGitHub Actionsのチェックを必須にする。
Dangerとは
Dangerは、プルリクエストの体裁を自動でチェックできるツールです。例えば、
- 変更した行数が規定数を超えていないか
- PRのタイトルに任意の文字列(例えば"WIP")が含まれていないか
- 任意のファイル(例えばCHANGELOG.md)が更新されているか
などをCI上でチェックすることができます。
今回はDangerを使って、プルリクエスト時にブランチ名をチェックして、プレフィックスrelease/
を持つブランチのみをmainブランチにマージできるようにします。
DangerにはRuby版、Javascript版、Swift版があるようですが、今回はJavascript版を使いました。それぞれ文法が異なるようなので、詳しくは公式リファレンスを参照ください。
.github/workflows/ci.ymlの作成
GitHub Actions用のymlファイルを作成します。
設定は以下を参考にしました。
name: Danger
on:
pull_request
jobs:
danger:
name: Danger
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
# dangerのインストールにnode v14以上が必要なので準備
- name: Prepare Node
uses: actions/setup-node@v1
with:
node-version: 18
- name: Install yarn
run: npm install -g yarn
# package.jsonがない場合は作成.ルートディレクトリにある場合は不要.
- name: Initialize yarn
run: yarn init -y
# package.jsonにdangerを追加
- name: Add danger to package.json
run: yarn add danger --dev
# パッケージをインストール
- name: Install danger
run: yarn
# dangerを実行.GitHubリポジトリにアクセスするためGITHUB_TOKENが必要.
- name: Run Danger
run: yarn danger ci
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
dangerfile.jsの準備
プルリクエストのどのような情報をチェックするかはdangerfile.js
に記載していきます。Dangerは自動でルートディレクトリにあるdangerfile.js
を参照するので、作成します。
「プレフィックスrelease/
を持つブランチのみをmainブランチにマージできる」を実現するには、以下のように記述します。
import { danger } from 'danger';
const baseBranchName = danger.github.pr.base.ref
const headBranchName = danger.github.pr.head.ref
if (baseBranchName === 'main' && !headBranchName.startsWith('release/')) {
fail(baseBranchName + ' branch cannot be merged with ' + headBranchName + ' branch.')
}
danger.github.pr
で、プルリクエストに関する情報をもつオブジェクトを取得できます。head.ref
で取り込みたいブランチ名、base.ref
でマージ先のベースブランチ名を取得します。
ベースブランチがmain
かつ、ヘッドブランチがrelease/
で始まらない場合、CIを失敗させます。
CIを失敗させるにはfail()
を呼び出します。引数には失敗時に残すメッセージを記載します。
ブランチ保護ルールの設定
GitHubのリポジトリページのSettings > Branches > Add ruleを選択します。
2つめのRequire status checks to pass before merging
にチェックを入れてCreateボタンをクリックします。
これにて設定は完了です。試しに、mainブランチにfeature/use_danger
ブランチをマージするプルリクエストを作成してみます。
CIが失敗し、図のようにfail()で渡したメッセージがコメントの形で残ります。(何度も失敗した場合は、コメントの編集という形で上書きされていくようです)
今度はブランチ名を変えて、release/
でプルリクエストを出してみます。All greenとなり、マージができるようになりました。
最後に
今回は表題を実現する最小限の設定を行いました。現状dangerfile.js
の文法が間違っているときCIが通ってしまうため、ESLintなどの静的解析もあったほうがよさそうです。
Dangerはブランチ名チェックだけでなく、PRタイトルや変更コード行数などの複雑なチェックを自動化できます。Dangerを使いこなして、レビューを効率よくしていきたいなと思いました。