8
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

特定のプレフィックスを持つブランチのみマージを許可したい

Last updated at Posted at 2022-10-18

はじめに

Gitのブランチ運用はGitflowGitHub 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ファイルを作成します。

設定は以下を参考にしました。

.github/workflows/ci.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ブランチにマージできる」を実現するには、以下のように記述します。

dangerfile.js
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を選択します。

スクリーンショット 2022-10-19 7.32.27.png

2つめのRequire status checks to pass before mergingにチェックを入れてCreateボタンをクリックします。

スクリーンショット 2022-10-19 7.39.26.png

これにて設定は完了です。試しに、mainブランチにfeature/use_dangerブランチをマージするプルリクエストを作成してみます。

スクリーンショット 2022-10-19 8.01.09.png

CIが失敗し、図のようにfail()で渡したメッセージがコメントの形で残ります。(何度も失敗した場合は、コメントの編集という形で上書きされていくようです)

今度はブランチ名を変えて、release/でプルリクエストを出してみます。All greenとなり、マージができるようになりました。

スクリーンショット 2022-10-19 7.47.36.png

最後に

今回は表題を実現する最小限の設定を行いました。現状dangerfile.jsの文法が間違っているときCIが通ってしまうため、ESLintなどの静的解析もあったほうがよさそうです。
Dangerはブランチ名チェックだけでなく、PRタイトルや変更コード行数などの複雑なチェックを自動化できます。Dangerを使いこなして、レビューを効率よくしていきたいなと思いました。

8
6
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?