はじめに

こんにちは matinana です。 CAMPFIRE Ownersという融資型クラウドファウンディングでサービス開発を行っています!

この記事は**CAMPFIRE Advent Calendar 2020**の 21 日目の記事です。

アドベントカレンダーも終盤戦に入りましたが、CAMP の記事の中にはゲーム要素を含んだ**走る!音が出る!HTML でミニゲームをつくりました**など面白い記事が沢山ありますのでぜひこの機会に覗いてみてください!

本記事の目的

チーム開発に関して全く知らなかった約一年前の自分が、一年間のチーム開発を通して学んだ態度や tips をまとめることで、

  • チーム開発の流れの理解
  • チーム開発に必要になりそうな態度の一案を提示

上記を行い、これからチーム開発を始める人の不安を払拭する一助になることを目的にしています。

書こうと思った動機(当時の私)

私が CAMPFIRE に入社したのは昨年の 11 月です。 独学でいくつかのアプリを作っていましたが、プログラミングの業務や他の人とチーム開発することは未経験でした。

そのため、当時の自分は github でブランチを分けての開発などもほぼしたことがなく、

  • 使ったことがある git コマンドといえばgit pushのみ (addcommitは vscode でポチッと出来た)
  • GitHub Flowどころかプルリクエストの作成も使ったことがない

上記のような、チーム開発のtの字も知らない(チですらない…)状態でした。

チーム開発一年目というのは、エンジニアとしてもきっと一年目。 目の前の山積みの問題にしっかりと向き合えるように、チーム開発の雰囲気を掴み取ってもらい、闇雲に生まれてしまう不安を軽減できればと考えています。

話さないこと

✕ 開発〜プルリクエスト作成までの基本的な git のコマンドについて

こちらは@shh-nkmr さんが書いてくださっているgit 初学者の初めてのチーム開発で気をつける事の備忘録にまとまっています。 開発〜プルリクエスト作成までの基本的な git コマンドに自信がない場合はこちらをご参照ください。

✕ 具体的なコードの書き方やリファクタのコツなどに関して

私も知りたいです 😂 笑 残念ながらこれらは対象外です。

目次

  • 基本的なチーム開発の流れの整理
  • 課題や仕様の整理
  • 実装
    • git blame を活かす
    • 実装のスコープを意識する
    • コミットメッセージにプレフィックスをつける
    • rebase でコミットを整理する
  • PR 作成
    • 気になることは全部コメントで書く
    • PR を小分けにする
    • 動作確認をしっかりする
  • レビュー
    • 疑問点を投げるのも大切なこと
    • 良いと思った部分は言葉にして良いと言う
    • 悪い点を指摘するのではなく、相手の理解が進む形で投げるようにする
    • nits IMO MUST などのレビューコメントにラベルをつけてみる
  • 本番反映
  • あとがき

基本的なチーム開発の流れの整理

GitHub Flow どころかプルリクエストの作成も使ったことがない

前述のように一年前の自分はこのレベルだったので、まずは基本的なチーム開発の流れだけをさらっと見てみましょう!

GitHub Flow

チーム開発の進め方はいくつかあるかと思いますが、CAMP でも取り入れているGitHub Flowを理解すれば、大体どんな形式の進め方にも応用出来ると思います!

GitHub Flow に関しては@tbpgr さんのGitHub Flow 図解がとてもわかり易くまとまっているので、こちらを読んで頂ければと思います!

今回は後述する各セクションのイメージが湧くように開発の流れだけリスト化しておきますね!

GitHub Flow を用いたチーム開発の一連の流れ

  1. 課題や仕様を整理
  2. 実装
  3. プルリクエストの作成
  4. レビュー
  5. 本番反映 🎉

上記の流れでチーム開発は進んでいきます! それではそれぞれの項目に関して見てみましょう!

1. タスク管理アプリなどで実装する課題や仕様を整理

個人でアプリを作っていたときも「この機能を追加しよう!」と、目的や課題を洗い出すことはありますよね。

これはチーム開発においても同じで、まずは実際に手を動かす前に課題や仕様の整理を行います。

