2人目の開発者を迎える前に決めておきたいルール/設定

本記事はQmonus Value Streamの投稿キャンペーン記事です。

## はじめに(対象読者)

今までありがたいことに1人開発体制から開発者を増やしていったり少人数から10名以上に拡大していく過渡期のチームに参画させていただいた経験が何度かあり、その都度ドキュメント整備屋さんのようなことをしてきたのですが、その中で「このルール/設定は最初からあった方がよかったな～」と思うものをピックアップしました。
今まさに1人開発体制からチーム開発体制へ移行しようとしている方、あるいは既に拡大を始めているものの開発者を増やすたびスピードと品質に影響が出ている(気がしている)方の見直し用にもなればいいなと思っています。

またこんなのもあれば便利だったよ～というものがあればコメントなどで教えてください。

## 目次

-  **Git/GitHub関連**
    - ルール
        - ブランチ構成
        - コミットメッセージの書き方
        - Pull Requestの書き方
            - ラベルの使い方
        - タスク管理ツールとの連携方針/方法
    - 設定
        - ブランチ保護
        - リモートリポジトリのアクセス権限
- **開発環境関連**
    - ランタイムのバージョン及びパッケージマネージャーの使用方法
    - リンター/フォーマッター
- **開発ルール**
    - 命名規則
    - ディレクトリ構成
    - テスト戦略/方針

## Git/GitHub関連

Gitおよびホスティングサービスの使い方は後からの変更(主に過去分への遡及)が困難なためできる限り1人のうちに細かいルールや仕組みまで作っておきたいところです。


### ブランチ構成

