【NE-WG】GitHub branch 保護

# 前置き
私は[こちら](https://dev.classmethod.jp/tool/github/protect-branch/)を見て大体の仕様は学びましたが、やっぱり使って見ないとわからないのと、どういう場合に使えるのとかがあった方がわかりやすいかと思って個人的なメモとして残します。

# ブランチ保護設定画面への遷移方法
![スクリーンショット 2019-12-08 15.29.05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/547491/954a6fb5-5935-7a33-50f9-9b090f085f12.png)
上記画面で、Setting(上タブ) -> Branches(左タブ)を押下すれば上記の画面になります。
下の方にある Add rule ボタンで設定可能です。

え？上の方にある ZenHubタブが気になるって？よくぞ気づいてくれました！GitHub使うならZenHubリンクさせておくとスクラム開発めっちゃ便利なツールなんですよ〜…あー機会があればまたお話しします。というより早くZenHub導入しろ。

# ブランチ保護設定画面(上)
![スクリーンショット 2019-12-08 15.27.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/547491/2d3430f3-94f3-3498-1fda-2e23db13740d.png)
画面が大きいのでまずは上の画面から。説明の都合上、すでに設定しておいてあるもので説明します。まあ、検証用なんで設定方法は適当ですが・・・。

## Branch name pattern
ここに保護して欲しいブランチ名を書きます。昔は選択式だったような気がします。GitHubはコロコロ仕様が変わるので臨機応変に対応ですね〜。

で、見て分かる通り「*」を使うことにより部分一致するブランチに共通の設定をすることが可能です。例えば

- release/1.0
- release/1.1
- release/2.0
- release/3.0

のブランチを同様の保護設定したければ、枠の中に

- **release***

と打てばいいんですね。簡単ですね〜。設定すると以下のようになります。まあ、featureブランチは共通設定することはないと思いますが・・・
![スクリーンショット 2019-12-08 15.44.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/547491/4a038abd-d7f8-8e38-0bab-1af444af928e.png)

# ブランチ保護設定画面(中)
![スクリーンショット 2019-12-08 15.52.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/547491/58dbd7fb-64fc-99eb-309d-3d9c41943ea1.png)

## Protect matching branches
ここからが本格的な設定画面です。外枠の説明は[こちら](https://dev.classmethod.jp/tool/github/protect-branch/)に任せるとしてメインは具体例を記載します。

### Require pull request reviews before merging
よくある現場の事象・・・
A：おい誰だ勝手に結合したの！
B：私知りません。
C：俺しらね。
D：僕もわからないですね。
~ 10分後 ~
A：ログ見たらBじゃねえか！ふざけるな！
B：そ、そう言われても心当たりが・・・
A：◯◯時◯◯分に結合したことになってるんだが？！
B：本当にわからないんです。
C：(GitHub初心者なんだからミスぐらいあるだろ普通)
D：(ある程度どうしてこうなったか分かるけど、
　　これGitHubの詳細まで知っていても普通誰でもミスると思うけど・・・)
上記の大半はこの保護で片付きます。

#### Dismiss stale pull request approvals when new commits are pushed
上にある**Required approving reviews:**とセットで使います。これは人数指定ができまして、**指定人数が結合許可を出さなければそのブランチに結合させなくすること**ができます。

上記の会話の例では対象となるbranchが保護されておらずその結果Bが誤って結合してしまい事故が起きています。Bにしてみれば、「別のブランチを指定していたはずが・・・」とか「pushする場所を正しく指定した・・・」とかあるかも知れませんが、所詮は人間はミスります。

ここで、ちゃんと保護されていればおそらく結合する前にAあたりが気づくはずなので後の祭りにならずにすみます。

#### Require review from Code Owners
次に以下の事象の時はどうでしょう。
B：できましたー！！
A：見せてみろ。あー、まあいいんじゃね。結合するわ。
~ 20分後 ~
D：すいません。更新箇所を取り込んだらバグって動かなくなりました。
C：見せてみ？うんにゃ？これはBさんの修正箇所だわな。
B：え、あ・・・すいません。Aさんから許可をもらったんで・・・
A：あ？それぐらい自分で気付けや！
B：ううう・・・
D：(ところで、Aってそこまでこの開発言語知識あったっけ？)
C：(いや、この言語は結構最新のだからおそらくねえな。俺が見ときゃよかったか。)

言語や技術力によって、得意不得意があるので適正外の方が結合許可を出すのは良くないです。そんな時にこれを使います。
![スクリーンショット 2019-12-08 16.33.40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/547491/29780888-5847-9ffc-ed10-7f007ef88f4c.png)
プロジェクト上から .github/ フォルダを作って、中に**CODEOWNERS**ファイルを作成します。書き方は以下を参照してください。

```
# Lines starting with '#' are comments.(<- # 列はコメント！)
# Each line is a file pattern followed by one or more owners.
 
# These owners will be the default owners for everything in the repo.
# (全ファイルを特定のユーザチェック必須にするには以下のように書きます。)
# (*だけで全ファイルを意味します)
*       @Sempu-Mizuha @Sempu-Momomi
 
# Order is important. The last matching pattern has the most precedence.
# So if a pull request only touches javascript files, only these owners
# will be requested to review.
# (特定のファイルのみを特定のユーザチェック必須にするには以下のように書きます。)
*.js    @octocat @github/js
 
# You can also use email addresses if you prefer.
# (特定のフォルダのファイル指定も可能です。ユーザーはメールアドレスでもOK)
docs/*  docs@example.com
```

#### Restrict who can dismiss pull request reviews
ところで、以下のようになったらどうしますか？
A：おい！誰だよこの結合拒否出したの！
B：あ、はい。確か、私のレビューをEさんにお願いしたんです。
D：Eさんって凄い技術者だったよね。
B：はい！いっぱい成長できました！
A：うんなんはどうでもいいんだよ！今いねえんだろ！結合できなきゃ仕事進まないだろ！
C：(Setting 弄れよ)

Cの発言はさておき、職場では色々あり担当者がいなくなるなど日常茶飯事です。上記の場合Eさんがチームに復帰するまで結合不能で詰みます。

そこでこの機能を設定し、ユーザー(例えばAさん)を設定することにより設定されたユーザー(例えばAさん)は結合拒否をキャンセルさせることができます。

ただし、対象のリポジトリで管理者権限以上を持っていれば態々自分のユーザーを設定しなくてもこの項目にチェックがついているだけで結合拒否をキャンセルできます。

### Require status checks to pass before merging
超簡単に説明すると、自身でオリジナルのチェック方法を設定できるというものです。ただ、設定方法とかは滅茶苦茶面倒臭いので割愛します。第一、設定しなくても十分ブランチを保護できます。

#### Require branches to be up to date before merging
デフォルトのチェックとして上記のものがついています。これは、結合したいブランチが結合先のブランチで更新された内容を取得しているかチェックするものです。古すぎるブランチほど結合先の最新情報を取得していない可能性が増えるのでこのチエックで引っかかるようになります。

作ったブランチは出来るだけ早く取り込めるようにタスク内容を切り分けることが必要になってきます。

# ブランチ保護設定画面(下)
![スクリーンショット 2019-12-08 17.44.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/547491/a449bf2a-5994-c7c4-3d8b-677fd3ecf1c7.png)

### Require signed commits
コミット時、デジタル署名をしなければコミットできません。余程、セキュリティ特化でもない限り利用しません。

### Require linear history
プルリクエスト時以下の3パターンの結合方法がありますが、一番上**merge commits**の方法をrejectします。

- ~~merge commits~~
- squash merging 
- rebase merging 

詳細の説明は[こちら](https://help.github.com/ja/github/administering-a-repository/requiring-a-linear-commit-history)に投げますが結合履歴が一番複雑になる結合方法をrejectすることにより結合履歴を管理しやすくします。最近追加された要素みたいです。

### Include administrators
ブランチ保護の適応範囲に管理者も含めさせます。

### Restrict who can push to matching branches
以下の揉め事を回避できます。
D：おっと、僕のブランチのコミット履歴にBさんの名前が入っているね。
B：え？私、自分のブランチにコミットしたと思ったのですが・・・
A：おい、pushする時にはちゃんとブランチ確認しろって言っただろ！
B：ご、ごめんなさい・・・
C：(普通に考えて毎回毎回いちいち確認してられっかっての！)

ここを有効にした上で、ユーザー名を指定することにより、ブランチにpushできるユーザーを指定できます。登録されていないユーザーがpushしようとするとrejectされます。

## Rules applied to everyone including administrators
簡単に説明すれば、このブランチに対し強制プッシュやブランチ削除可能にするものです。今回は保護とは逆の判断なので割愛。

# まとめ
他のサイトでも似たような説明は結構ありますが、どう言った場面でどのように活用するのかがよくわからなくて結局取り入れないというのが帝石な感じがしたのでメモとして記載してみました。

どっかの他のシステムや資産管理とは違い最低限のものは結構簡単に設定できるので、出来るだけ利用して頂きより利便性よくそして犯人探しという罪のなすり合い付けが起きないことを祈っています。