CAMPFIRE にはいくつかのサービスがあるため、サービスごとにいろいろなタスク管理が行われていますが、CAMPFIRE Owners では主にAsanaというタスク管理ツールで課題や仕様の管理を行っています。

Asana :この画像はAsanaの公式から持ってきました! (画像は asana 公式より)

考えるべきこと

タスクを作った際に、**「実装前に何を、どこまで決めるか」はチームや担当するエンジニアのレベル感によってバラバラだと思いますが、はじめてのチーム開発の場合は、「何を、どこまで」の「何ってそもそもなに?笑」**という感じかと思います。

今回はイメージしやすいように今の時期にありがちな年末年始営業のお知らせページの実装に関して考えてみましょう!

基本的に実装に入る前に考えるべきは下記の2つがマスト項目かと思います!

1. 実現したい目的や解決したい課題はなにか( ≒ なぜ実装をするのか?)

1つ目は「なぜ実装するのか?」の確認ですね。リソースが限られている以上、なぜそれを行うのか?はどんな開発でも出発点だと思います。

今回の例で言えば下記のような形でしょうか?

年末年始でサービスの運営・ユーザー対応が通常と異なるため、変更点をユーザーにアナウンスする必要がある。現状、お知らせページでも通知するが、ユーザの目に付きにくいため、不要なコンタクトリソースを減らすために年末年始運営に関する静的ページを作成し、トップページのファーストビューにそのページへのリンクを設置する。

2. 仕様の確認

2つ目は、1つ目で決めた課題を解決するための仕様部分です。 ここで仕様が課題の解決にマッチしていない場合、

  • 実装後に再度実装をやりなおす
  • 追加実装が必要になる

上記が発生してしまうため、チーム開発初心者の方は、しっかりとすり合わせをした方が良いと思います。

今回の例で言えば下記のようなことをしっかりと確認しておきたいですよね!

  • お知らせページの URL はどうするのか?
  • お知らせページの内容(文章・デザイン)はどうするのか?
  • トップページのどこに、どのようなデザインでお知らせページへのリンクを設置するのか?

仕様を満たさないことはそんなに多くないかもしれませんが、逆に、めちゃくちゃ大変だった実装が、確認してみるとマストの実装ではなく今回は対応先延ばしでも良かったは、よくある話かと思いますので、最初に書いた「何をどこまで」の「どこまで」の部分もしっかり確認するようにすると良いかと思います!

この目的設計や仕様確認の部分は、チーム開発の経験が浅い場合は先輩エンジニアやプロジェクトマネージャーなどがしっかりと付いてくれると思うので、今回はさらっと流れのみの紹介に留めます(私もそこまで tips が溜まっていません 😂)

実装に関する tips

仕様イメージが湧いたところで、次はいよいよ実装です! チーム開発をされる段階ということは、実装自体はしたことがあるかと思うので、tips 的なものを共有することで、理解の促進に繋げられればと思っています 😊

git blame を活かす

はじめてのチーム開発ということは、他人が書いたコードをもとに機能追加や変更をするのも初めてだと思います。

全体の仕様もまだ把握出来ていないと、コードを書いていても、「このコードはなぜこういう書き方に?」みたいなことはザラにありますよね。

そんなときにコードを一つ一つ追っていって理解を深めることはとても大切ですが、コードリーディング以外の側面でも周辺知識を蓄える方法はあります!

ズバリ、git blameコマンドです。

$ git blame fileへのパス

b12a90bd (matinana 2019-04-24 20:23:35 +0900  46)       pickerResult: '',
839d3259 (matinana 2019-05-20 22:20:29 +0900  47)       validate: false,
c744cf6d (matinana 2019-11-09 22:43:22 +0900  48)     };

このコマンドで、上記ようにコードに変更が加えられたときのコミット ID が表示されます。 これを下記画像のようにgithub の検索バーに入れて検索すると該当のコミットが表示されます!

