GitHubを楽しく使おう

# なにこれ
普段お世話になっているgithubをもっと便利に使うために思っているところを雑に書く。
会社でまとめた内容が割とウケが良かったので知見の棚卸し。

# 設定編
## ブランチの保護（削除対策編）
人間はミスをする生き物です。
「うっかりミス」が発生することがままあるでしょう。
でも、そんな「うっかりミス」のせいで、稼働中のサービスにデプロイやCI/CDしているブランチを消してしまった場合、大変マズイことになります。
サービスの規模や時間によるとは思いますが、ちょっと前の職の例ではホットタイムだと**毎秒n万円の損失**が発生することになるので冗談抜きでマズイことになります。

ということで、間違って消しちゃうことがないように重要なブランチは保護してあげましょう。

### やり方
* 保護したいブランチのgithubページを開く
* `Settings` > `Branches` > `Protected branches`を開く
    * `Branch protection rules` と出ている場合は `Add rule` ボタンを押せばOK
    * 認証ページに飛ばされた場合はパスワードを入れる
* `Apply rule to` というところで保護したいブランチを指定
![image.png](https://qiita-image-store.s3.amazonaws.com/0/287363/3bb13dcc-d7ad-2d9f-c0fb-d1baff897781.png)
* 一応この段階でブランチの保護はOK。「うっかりミス」は最低限防げるはず

## ブランチの保護（未レビューなプルリクエストのマージ対策編）
削除に対しての保護は上の対応で基本的にはOKです（やろうと思えばこれでも消せるけど）。
ただ、ブランチは削除だけでなく、危険なマージからも保護しないといけません。

### やり方
ブランチの保護設定画面で`Protect matching branches`の下に`Require pull request reviews before merging `という項目があります。
これはプルリクエスト（以降：PR）のマージをする際に、**レビュアーからの承認をもらっていない場合はマージできなくする**という保護設定です。
これを設定すると、PRの画面で
<img width="788" alt="スクリーンショット 2018-09-06 1.18.43.png" src="https://qiita-image-store.s3.amazonaws.com/0/287363/fe84ca76-a4ec-becc-e9d9-13f95e87af20.png">
というようにCircleCIのチェックとは別に、マージにロックをかけてくれます（CircleCI使ってない場合は項目が2個になります）。
承認要求人数や必須承認者（この人の承認がないとロック）の設定、コミットがあるたびに再承認を要求するなどの設定で、よりきめ細かな承認ルールを定義できます。

### 余談
開発の優先度やチーム内の指針で利用するかどうかが決まってくる内容だとは思いますが、僕個人としては`レビュアー：1名`の設定がベターかなと思っています。

* チーム開発の場合、ここの設定が0名は基本的には無しかなーと思ってます。
    * だったらPR出さないでマージしちゃいなよって思っちゃいます。
    * エビデンス残すためっていうのはわかるけど
* ここが2名以上になると開発速度が落ちていきます（承認待ちになりやすくなるので）
    * というか多人数になればなるほど、なぁなぁでマージすることが多くなるので、多人数は逆に製品の品質が落ちていくような気がしています
    * その昔、必要承認数3だった時、PRが永遠にマージされない現象が起きて爆死したことがあります

その他にも細かい設定ができるので調べてみて、チーム内でルール策定ができるといいと思うよ。

## ブランチの保護（master直push対策編）
そうなんですよね。
githubは強制mergeは防げるけど、直pushは防げないんですよね・・・。
ということで以下を参考に。
FYI: [特定ブランチのgit push origin masterを禁止する](https://qiita.com/justin999/items/5f0f3daaf6cd4882f9cf)

要は

* 保護したい対象の`.git`フォルダにhook用のファイルを作成
* 保護したいブランチを指定
* **各個人が各々設定する必要がある**

という内容。
最後が特に重要。

対応としては、以下のような感じにすればOKです。
必要に応じて対象を増やしたり減らしたりしよう。

```shell
$ cat "プロジェクトディレクトリ"/.git/hooks/pre-push
#!/bin/bash

while read local_ref local_sha1 remote_ref remote_sha1
do
  if [[ "${remote_ref##refs/heads/}" = "master" ]]; then
    echo "Do not push to master branch!!!"
    exit 1
  elif [[ "${remote_ref##refs/heads/}" = "develop" ]]; then
    echo "Do not push to develop branch!!!"
    exit 1
  fi
done
```

---

# テンプレート編
githubはPRやissueにテンプレートを入れることができます。
これを導入することで

* 毎回PRやissueで文言や項目を考えるのが面倒
* メンバー個々人に任せたりすると、人によって説明の粒度がばらつき出る
* ある程度放置されたPRを見たときに、なんのための修正・更新なのかが理解できなくなる
 * ~~そもそもPRが放置されている事象自体が異常事態とかいうツッコミはさておき~~

という問題が解決され、ある程度製品の品質が保たれます。
是非入れましょう。

## やり方
テンプレートを入れたいブランチに`.github`というフォルダを作成。

* **PULL_REQUEST_TEMPLATE.md**：PRのテンプレート
* **ISSUE_TEMPLATE.md**：issueのテンプレート
* CONTRIBUTING.md：Contributeのテンプレート（社内開発だとあまり出番ないかも？）

を作成。以上。

ここで書いたMarkdownがそのままPR / issue作成時に埋め込まれます。
サンプル：
<img width="512" alt="スクリーンショット 2018-09-06 11.58.33.png" src="https://qiita-image-store.s3.amazonaws.com/0/287363/983338e5-9643-f6ee-cdea-f2b32382d1d2.png">
超便利。
そのなかで必要なものだけ使えばいいと思う。
例： https://github.com/mochisuna/issue-template-sample/pull/1

ちなみに、テンプレートは複数用意することもできて、要件に合わせて切り替えるなんていう運用もできてしまう！！！
FYI: [GitHub の Issue Template を複数設定して使い分ける](https://qiita.com/suzuki-hoge/items/04de7d779bed6572bb99)
ありがたやー。

### 個人的な見解
* 実装の背景・目的
* やったこと

は基本的に欲しい項目。

PRを出してまで機能を作成したということは、そこに至る背景（もっと言えばニーズ）があるはずなので、レビューする側からすれば「なんのためにこれやったんですか？」ということを説明して欲しいところです。
下手に省略するよりも、最終的にはその方が効率的です。
ただ、毎回書くと、それはそれで手間というのはわかるのでチーム内で方針が共有できてればいいんじゃないかなぁ・・・。

後は**緊急時対応で承認待ってられない場合どうするのか問題**はありますね。
おそらく設定を一時的に外してもらう形になるのかなぁ・・・。
緊急時だからしょうがない・・・よね？
~~・・・というかそんな自体が頻発する場合は何かがおかしい。
ちゃんとレビューしてって話になる。~~

# ブランチ運用編
個人的にはほぼ2択だと思っています。
FYI：[git flowとgithub flowとは？その違いは？](https://qiita.com/mint__/items/bfc58589b5b1e0a1856a)

* git flow
* github flow

個人的な見解としては（雑すぎて色々ツッコミもらいそうだけど）、

* **開発を早めてガンガンリリースしていきたい場合はgithub flow**
* **ある程度製品ができてきたらgit flow**

という使い分けかなー？って思ってます。
CCIでCI/CDすることを考えるとgit flowの方が何かと安全な気がしている（ここは気のせいな可能性が高い）。

後、branchにも命名規則があった方がいいですね。

* feature/hogehoge
* bugfix/hogehoge
* hotfix/hogehoge

とかで、「なんのための開発なのか」を明記するように名前付けしてあげると

* どういう意図でブランチを切ったのか
* どのブランチが優先度高いのか

などがわかりやすくなるので大変good。
ちなみに末尾を`/`にしておくとgit clientによってはディレクトリ形式で解釈してくれるので、ちょっとイケメン。

# プルリクエスト編
ここに関してはチームの文化次第な側面が多いと思います。

* PRのタイトルにprefixとして`[WIP]`、`[IR]`、`[Bugfix]`という文言をつけてステータス管理
* PRラベルでステータス管理
* 男気一本、つうと言えばかあで解決

・・・など。
なので、個人的にはラベルで管理したい気持ちがあるけれど、一概に`これがいい`とか`こうじゃないとだめ`とかは深く掘らないようにします。
チームで話し合って決めましょう。

なんにせよ一律して言えることは

* **マージ済みのブランチは必ず消す**
* **PRは基本的にマージするか棄却する**
  * どちらもしないで放置するのは一番ダメ

というルールはあった方がいいですね。
マージ済みのブランチを消さずに放置した結果、**名前の重複**や**似た名前のブランチを間違って`checkout`**しちゃったり、
出したPRを誰も見ないでずっと放置した結果、**PR同士がコンフリクトしまくる**、あるいは**そもそも状況が変わってPR自体が不要になる**ことがあるので・・・。

必要なものだけ残そうぜ！

## 個人的に良いと思ったルール
### 生煮えPR
ここの資料でも言及されてるルールです
FYI: https://speakerdeck.com/ken_c_lo/pull-request-4-designers-githubwoshi-tutapuroguramatodezainafalseitereteibunakai-fa-huro?slide=11

要点としては、

- 機能的には不完全だけど早い段階でPRとして出してしまう
- 「こういう風にしたいけどどうする？」みたいなのを議論しながら進める
- 早い段階で進め方レベルでの間違いや方針について修正できる

といったもので、内容がふわっとしているものや技術的に難しいもの、規模が大きくなりそうなものなどを進めるにあたり便利です。
コードの進め方に困った際にも有用で、よく使っています。
`[WIP]`という接頭語をPRに入れるかタグを用意しちゃうのが良い感じある。

### コメントルール
コメントを入れる際に、どういう意図なのかを接頭語で書いてしまうやり方です。
FYI: [英語のコメントや issue で頻出する略語の意味 (FYI, AFAIK, ...)](https://qiita.com/uasi/items/86c3a09d17792ab62dfe)
・・・よく考えたらこのFYI自体が該当しますね。

何を思ってのコメントなのかが明確になるのでとってもよさみが深い。
特に、このコメントは `ただの文句じゃないよね？` とか、 `僕ならこうするよ` みたいなのを自分で確認してから投稿できるのがいいなと思います。

余談というかどうでも良い内容ですけど、僕の場合

* imo
* MUST
* ask
* nits
* FYI

がよく使うワード。
なぜか大文字小文字がごちゃまぜ。
統一しよ・・・。

---

# 拡張を入れてもっと良い感じに使いたい編
正直これが言いたかった。

## Octotree
今回紹介する商品はこちら、[`Octotree`](FYI:https://github.com/buunguyen/octotree)。
階層状にブランチを表示してくれる。

例：普段お世話になってる[Karabiner-Elements](https://github.com/tekezo/Karabiner-Elements)様の場合
![samplekara.png](https://qiita-image-store.s3.amazonaws.com/0/287363/d600f304-fa8c-b146-4e3d-c8ef93342f41.png)


しかも、PRの場合は差分があるファイルだけ出してくれる。
<img width="512" alt="スクリーンショット 2018-09-06 12.25.57.png" src="https://qiita-image-store.s3.amazonaws.com/0/287363/02200d72-39c8-812e-2b4f-6677fd7645ab.png">

とっても便利！
<img width="128" alt="img.png" src="https://qiita-image-store.s3.amazonaws.com/0/287363/8a6b9735-27bf-4ac4-3918-f11b237e523c.png">

## Refined GitHub
続いてこちら、[`Refined GitHub`](FYI:https://github.com/sindresorhus/refined-github)。

GitHubの表示をいい感じに変えてくれたり、追加機能として直近マージされたブランチのPRを出せたりするようになります。
機能が多く、詳しくはREADMEを見た方が良いのですが、とりあえず痒いところに手が届きまくるので大変便利。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/287363/ece649b3-bc23-23a5-6bd6-6cd54a1e6909.png)

↑アイコンも可愛い。

余談：PRマージ後のブランチ削除はOSSのアプリでもあったりします
FYI: [Delete merged branch](https://probot.github.io/apps/delete-merged-branch/)

# その他
## Activity overview
（2018年9月現在）[最近追加された機能](https://blog.github.com/changelog/2018-08-24-profile-activity-overview/)です。
その人がgithub上でどんなことをやってきたのかを４種類のデータでグラフ化してくれます。

* Code review
* Issues
* Commits
* Pull requests

どれが伸びてると良いとかではなく、その組織においてどういう貢献をしているかが重要かなと思っています。
僕の場合、本業では

![スクリーンショット 2018-09-06 14.33.46.png](https://qiita-image-store.s3.amazonaws.com/0/287363/00153f74-2505-c280-91ee-c8c7d3307cc0.png)
レビューしないおじさん。

別の組織では、
<img width="271" alt="スクリーンショット 2018-09-06 14.34.44.png" src="https://qiita-image-store.s3.amazonaws.com/0/287363/c930ced5-47a0-ae66-7db2-56d9b63ae187.png">
文句ばっかりおじさん。

みたいなのがよくわかります。

# まとめ
* githubはとっっっっっても便利。だからもっと便利に使おう。
* `運用で頑張る`は頑張れない未来しか待っていないので、人間の手が介在しにくい運用フローがいいですよね。
* 拡張とかテンプレとか、使えるもんは使ったもん勝ち。


# 参考・引用した記事
- [特定ブランチのgit push origin masterを禁止する](https://qiita.com/justin999/items/5f0f3daaf6cd4882f9cf)
- [GitHub の Issue Template を複数設定して使い分ける](https://qiita.com/suzuki-hoge/items/04de7d779bed6572bb99)
- [git flowとgithub flowとは？その違いは？](https://qiita.com/mint__/items/bfc58589b5b1e0a1856a)
- https://speakerdeck.com/ken_c_lo/pull-request-4-designers-githubwoshi-tutapuroguramatodezainafalseitereteibunakai-fa-huro?slide=11
- [英語のコメントや issue で頻出する略語の意味 (FYI, AFAIK, ...)](https://qiita.com/uasi/items/86c3a09d17792ab62dfe)

ありがとうございます。
抜け漏れあったらごめんなさい。