はじめに
developブランチからfeatureブランチを切って、featureブランチで開発をした後にdevelopへPRを投げるブランチ戦略は割と多い気がします。
しかし、feature以外のブランチからdevelopにPRを誤って送ってしまった場合、PRの承認者が誤ってマージしてしまう可能性もあると思います。
運用面で回避できればいいのですが、可能であればシステム的に対象のブランチからしかPRを受け付けないように制限を入れたいです。
本記事はこちらの方法について記載します。
ゴール
GitHub Actionを使用しdevelopブランチへのプルリクエストは、プレフィックスに「feature」がつくブランチからしか受け付けないように制限する。
前提
デフォルトブランチをmainとして、main⇒develop⇒feature/○○ブランチを作成している状態を想定しています。
featureブランチの名前について
featureはdevelopからfeature/hoge1、feature/hoge2などそれぞれブランチを切る場合、一意なブランチ名とはならないと思います。
プレフィックスに「feature/」がついてるのが特徴なので、正規表現で「feature/○○」といったブランチ名を検知したいです。
正規表現
次の正規表現でfeature/
で始まるブランチ名を検知します。
^feature/.*
- ^: 行の先頭
- feature/: "feature/" という文字列
- .*: 任意の文字列が続く
ソース(ymlファイル)
以下はdevelop.ymlファイル全体のコードになります。
name: CI
on:
pull_request:
types: [opened, reopened]
branches:
- develop
jobs:
cicd_test:
name: feature_to_devlop
runs-on: ubuntu-latest
steps:
- name: Check:if PR is from feature to develop branch
run: |
if [ "${{ github.event.pull_request.base.ref }}" == "develop" ] && [[ "${{ github.event.pull_request.head.ref }}" =~ ^feature/.* ]]; then
echo "Pull request from feature to develop branch"
else
echo "Pull request not from feature to develop branch, exiting with code 1"
exit 1
fi
◆ 詳細
if文の条件としては、PRが featureからdevelop ブランチに向けられている事を設定しています。
この条件が満たされた場合、GitHub Actionのワークフローのステータスチェックは成功し、
条件に当てはまらない場合はelseに入り、ステータスチェック処理を失敗させます。
if [ "${{ github.event.pull_request.base.ref }}" == "develop" ] && [[ "${{ github.event.pull_request.head.ref }}" =~ ^feature/.* ]]; then
echo "Pull request from feature to develop branch"
else
echo "Pull request not from feature to develop branch, exiting with code 1"
exit 1
fi
Branch protection rulesの設定
developブランチに対するブランチの保護ルールを設定していきます。
テキストボックスにジョブ名を入力し、動かす対象のジョブを選択します。
実行
developブランチに対して、以下の2つのパターンを検証してみます。
- errortestブランチ⇒developブランチへのPRを送付
- feature/○○ブランチ⇒developブランチへPRを送付
◆1. errortestブランチ⇒developブランチへのPR
PRを出してみると以下の通り、ステータスチェックで弾く事ができました。
errortestブランチは、ブランチ名がfeature/○○ではないのでこの結果は想定通りです。
◆2. feature/test1ブランチ⇒developブランチへPR
PRを出してみると以下の通り、ステータスチェックを通す事ができました。
feature/test1ブランチは、ブランチ名がfeature/○○に当てはまっているのでこの結果は想定通りです。
参考