このコミットの PR の内容やコメントなどを追うことで実装が追加された当時の背景を知る事ができます。 どうしても分からないことはチームに投げるのも大切ですが、自分で読み解くこともチーム開発の面白みですので、ぜひ試してみてください!

実装のスコープを意識する

実装をしていると、ついつい今回の実装範囲と異なる部分で改善点が見つかったりします。 個人でアプリを作っているときは「お、ここの機能ちょっとおかしいから、ついでに直しちゃおう!」というのはよくあることですよね。

ですが、チーム開発ではそれが必ずしも良いとは限りません。笑

個人開発で「ついでに直しちゃおう」が出来るのは仕様を完全に把握しているため変更箇所の影響範囲が明確になっているからだと思います。

チーム開発だと変更した箇所の影響範囲が本当に変更した場所だけでよいのか?の検証が必要になります。

  • 他の場所も合わせて変更する必要がある
  • 一般的にはアンチパターンだとしても特別な理由で現状の実装にしている

上記のような可能性もあります。

これらの確認をレビュアーにも強いるのは酷な話ですよね。

今回の対応箇所以外で変更が必要だと思ったら別途タスクを積んだりPR 作成時にレビュアーにも意見を求めるのが良いと思います。

プログラミングの世界にはボーイスカウトルールという言葉がありますので、スコープ内であればリファクタや修正はどんどんしていく態度が良いと思います!

ただ、タスクのスコープを明確にすることは、誤解や不具合を産まないためにとても大切なことだとこの一年間を通して学んだため、ぜひ共有させてください ✋

コミットメッセージにプレフィックスをつける

みなさんはどんなコミットメッセージをつけていますか? チーム開発の経験がないと、コミットメッセージを他の人に読んでもらう体験もないですから、「その時の自分だけがわかるメッセージ」をつけてしまいがちかなと思います。

コミットメッセージが適当な場合

たとえば

state まわりの調整

上記のようなコミットメッセージですと

  • なんの state を
  • どのように調整したのか

上記の情報がわかりませんし、また

  • 新規追加なのか
  • リファクタなのか
  • それとも lint のような細かい調整なのか

上記のような情報もわかりません。

これだと、レビュアーへの負担がとても大きくなってしまいますよね。

そこで出てくるのがコミットメッセージにプレフィックスを付けるという tips です!

プレフィックスをつける場合

詳しくは@numanomanu さんが【今日からできる】コミットメッセージに 「プレフィックス」 をつけるだけで、開発効率が上がった話の記事で書いてくださっていますが、下記のようにコミットメッセージに対応内容に沿ったタイプを付与するようにします!

prefix.png

これによってまさに前述の記事で書かれている下記のような恩恵が生まれます。(前述の記事がとてもしっかりまとまっているのでまるっと引用させていただきます m(_ _)m)

  • 機能をプレフィックスレベルで分割して作るようになる
  • コミットが見やすくなる
  • レビューしやすくなる
  • コミットログを検索しやすくなる

個人的には

機能をプレフィックスレベルで分割して作るようになる

上記がとてもイケてる効能だと思います。

コミットをプレフィックス(内容)によって分割するように意識することで

  • 処理の全体を把握してから実装する癖がつく
  • 処理を細かく分けることで、実装の整理が進み、漏れや間違った実装を防ぐことが出来る

上記など、レビュアーへの負担軽減だけでなく、エンジニアとしての成長にも寄与すると考えているからです!

プレフィックスをつける場合(例)

コメントだけだとイメージがわかないと思います。 先程のstate まわりの調整にプレフィックスを付けてタイプごとの違いをみると、どうメッセージが変わるのかを見てみましょう!

feat: state まわりの調整

これですと、既存の機能に足りていなかった state を追加したイメージですね! その場合は、何を追加したかの情報も欲しくなりませんか?

feat: ログイン時の state 情報を追加

のほうがよいのでは?と考えられるかもしれません。

fix: state まわりの調整

この場合ですと何かしら既存のバグの修正した形になりますね! でしたら

fix: ログアウト時に state 情報を削除してログイン情報を見れないように変更

上記のように fix した内容も分かる形の方が良いかもしれないと思いつけそうです!

