GitHub で PR 後、CI のテストをパスしたら自動的にマージさせたい。ただし条件付きで。
例えば、特定のファイルが変更された場合のみ自動マージさせるように限定するなど。
例えばリポジトリが、下記の構成だとします。
$ ls
my-script.sh data1.json data2.json run-test-data.sh
このリポジトリに PR(Pull Request)があった場合、テストをパスしてもデータ・ファイルが変更された場合のみ自動マージさせたいのです。この場合 *.json
のデータファイルです。
逆に言えば、CircleCI のテストをパスしてもデータファイル以外、つまり my-script.sh
や run-test-data.sh
などに変更があった場合は自動マージさせないで、レビューさせたいのです。
TL; DR(Automated Merging with Mergify.IO)
自動マージには、マージ処理に特化した GitHub アプリ「Mergify.IO」を利用すると楽。
ただし条件設定に、一工夫が必要。
Mergify.IO の PR 時の条件設定 pull_request_rules
で「変更されたファイル名とファイル数が条件にマッチした」場合にマージさせる設定にします。
-
files
属性に対象となるファイル名を指定 -
"#files=1"
と個数の設定にファイル数を限定
ポイントは、この時に「FILE_A
OR
FILE_B
」と「FILE_A
AND
FILE_B
」の2種類の記述を追加することです。
-
OR
処理(FILE_A OR FILE B
)- 変更を許可したいファイルごとにルールセットを作成します。
-
AND
処理(FILE_A NAD FILE_B
)- 変更を許可したいファイル名すべてを記載したルールセットを作成します。
pull_request_rules:
- name: automatic merge on CircleCI success if data1.json was changed
conditions:
- "status-success=ci/circleci: build"
- base=master
- files=data1.json
- "#files=1"
actions:
merge:
method: merge
strict: true
- name: automatic merge on CircleCI success if data2.json was changed
conditions:
- "status-success=ci/circleci: build"
- base=master
- files=data2.json
- "#files=1"
actions:
merge:
method: merge
strict: true
pull_request_rules:
- name: automatic merge on CircleCI success if data1.json and data2.json was changed
conditions:
- "status-success=ci/circleci: build"
- base=master
- files=data1.json
- files=data2.json
- "#files=2"
actions:
merge:
method: merge
strict: true
TS; DR
Mergify.IOとは
- Mergify.IO オフィシャルサイト
Mergify.IO とは PR 時のマージ操作に特化した CI の1種です。GitHub App として提供されており GitHub Marketplace から追加できます。オープンソースの場合は無料で利用できます。
PR があった場合に「CI のテストをパスし、コードレビューで n 件の承認(Approve)が付いたら自動的にマージさせ、作業ブランチを削除する」といった自動化ができます。
基本的な仕組みはシンプルです。
- PR 時の他のサービスやユーザーの操作から付いたコメントを解析
- コメントが指定された文字列を含んだ場合にトリガー(発動)する
そのため、CI は CircleCI に限らず TravisCI や自作 GitHub App でも条件に追加できます。
少人数で開発されており、まだ若いサービスなので細かいところでドキュメントの情報が足りないのですが、2019/06/11現在、本体エンジンは精力的に開発されています。
Mergify.IO の使い方
- アカウント作成(GitHub アカウントで OAuth ログイン)
- GitHub 上のリポジトリに
.mergify.yml
をアップロード(コミットしてプッシュ) - 別途何か PR をして動作を確かめる
一般的な GitHub App の追加同様、GitHub Marketplace を開き、GitHub アカウントでログイン後、リポジトリに紐づけます。
次に、Mergify.IO の設定ファイルである .mergify.yml
ファイルをリポジトリのルートに置き、一度監視対象のブランチ(master
など)に反映させると、以降の PR で、その設定ファイルにそったマージ操作を行えます。
-
Mergify.IO
の Qiita 記事 @ Google検索
Mergify.IO の使い道
なんでも無条件でマージするのは危険です。悪意あるスクリプトを埋め込まれる可能性もあるからです。
しかし、クリティカルでなく Linter
によるチェックや CI のテストでパスすれば問題がないファイルで、マージ権限のあるメンバーの手をわずらわせたくない場合に重宝します。例えば README.md
の typo だったり、単純なデータの追加などです。
もしくは、レビュー権限のあるユーザーの承認を過半数得た場合にはマージさせるといった具合です。
サンプルを触ってみる
Qiita ユーザとして個人的に興味あるニュース・フィードを集めたリポジトリを用意しました。JSON 形式です。
- リポジトリ: https://github.com/Qithub-BOT/News-Feeds @ GitHub
- ニュース・フィード一覧: list_url_feeds_nice.json
気になる未登録のフィードを見つけたら、このリポジトリを clone
→ 追加 → PR をかけてみてください。以下の条件を網羅した場合、自動的にマージされるようにしました。追加できるフィードの趣旨に同意できるならお触り自由です。
-
*.json
ファイルのみが変更されている。 - 以下の CI のテストをパスした。(validate_json.sh)
- 有効な JSON である。(JSON 構文にミスがない)
- フィードの URL が重複していない。
- 各フィードの登録(要素)の並び順が URL の ABC 順である。
- URL 先のフィードが解析可能な状態である。
- 404 エラーでない。(URL 先が有効である)
- XML/Atom として有効な構文である。
- 非可視文字が含まれていない。
🐒なお、URL 先のフィード(XML/Atom)の構文チェックには、URL を指定すると JSON フォーマットに変換するコマンドを作ったので、正常に JSON 形式で取得できたら
OK
としています。GoFeed-CLI @ GitHub
このリポジトリのポイントは、やはり CircleCI をパスしたら自動マージされる点です。
- files=<FILE NAME>
と対象ファイルを限定し、- "#files=n"
で変更されたファイル数を指定する組み合わせで、特定のファイルのみの変更の条件を作れます。
複数のファイルを指定したい場合、- files=["FILE1", "FILE2"]
といった形式には対応していないので、 - files=<FILE NAME>
を複数個指定します。
また、同じ条件(condition
)内での or
には対応していないのですが、ルールを追加(別々の condition
に)することで or
対応できます。
この方法がわからず、Issue で聞いたら親切に教えてもらったので記事にしてみました。
- Can't merge when "files" condition list is set | #Issue 430 | @ GitHub