オリジナルの構成である場合はもちろん、既存のモデルを用いる場合についても「[**git-flow**](https://nvie.com/posts/a-successful-git-branching-model/)を使用します」のような簡素なドキュメンテーションではなく1つ1つのブランチについて使用用途、繋がるブランチ(データフロー)、CI/CDとの関わりなどを定めてまとめます。
特にhotfixについては人によって様々な運用を経験している場合があるので、キチンとルールを決めて余計な認識の齟齬を防ぎましょう。

#### ブランチ名の強制

詳しくは後段の[ブランチ保護](https://qiita.com/nicco_mirai/items/2f28bf32101091f2ab21#%E3%83%96%E3%83%A9%E3%83%B3%E3%83%81%E4%BF%9D%E8%AD%B7)で解説しますが、GitHubの[**Branch Ruleset**](https://docs.github.com/ja/repositories/configuring-branches-and-merges-in-your-repository/managing-rulesets/about-rulesets)を応用してブランチ名のルールを強制することができます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/245527/88b3497b-e358-524c-c4c7-1e410d175808.png)

図: `feature/**/*`という名前に該当**しない**ブランチの作成をRestrict

参考: [**zzzkan.me - GitHubのリポジトリルールでブランチ名を強制する**](https://zzzkan.me/blog/github-branch-naming-policy/)

:::note warn
Organizationの方のRulesetsにこのような項目が追加されていたので将来的にこのやり方は変わるかもしれません。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/245527/ee328bb6-c8ff-36a9-7d96-9eec45cc7f26.png)
:::

### コミットメッセージの書き方

日本語/英語、issueやチケット番号の付与、各プレフィックスの意味など、**誰**が**どの情報**を元に過去の変更を遡りたいのかから逆算してルールを制定しましょう。

これらはメッセージのテンプレートと一緒にまとめ、[**テンプレートリポジトリ**](https://docs.github.com/ja/repositories/creating-and-managing-repositories/creating-a-repository-from-a-template)(モノレポではない場合)の.gitmessageのようなファイルに記載しておきます。

個人的ベストプラクティスとしてissue番号については上記Branch Rulesetでブランチ名にissue番号の付与を強制し、[**hooks**](https://git-scm.com/book/ja/v2/Git-%E3%81%AE%E3%82%AB%E3%82%B9%E3%82%BF%E3%83%9E%E3%82%A4%E3%82%BA-Git-%E3%83%95%E3%83%83%E3%82%AF)でブランチ名からコミットメッセージに番号を転記するような仕組みにするとミスが少なくていい感じでした。

### Pull Requestの書き方

issueやPRもコミットメッセージと同様に型(テンプレート)を定めておくと後でサルベージしやすくなって便利です。
リポジトリの`.github`ディレクトリに`pull_request_template.md`というファイルを用意するとPRを新規作成する際にその内容がテンプレートとして展開されるので、こちらもテンプレートリポジトリに突っ込んでおきましょう。

参考: [**Issueとプルリクエストのテンプレートについて**](https://docs.github.com/ja/communities/using-templates-to-encourage-useful-issues-and-pull-requests/about-issue-and-pull-request-templates)

#### 自動生成リリースノートとラベル

最近GitHubの公式機能として[**リリースノートを自動で生成できるようになりました**](https://docs.github.com/ja/repositories/releasing-projects-on-github/automatically-generated-release-notes)。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/245527/8442d7fa-ff9e-1065-c01b-ca2e91ebd3f8.png)

この際PRのカテゴリ分けにラベルが使用されるので、今からルールを策定する場合はこのあたりも踏まえた上でラベルを作成するとよいです。

### タスク管理ツールとの連携方針/方法

なんらかのツールによってタスクを管理している場合は

- どのようなルールによって
→ ブランチ名にJIRA課題キーを入れる、issueにNotionページへのリンクを貼る…
- GitHub上で見られるどの要素と
→ コミット、PR、issue...
- タスク管理ツール上で見られるどの要素が紐づくのか

という情報をドキュメントにまとめておきましょう。これも公式のドキュメントをぺっと貼るよりは自分の言葉で簡潔にまとめたものを用意する方が読み手にとって優しいです。

なおタスク管理ツール側で公式に連携方法が用意されておらず自分で何らかの仕組みを作らなければいけない場合、管理ツール側からGitHubの要素に飛べるかどうかと**GitHub側から管理ツールの要素に飛べるかどうか**の双方向性を必ず満たすよう注意してください。これがないと、痛い目を、見ます。

### ブランチ保護

ブランチの保護は**必ず**かけましょう。

> "*If it can happen, it will happen.*"

で知られるマーフィーの法則ですが、これを日本語に訳すと

> "フォースプッシュが可能なら、される。"
> "テストの通っていないPRがマージできるなら、される。"

となります。ブランチの保護は必ずかけましょう。

#### Branch Ruleset

[ブランチ名の強制](https://qiita.com/nicco_mirai/items/2f28bf32101091f2ab21#%E3%83%96%E3%83%A9%E3%83%B3%E3%83%81%E5%90%8D%E3%81%AE%E5%BC%B7%E5%88%B6)で少しだけ触れたGitHubの[**Branch Ruleset**](https://docs.github.com/ja/repositories/configuring-branches-and-merges-in-your-repository/managing-rulesets/about-rulesets)は従来あったBranch protection rulesを拡張したもので、大きな違いとして**複数のブランチに同一のルールを設定する**ことが容易になっています。
またリポジトリではなくOrganizationでRulesetを作成することにより全てのリポジトリにルールを適用することも可能となっていますので、[**公式ドキュメント**](https://docs.github.com/ja/repositories/configuring-branches-and-merges-in-your-repository/managing-rulesets/available-rules-for-rulesets)を読んで必要な場所に必要なルールを設定してください。

##### よかったレシピ

・Block force pushes +
・Require a pull request before merging +
・Require status checks to pass

→ ステータスチェック(テストなど)をパスしたPRをマージすることでのみブランチの更新が可能

[**git-flow**](https://nvie.com/posts/a-successful-git-branching-model/)で言う`main`、`release`、`develop`をこのルールで縛り、`feature/*`などその他のブランチには一切の制限をかけないという運用が前述のリリースノート自動生成と相性がよくベネでした。

### リモートリポジトリのアクセス権限

ブランチの保護を保護するためにリモートリポジトリ自体を保護します。

https://github.com/organizations/your_organization_name/settings/member_privileges
からBase permissionsをWrite以下(mainブランチが適切に保護されていれば必ずしもReadである必要はありません)に設定し、
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/245527/de473536-c680-3d46-2348-16997af7c294.png)

https://github.com/your_organization_name/your_repository_name/settings/access
でMaintain以上のRoleを付与したい**チーム**を追加します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/245527/9a4ea21c-357c-26e3-88af-9aaf3b73a150.png)

アクセス管理の基本として権限はユーザーではなくユーザーグループに対して付与するものなので、Add peopleボタンのことは見なかったことにしてください。

## 開発環境関連

開発環境の共有にDocker(コンテナ)を使用するかどうかという話は後からでも問題ないためここでは対象外としています。

### ランタイムのバージョン及びパッケージマネージャーの使用方法

これはREADMEを書こうね、という話です。メジャーなパッケージマネージャーだし使い方は分かるよね？は思わぬ事故の元なのでキチンとREADMEにセットアップ方法を記載してください。

またこれはあるあるなのですが、**自分のバージョン/パッケージマネージャーの使い方が間違っている**、あるいは**レガシーである**場合があります。READMEを書き始める前に今一度自分の知識をアップデートしておきましょう。マネージャーの乗り換えも**今ならまだ間に合います**。

### リンター/フォーマッター

リンターによる制限は人が増えれば増えるほど、コードが積まれれば積まれるほど**厳しい側に倒すことが困難になっていきます**。「できる限り早期」に「最も厳しいルールセット」を「カスタマイズなし」で導入することを強くおすすめします。そこから段々実態にあわせてルール改定していきましょう。

フォーマッターについてもできる限りカスタマイズの余地がないものを導入すると人が増えた際に余計なイデオロギーバトルが発生せずに済みます。おすすめです。

## 開発ルール
### 命名規則

命名についてはGit関連と同様遡及が難しいため初期に方針を策定した方がよいのですが、(プロジェクト固有の命名を除いて)一定以上の正解がないという命名の特性上どこまで書くべきか迷ってしまうことがあります。
そんな時におすすめなのが項目ごとに「必須」「強く推奨」「推奨」などのレベルを記載する手法です。これなら書こうかどうか迷ったものもとりあえず書いておけますし、自分以外の人が規則を更新する際のハードルも下がります。

この手法は後にコーディング規約を作成する際にも用いることができます。

### ディレクトリ構成

ディレクトリ構成について決まりがないまま人を増やすと様々な場所に様々なファイルが散らかって大変なことになります。特に汎用的に使える関数は複数人が作ってしまったり、せっかく作ったのに他の人に使ってもらえないなど悲しい事故が多発するため初期にルールを定めておきましょう。

### テスト戦略/方針

- どのような戦略をもとに
- どのようなテストを
- どのタイミングで実施していて
- 逆にどのようなテストを(意図的に)実施していないのか

あたりの書かれたドキュメントがあると新しく参画した人がテストを書きやすくなります。というかこれがないと書けないので必ず初期に作成しましょう。また

- テストコードと対象モジュールの位置関係
- テストの命名規則

についても事前に決め、あわせて記載しておくとよいです。

## おわりに

こうしてみると「明日から新しい人を入れて一緒にバリバリ開発したい！」を実現するためだけでも結構な量の決めごとをしなければいけないんだなぁと思います。
ですがこれらのルールは1度整えてさえしまえば(定期的にメンテナンスすることを前提に)長きにわたって開発をブーストできるチームの資産となりますので、是非どこかで考えて作ってみてください。

それでは。