refactor: state まわりの調整

こちらの場合は、リファクタですからこのままのメッセージでも良いかもしれませんが、なにを改善したのかが分かるように書いてあげるのも一案かもしれません!

refactor: 重複している state の記述を共通化

これらのようにメッセージを切り分けることで、

  • レビューがしやすくなりそう
  • 処理の整理が進みそう

上記のようなメリットが生まれそうな気がしませんか? ぜひ、今日から試して見てください!(未だに自分も徹底できてないです…😂)

rebase コマンドを活用してもっとコミットをわかりやすくしよう!

こちらは前項にも関連するのですが、rebase コマンドを使うとコミットをまとめることができます。 たとえば、開発の流れのセクションで想定していた「年末年始営業のお知らせページの実装」のコミットログを見てみましょう!(適当に作ったログです m(_ _)m)

// git log --onelineコマンド
6zb78bz style: トップのお知らせページへのリンクカラーを変更  ④
z128z1z style: お知らせページのタイトルのフォントサイズを修正  ③
abcz30z feat: トップにお知らせページへのリンクを追加 ②
zb9z104 style: お知らせページのデザインを変更 ①

上記のようにお知らせページのデザインを変更した後に、トップページにお知らせページへのリンクを張りました。 しかしその後、お知らせページのフォントサイズの指定を忘れていたたため変更し、さらにその後トップのリンクカラーが変更になったためリンクの色も再変更します。

あるあるな状況ですし、このままでも良いのですが、同じような修正が今後何個も出てくることもあります。 そういうときに ③ は ① に、④ は ② にと、一緒くたに出来るものはまとめてしまったほうが自分のコミットを見返すときにも、レビューして頂くときにもわかりやすいですよね!

そんなときに使えるのがrebase コマンドです。

詳しくは iwb.jp さんのGit の複数コミットを rebase と squash でまとめる方法 でまとめてくださっていますので、こちらを見てください。笑

結果として

③ は ① に、④ は ② にと、一緒くたに出来る

上記が実現できます!

<注意点>

PR を作成し、レビューに投げたあとに rebase を行うと、レビュアー側でコンフリクトの解消を行う必要が出てくるため、私はレビューを投げたあとは使わないようにしています。

rebase をしてしまうと、コンフリクトが発生するだけでなく、レビュアーがすでに確認したコミット部分にも変更が加えられる可能性があるため、再確認して頂く必要が出てきてしまいます。

チーム開発の鉄則は CAMPFIRE のバリューの一つにもなっている「人にやさしくあろう」だと思っているので、なるべく相手に負担がかからないように出来ると良いですよね 😊

PR 作成時の tips

実装も一段落したら、レビューして頂くために PR を作成です! 個人的に意識したいなぁと思っていることを 3 つほどシェアさせてください!

気になることは全部コメントで書く

開発経験が浅いと、レビューしてもらうときは不安になりますよね! 「これでよかったのかな…」と思いながら PR を作ることも多々あると思います。

そういうときは、事前に全部コメントで不安な点を書いておきましょう! コードが有るということは、不安でも意思決定をして実装をした理由があるはずです。

そのため、

「この部分は、〜と記述が冗長なのでリファクタの余地がありそうですが、中々思いつきません。〜のファイルでも同じような書き方をしていたので現状の形にしましたが、なにか良い実装方針などあればシェア頂ければと思います!」

上記のように不安な点考えたことを書いておけば、レビュアーがコードを見る前の段階で

  • 実装者が何がわかっていて / 何がわかっていないか(該当部分の処理に問題があると考えてはいるが、改善点はわかっていない)
  • 何を考えたか(既存の似た実装は頭に入っている)

上記がある程度伝わります。

そしたらレビュアーもより具体的なコメントをくださりそうですよね 😊

また、何がわからないかを記述することで、考えの整理ができて、良い実装が思いつくこともあります。 ぜひ PR 作成時に不安な箇所はすべてコメントする姿勢を試してみてください!

PR を小分けにする

一人で開発していると機能をまるっと開発してから本番反映するため、実装のかたまりが大きくなりがちです。

例としてユーザーに一年間の利用データを PDF で出力する機能を考えてみましょう。 必要な実装としては

  1. 利用データを記録するテーブルの作成
  2. 利用データを集計しテーブルに記録する処理
  3. ユーザーがマイページで出力ボタンを押すと記録テーブルから該当の一年の利用データの PDF を出力する処理

上記などが考えられます。

これらを1つの PR として作成すると、1 の実装が変わった場合、レビュアーは 2 でも 3 でも 1 の変更内容を確認する必要性が出てきますね。

もちろん別々の PR の場合でも、2 と 3 の PR には 1 の変更点の修正は入りますが、そもそも PR が分けられていることで、

  • 確認範囲が小さくなっている
  • 各々の PR での追加機能にスコープを絞ってレビューが可能である

上記から格段にレビューがしやすくなります。

最初の頃はPR をどう小分けにすればよいのかが分からないと思いますが、そういう場合は先輩エンジニアに仕様確認の段階で「こういう分け方で実装しようと思う」という確認を投げるのが良いと思います!

小さい PR にすればするほど変な実装をしてしまったときに方向転換が効きやすいです。 実装に自信がないときほど意識していきましょう。笑

動作確認をしっかりする

入社したばかりの際に先輩エンジニアに「初心者エンジニアに気をつけてほしいことはありますか?」と聞いたら「動作確認をしっかり行う」という答えが返ってきました。

きれいなコードの書き方やリファクタの方法に関しては、一年目のエンジニアにとって大きな課題だと思いますが、まずは「意図した機能になっているか」をしっかりと担保することが大切なのは、本当にそうだなぁとしみじみ思います。

私は動作確認時に下記のような手順を一つ一つ項目化し列挙するのが良いと考えています!

  • デザイン変更の場合

    • PC・SP の各変更した全画面のスクショをしっかりと撮る
    • 推奨環境(ブラウザや実機確認など)での崩れがないか確認する
  • 機能変更の場合

    • 変更・追加した機能を流れで列挙するようにする
      • ✕ 「登録機能の追加」
      • ○ 言葉で手順を確認する
        • 〜画面に登録ボタンを追加
        • ボタン押下で新しい ○○ が〜に表示
        • 完了ボタン押下で〜画面に遷移

上記のような

  • 目で見る
  • 手順を読む

このような動作確認を行っていくと、デプロイ後に「え、やっちゃった…😨」みたいなことを減らせる気がします。

レビュー

レビューってめちゃくちゃ難しいですよね…。僕も未だに自信を持ってできません。 ですので、自分としてこういう態度があると良いなぁと思う tips を何点か共有させてください。

疑問点を投げるのも大切なこと

そもそもチーム開発をはじめた最初の頃は、自分自身がチームの中で一番知識も経験も浅いと思います。 そんな中でレビューなんて出来るか?というのが素直な感想ではないでしょうか?

そんな中、誤った指摘をしてしまうことも度々あります。 しかし、そうした際にも下記のようなコメントを頂けました!

指摘していただけると xx だったかと考える機会になるので、どんどん指摘していただいた方が助かります!

神!!👼

もちろん、誤った指摘によって、実装が間違った方向に行ってしまう可能性もあるため、誤った指摘でも良いと言うつもりはありません。

ですが、指摘をすることで実装者が改めて気づくこともあります

また、レビュー側がよく分からないというのは、場合によっては

  • リファクタの余地のあるわかりやすいコードになっていない
  • ベストプラクティスから外れたコードになっている

上記のような可能性もあります。

分かる点だけでレビューするのではなく、分からないという情報も大切な情報の一つになり得るという可能性を持って、自信を持ってレビューにトライしていけば良いのではないでしょうか!

良いと思った部分は言葉にして良いと言う

良い部分はスルーしがちですが、「ここの書き方良いですね!」と一言あるだけで嬉しさ100倍になるので、出来る限りポジティブなコメントを残すようにトライしたいと思っています。

悪い点を指摘するのではなく、相手の理解が進む形で投げるようにする

改善・修正すべき点を見つけたときに 「ここは@@に直してください」とただ修正点を指摘するのではなく、相手の理解が進む形のレスポンスを心がけると良いと思います。

相手の理解が進むレスポンスというのは

  • 指針をシェアする
  • コードをシェアする
  • コードに添えて、その人の理解が進むアドバイスも添える

上記のように相手のレベルや理解度に合わせてレスポンスを変えることが大切だと思います。 レビューはコードの間違いを指摘するものではなく、相手と自分のコードへの理解を深めるため(=結果としてコードを正しいものに導ける)だと自分は考えています。

Qiita で良いレビューに関して調べると、みなさん共通して「コードの書き手を尊重しよう」ということを述べています。

コードレビューは緊張するものですが、サービスの改善や自身の成長に繋がるし最高ー!と思えるようなチームでのレビュー体験を築いていきたいですよね!

[nits] [IMO] [MUST]などのラベルをつけてみる

ちょっと tips 的なものも少し。

レビューする際に、

  • これ超細かい指摘だな…
  • これは絶対に対応して貰いたい部分だ

など、当然のようにレビューコメント一つとっても重要度の差がありますよね! そういうときは、コメントの重要度を示すラベルをつけるのもわかりやすいです!

詳しいラベルの説明に関しては@miyarappo さんが自分のレビューコメントのラベルと意図でまとめてくださっているのでこちらをご確認頂ければと思います!

コミットメッセージのプレフィックスコメントと同じように、コメントの意図を明確化出来るようになりますので、レビューコメントが多くなる場合は使いこなしたいなぁと日々思っています。

LGTM 画像

みんな大好き LGTM😘

個人で開発していた際には、PR を LGTM して貰ったことはないと思います 😂 ですが、チーム開発では PR のアプルーブを行うときに**Looks Good To Me(見た感じいい感じ!)**という LGTM のコメントを添える文化があります。

頑張って実装した内容が認められる瞬間ですからね、やっぱり嬉しいですよね笑

チームや人によって LGTM がコメントだけの場合、画像も添える場合など様々かと思いますが、個人的にはなるべく画像を添えるようにしています!

実家で飼っている愛犬です笑 (これは今作った実家の愛犬)

LGTM 画像を作れるLGTMOONや検索サイトのLGTM.funなど様々なサービスがありますので、ぜひ実装相手が喜びそうな画像で LGTM してあげてください\(^o^)/

#本番反映

おめでとうございます!🎉 ついに本番反映ですね!

個人で何千人・何万人に使ってもらえるアプリを作ったことがある場合は例外ですが、そうでないなら自分の追加した機能がそういった沢山の方々に届けられるというのは素敵なことですよね!

このセクション、

  • デプロイ時の tips
  • ドキュメントの整理
  • 運用する人たちへのホウレンソウ

など、沢山共有するべきことが多くあると思うのですが、この記事も長くなりすぎてしまったので、本番反映時〜後のことはまた違う記事で書ければ良いなあと思います。私個人としては、このセクションは不安に感じるというよりも、プラスアルファで出来ると良いことのセクションだと思っているので、今回はスコープ外にします!😚

#あとがき

「未経験からのチーム開発で学んだ Tips と態度」というタイトルで書いてきました。 この記事を読んでくださった方の中で、まさに今チーム開発を始めるところという方も何人かいるかもしれません。

たぶん、すごく不安で辛いですよね?

でもその辛さがチーム開発によるものではなく、自分の知識不足や不甲斐なさからくるものだけになるように色々な知識や経験を共有して成長していけるのがチーム開発の醍醐味だと思っています。

この記事でも沢山の記事を引用させていただきましたが、オープンソースや情報発信がとても活発なエンジニアという繋がりは、いわば**One Team!**だと思いますので、あなたの大変さがこの記事や qiita にある沢山の記事で少しでも減らせて、あなたのコードの乗った素晴らしいサービスが世の中にあふれることを心より願っています!

最後まで読んでくださりありがとうございました!

Happy Hacking!