Findyの爆速開発を支えるPull requestの粒度

こんにちは。

Findy で Tech Lead をやらせてもらってる戸田です。

既に皆さんも御存知かと思いますが、弊社では開発生産性の向上に対して非常に力を入れています。

以前公開した↓の記事で、弊社の高い開発生産性を支えている取り組み、技術についてお話させていただきました。

tech.findy.co.jp

ありがたいことに、この記事を多くの方に読んでいただき反響をいただいております。

そこで今回は、↑の記事でも紹介されている「Pull requestの粒度」について更に深堀りしてお話しようと思います。

Pull requestの粒度は、弊社にJOINしたら最初に必ず覚えてもらう最重要テクニックの1つです。

それでは見ていきましょう!

大きなPull request

Pull requestのレビュー依頼が飛んできて確認したら、大きなPull requestでブラウザをそっと閉じた経験がある方は少なくないと思います。

大きなPull requestにおけるデメリットは数多く存在します。

パッと思いつくデメリットを列挙してみます。心当たりがある読者の方もいるのではないでしょうか?

  • topic branchの生存期間が長くなり、結果的にbase branchとの差分が大きくなりconflictの発生確率が高くなる
  • 変更内容が多岐に渡るため、問題発生時の原因特定に時間が掛かってしまう
  • revert時に余計な内容までrevertされてしまう
  • レビューの質が落ちる
    • レビュワーが見るべき範囲が広くなるため、認知負荷が大きくなる
      • あとで見とこ、、、となりがち
        • 結果的にtopic branchの生存期間が長くなる
        • base branchとの差分が大きくなる
        • conflictの発生確率が高くなる
    • 指摘内容が増え、結果的に手戻りが増える
  • etc

このようにデメリットは数多く存在します。システム開発において大きなPull requestの存在は、円滑な開発を阻害する要因となるでしょう。

では「大きなPull request」とは具体的にどんなPull requestのことを指しているのでしょうか?

適切な粒度とは

ここでサイズと粒度の違いを説明する必要が出てきます。

そのPull requestが1つのことに注力できているかどうかが、粒度を語る上で非常に重要なポイントになります。

Pull requestのサイズとは、コードの変更行数や変更ファイル数のことを指します。

しかし、コードの行数や変更ファイル数が多かったとしても、変更内容が一意であれば問題ないはずです。

例えば、関数名を変更して一括置換した場合を例に挙げましょう。変更ファイル数は多くなりますが、変更内容は一意です。

こういったケースの場合、Pull requestの概要欄に一括置換した旨を記載しておけば、変更内容を全て確認せずとも変更後の関数名をレビューし、CIが通ればマージ出来るはずです。

一方、Pull requestの粒度とは、コードの変更内容のことを指します。

例えば、変更ファイル数が少ない一方、データ取得・データ加工・描画処理を同じPull requestで対応した場合を例に挙げて考えてみましょう。

この場合、それぞれの処理は全く異なる内容です。しかし同じPull request内で対応してしまったため、変更内容全てを一度にレビューする必要があり、レビュワーに対する認知負荷が大きくなってしまいます。

極論ですが、たとえ変更行数が1万行を超えていたとしても、変更内容が一意であれば問題は無いと考えています。

逆に変更行数が20行程度の不具合修正の中に「ついでにリファクタ」した内容が含まれていた場合、粒度が大きいと判断しPull requestを分割すべきなのです。

なぜならば、もし不具合修正に失敗していてrevertしようとした際に、ついでにリファクタした内容もrevertされてしまうからです。こういったケースの場合、リファクタをしたPull requestを別で作成します。

つまり本質はコードの変更行数や変更ファイル数ではなく、変更内容そのものにあるということを理解できたかと思います。

粒度が適切であれば、1行だけの修正でも、1万行の修正でも問題ありません。

10のプルリクを1回レビューするよりも、1のプルリクを10回レビューする方が、作成者、レビュワー共に負担が少ないのです。

適切な粒度を維持するために

タスク分解

Pull requestの粒度について完全に理解したので、これからは適切な粒度でPull requestを作るぞ!と思い立っても、すぐに実現させるのは難しいものです。

理解はしているけど、やってみるとやることがどんどん増えていき、結果的にPull requestが肥大化しがちです。

それを解決するのがタスク分解です。概要は↓のページを参照してください。

tech.findy.co.jp

タスク分解に関しても、別の機会で詳細にお話できればと思います。

迷ったら小さく

とは言え、最初のうちは粒度に対して悩むことが出てくると思います。

もっと作り込んでからレビュー依頼を出す?それとも今の段階で出す?でも修正内容が小さすぎないか?などといった葛藤は自分にも経験があります。

そういう時は、より小さい粒度の段階でレビュー依頼を出すことをオススメします。レビューのやり取りの中で粒度に対する議論を行い、そこで認識を合わせればOKです。

Pull requestを大きく作って後から分解するより、小さく作って後から修正内容を追加する方が圧倒的に楽だからです。

まずは小さすぎても良いので小さく作り、そこから肉付けしていくようなイメージでPull requestを作成していくと良いでしょう。

レビューを最優先にする

Pull requestの粒度が小さくなった場合、レビュー依頼に対して最優先で取り組む必要があります。

なぜならば、マージしないと次の修正に着手出来ない場合に、レビューがボトルネックになり結果的に開発スピードが遅くなってしまうからです。

自分の作業を一時中断して、10分程度レビューして自分の作業に戻るとコンテキストスイッチを戻すのが非常に難しいと思います。

でも心配しなくてよいです。Pull requestの粒度が適切であれば、レビュワーが確認する内容も小さくなるためレビューに掛かる時間が短縮されます。

そのため、自分の作業を一時中断することになったとしても、すぐまた自分の作業に戻ることができるようになります。

弊社では1つのPull requestのレビューに掛ける時間はほんの数分程度となっています。1分以内で終わることもあります。

粒度が適切なPull requestが当たり前となれば、レビューを最優先にする習慣、文化が組織に根付くはずです。

CI高速化

粒度が小さくなってくると、当然ながら作成されるPull requestの数が増えます。つまりCIの実行回数も比例して増えていきます。

CIの実行回数が増えた状態で実行速度が遅いと、逆に開発効率が落ちてしまいます。CIが遅いからPull requestの粒度も大きくなってしまうといったケースも見たことがあります。こうなってしまうと本末転倒です。

そこでCIの高速化も同時に進めた方が良いでしょう。詳細はこの記事では割愛しますが、↓の別記事を参考にしてみてください。

tech.findy.co.jp

feature flag運用

Pull requestの粒度は適切にしたいが、本番環境には影響を出したくない。というパターンはfeature flagを使うと良いでしょう。

ローカル環境でのみ実行されるようなコードにしておいて、その状態を維持しつつbase branchにマージし続けます。本番公開OKのタイミングでfeature flagを解除し、本番環境に反映します。

feature flagの運用方法はSaaSを使う、ライブラリを使うなどの方法がありますが、今回は一番カンタンに導入できる方法の、コード上にフラグを埋め込んで切り替える手法を紹介します。

実際にコードの例を見てみましょう。

export const SampleComponent = () => {
  const isEnabledNewLabel = process.env.FEATURE_NEW_LABEL === 'true';

  return (
    <div>
      {isEnabledNewLabel && <span>NEW</span>}
      <span>Sample</span>
    </div>
  );
};

環境変数に埋め込まれている FEATURE_NEW_LABEL の値によって、 NEW の表示を切り替える単純なcomponentです。

この仕組みにより、ローカル環境の環境変数をtrue、本番環境の環境変数をfalseにすることで、本番環境に影響を与えずに新機能の開発を進めることが可能になります。

開発が完了して本番環境に反映する際には、本番環境の環境変数をtrueにすることで新機能を公開できます。何かしらの問題が発生した場合、本番環境の環境変数をfalseに戻すことで、新機能を非公開に変更可能です。

本番環境で問題が起きなければ、環境変数のフラグとコード上の分岐を削除します。

この手法はfeature flagの管理が煩雑になったり、コード内の分岐やテストケースが増えるといったデメリットもありますが、Pull requestの粒度を適切に維持するためには非常に有効な手段です。

本番環境に影響を出さずに、Pull requestの粒度を適切に維持し続け、スピード感を持って開発する手段の1つとして活用してみてください。

topic branch運用

様々な事情によってfeature flagを使えない、使いたくない場合の手段として、topic branch運用を紹介します。

topic branch運用

base branchからtopic branchを切って、そこから更にdevelop branchを切ります。develop branchからtopic branchへのPull requestを作成し、そこで粒度を維持しつつレビューをします。

本番反映OKのタイミングでtopic branchからbase branchへのPull requestを作成し、マージします。このタイミングでのレビューは必要最低限でOKです。なぜなら、develop branchからtopic branchへのPull requestでレビューしているからです。

この手法により、base branchにはリリースのタイミングまで変更内容が反映されません。そのため本番環境への影響を与えず、Pull requestの粒度を適切に維持し続けることが可能になります。

定期的にbase branchからtopic branchへ変更をmergeしておくのがポイントです。topic branchの生存期間が長くなるので、base branchとの差分が大きくなりconflictが発生しやすくなるからです。最低でも1日1回はbase branchの修正内容を取り込んでおくと良いでしょう。

まとめ

いかがでしたでしょうか?

粒度を適切に維持することで、レビュワー、レビュイーの両者に対して優しいPull requestを作成し続けることができます。

弊社では最重要テクニックの1つとしていますが、比較的カンタンに覚えることができ、コツさえ掴めば誰でも実践できる内容です。

是非、皆さんも試してみてください。

現在、ファインディでは一緒に働くメンバーを募集中です。

興味がある方はこちらから ↓ herp.careers

【フルスタックエンジニアへの道!】ReactとTypeScriptの修行をした話

こんにちは、ファインディでFindy Team+(以下Team+)を開発しているEND(@aiandrox)です。

普段はバックエンドの開発をメインで担当しているのですが、3ヶ月間フロントエンドの開発に挑戦する機会がありました。短い期間でしたが、フロントエンドテックリードから直接指導してもらいながら実装をすることで、フロントエンドの開発を一人でできるくらいに慣れることができました。

今回は、その経験と学びについて書いていきます。

フロントエンドに挑戦する前の自分について

もともとはバックエンド(Ruby on Rails)の開発をメインでしていました。

前職では特にバックエンドとフロントエンドが分かれておらず、Rails View / CoffeeScript / FlowType / jQuery / Reactの混在したフロントエンドを触っていました。また、個人開発でReact / TypeScriptを触ったことはあったものの、あくまでも動くことを重視していたため、アーキテクチャの意識はあまりしていませんでした。

Team+のフロントエンドでは、前年に修正プルリクをいくつか出したので、アーキテクチャはなんとなく把握していました。しかし、既存の実装を踏襲したまま一部を修正する程度だったので、新規でComponentを作ったことはありませんでした。

フロントエンドに挑戦することになった経緯

もともと個人開発などもしていたので、フロントエンドへの興味もありました。将来的にはフルスタックエンジニアとしてスキルを広げたいという思いもありましたが、まずはバックエンドの技術を身に付けることを優先していました。そんな中、「フロントエンドの手が足りないんだけどやってみない?」という提案がありました。

いい機会!ということで、「やりたいです〜」「テックリードと一緒にやってもらおうと思ってます」「やったー」とトントン拍子で進んでいきました。

フロントエンドを学ぶ上で助けられたこと

フロントエンドに挑戦するにあたり、以下のサポートがあることにより、スムーズに実装を進めることができました。

フロントエンドのノウハウが溜まった記事の充実

社内記事に「フロントエンドを書くときに何を考えているか、どうしているか」というものがあり、これを参考にできました。「データ層を扱うものはデータ層の責務に閉じ込め、プレゼンテーション層は見た目に注力する。つまり、Pureな Presentational Componentは原則としてロジックを持ってはならない」といった基本的な考え方と、実際に画面を作るときの作業工程を書いていたので、とても役立ちました。

基準の考え方があったので、迷ったときにこれに立ち返ったり、「この場合はどうなのか?」と具体的に質問することができました。

開発ツールが揃っている

開発中はJavaScriptの統合テストツールWallaby.jsを使用していたので、デバッグがスムーズに進み、開発作業が非常に効率的になりました。

tech.findy.co.jp

また、CIによって一定の品質が自動的に担保されるので、レビュー前に自分で気付けることも多かったです。ESLintは実装に寄ってくれている感じがあり、hooksの依存などを自動で補完してくれるため初学者としては安心できました。

テックリードとマンツーマンでタスクをやっていく

テックリードとは同じチームなので、朝会で進捗の共有をするとき悩みポイントを共有したりしていました。また、実装方針に悩んだときは分報チャンネルに投げて拾ってもらったり、都度ペアプロなどでサポートしてもらいました。

また、自分が作成したプルリクに関してはすべて見てもらっていたので、私の理解度を把握されていました。そのため、プルリクの実装についての指摘や、理解度が浅そうなところなどがあったタイミングで呼び出していただきました。都度口頭で説明されたり自分からも「この理解で合ってます?」と壁打ちすることで、具体的な話から理解度を高めることができました。

※「体育館裏」は一見怖そうに見えるかもしれませんが、怒られたりすることはありません。コワクナイヨ

react.devの輪読会

もともと、フロントエンドをメインとするメンバーでReact公式のLearn Reactの輪読会を行っていたので、自分も途中から参加するようになりました。

書かれている文章だけだと言葉や概念が難しかったのですが、輪読会では具体的な解説があったりわからない点を質問できたりしたので、実践を理論で補強できました。これにより、プルリクで指摘された内容について「つまりそういうことなのか」と理解できるようになりました。

つまづいた点

タスク粒度を適切に分割すること

バックエンドに関しては、技術的にもドメイン的にも慣れているので、1つのクラスごとにプルリクを作成することができていました。しかし、フロントエンドに関しては、ローカルの画面で動く状態まで実装すると大きすぎるプルリクになることがありました。

これを解消するために、1つずつ実装した箇所のテストを書くことで安心してプルリクを出すことができました。バックエンドでは当然のように考えていたことでしたが、フロントエンドではつい画面でのデバッグをしようとする心が働いてしまっていたことを自覚しました。

また、最初はComponentを分割して実装するという意味をあまり理解できておらず、中途半端な状態で1プルリクにしたりもしていました。

Team+のフロントエンドの責務の考え方

フロントエンドの設計は以下のようになっています。

コンポーネント名 カスタムフック名 扱うデータ
Page Component Params Hook ブラウザURL
Container Component Facade Hook API や ストレージ等
Presentational Component Presenter Hook フォーム

Findy転職フロントエンドの開発生産性を向上させるためにやったこと - Findy Tech Blog

この思想をなんとなく頭に入れていたものの、実際に実装している途中で、「この記述はFacadeで書くべきなのか、Presenterで書くべきなのか」と迷うことがありました。

例えば、GAトラッキングの記述を最初はFacadeに書いていたのですが、「GAの実行はUIのクリックアクションをトリガーとするので、Presenterに書くのが適切」といったフィードバックを受けました。propsで渡された関数をPresenterでwrapするといったやり方が、最初は選択肢になかったので、新鮮に感じました。

また、ContainerからContainerを呼んでいる場合もあり、どのようにコンポーネントを分割するべきか迷う場面もありました。画面内のAPIを基準にFacadeを分割し、それに応じてContainerを組み立てていくとわかりやすかったです。

TypeScriptで慣れる必要があったこと

今まで書いてきたRuby / Railsと比較して、TypeScriptには型があるというのが大きな違いですが、個人的にはその堅牢さの中でJavaScriptの関数などを使いこなすのが難しかったです。

例えば、以下のような点です。

  • nullundefinedだけでなく、0もfalsyな値になる
  • 配列に対してfindを実行すると戻り値がundefinedになりうるため、必ず値が存在する場合にfindを使うと、型と実態が合わなくなってしまう

3ヶ月の挑戦の成果

この機会に、1つの新機能をテックリードと2人で分担して開発しました。私は、以下のような一覧画面と分析画面をそれぞれ2画面ずつ担当しました。

一覧画面

分析画面

また、安定してプルリクを作成することもできるようになりました。

この3ヶ月を通して、React全体やTeam+のフロントエンドでの設計思想を学び、コンポーネントの責務の分離や状態管理の方法について、実践を通して理解することができました。これにより、他のエンジニアへのレビューもある程度自信を持って行えるレベルになりました。

改めて感じたのは、ただ動けばいいのではなく、Reactで可読性・設計を考慮したコードを書くのは難しいということでした。記述方法の自由度が高い分、意図を設計として乗せる必要がある(テックリードからの受け売り)というのを実感しました。

自身の伸びしろ

今回の挑戦では表示するデータを取得するものばかりだったので、フォーム処理やデータの更新などに今後は積極的に挑戦したいです。

また、react.devの輪読会や共通コンポーネントを変更しようとしたときに、自分の実力不足を感じました。TypeScriptの知識不足や型の伝播を読み解けなかったり、既存の実装の変更対象がわかっても修正方法がわからない、概念はわかるが名称を知らない、などの伸びしろを見つけました。これに関しては、実際にやってみたり他の人のプルリクを参考に考えることを積み重ねていくことで、自身の糧にしていくつもりです。

ライブラリに関する理解もまだ浅いので、今後は開発にくわえて、フロントエンド環境のメンテナンスをできるような知識も増やしていきたいです。

おわりに

このように、ファインディではフルスタックを目指す環境で働くことができます。また、現在ファインディでは共に働く仲間を募集中です。興味のある方は、こちらのページからぜひどうぞ!

herp.careers

入社初月からさくさくアウトプット!スムーズな立ち上がりを支えるオンボーディングの具体例

こんにちは。

2024/7/1 からファインディに入社した斎藤です。

ファインディでは、Findy Team+ という、エンジニア組織の開発生産性を可視化し、開発チームやエンジニアリングメンバーのパフォーマンスを最大化するためのサービスの開発に携わっています。

今回は、私が入社初月からさくさくアウトプットできた理由についてご紹介します!

入社初月からプルリク1日4件出せました

ファインディでは1日あたり4件プルリクを作成するというのを1つの指標としています。

入社直後は慣れるまでは結構厳しい指標だなと思っていたのですが、この記事で紹介する様々な仕組みのサポートもあり気がついたら初月から達成できていました。

中途入社あるあるだと思いますが、入社直後になかなか成果が出せなくてプレッシャーを感じてしまうということがあります。

簡単なタスク中心ではありますが、初月から貢献しているという実感が持てたので心理的にもたくさんプルリクが出せて良かったなと感じています。

※1日4件という数値はあくまでアウトプット量の参考です。 闇雲にプルリクをたくさん出せばいいということではありません。アウトプットをプロダクトの成果につなげることが大切です。

入社1ヶ月目プルリク数

1日平均4.6件!!

入社1ヶ月目プルリク数

入社2ヶ月目のプルリク数

1日平均5.7件!!

入社2ヶ月目プルリク数

入社初月からさくさくアウトプットできた理由

Good First Issueの粒度が適切であったこと

新しく参画した人向けのIssueとしてGood First Issueを準備する文化がファインディにはありますが、粒度として難しすぎず簡単に終わりすぎず良い粒度で取り組めるタスクになっていました。

その中で複数箇所に同じ修正を加える作業があり、それをなるべく速く終わらせる意識で対応しました。

例:同じリファクタリングを複数ファイルに渡って対応するタスク

  • ある処理を別ファイルに移動するというリファクタリング
  • 対応すべきファイル名が列挙されていてわかりやすい

Good First Issue

スムーズな開発を支えるレビューとCI/CDがあること

入社前は開発生産性を可視化するプロダクトを開発しているくらいなので、さぞかし開発がしやすいんだろうなーと思っていましたが、 入社後はその想像を超えて開発がしやすい環境だなと感じました。

特に次のことが要因で開発をサクサク進めることができています。

  • レビューが速い!とにかく速い!
    • 1PRあたりオープンからレビューまでの平均時間:3.3h
  • プルリクの粒度を小さくして出す文化が根付いているためレビュー負荷が少ない
  • リリース作業が楽で、時間が取られない
    • リリースPR作成、e2eテストが自動化されていて基本的にマージボタンを押すだけで完了できる

この辺りは他の方の入社エントリーで詳しく紹介されているのでもしよかったら見てみてください。

メンターと密にコミュニケーション

メンターとの1on1で不慣れな点を解消しつつ、やることを明確に設定していただけたことで開発に集中できました。 1on1で印象的だったのは一度に多くの情報をインプットしないようにしていただけたことです。 入社後に必要な情報を適切なタイミングで適切な量に分けてインプットしていただけたので、ストレスなく業務に慣れることができました。

  • 適切な頻度(私の場合は週1回)でメンターとの1on1があり、そこで課題を解消できた
  • 1on1以外でも都度メンターに質問して迅速に疑問点を解消でき、開発に集中できた

ふりかえりをして日々改善が行われる

私のチームでは2週間に1回の頻度でFindy Team+の「KPTふりかえり」機能を使ってふりかえりを行っています。 そこで出た課題に対する打ち手を議論して改善に繋げる取り組みがとてもいいなと思いました。 ふりかえりで出たアクションはまずは試しにやってみましょうという感じですぐに実行されます。 アクションがすぐに実行されるというスピード感がとてもいいなと思いました。 そしてやってみたアクションについてどうだったかも合わせて次のふりかえりで確認しているので 継続的に改善が行われる仕組みになっています。

新しく参画した私が感じた課題はすでに改善のアクションが進んでいるという状態でした。 (なので課題が思いつかないという課題があります。。。)

このように現状に満足せず、より良くするにはどうしたら良いかを全員で考え行動していることが高い開発生産性に繋がっているんだろうなと感じました。

挙げられたProblemに対してTryを設定 KPT

全てのコードベースを把握していなくても既存を壊さない仕組み

またテストカバレッジが99%で、自分の改修で他へ影響があった場合にはちゃんとテストが落ちるようになっています。

このように、自分の開発に集中できる仕組みが整っているため、 最初から全てを把握していなくても、安全に開発を進めることができます。

なので、全くプロダクトの知識がない入社直後でも 自分の担当作業に集中できるので、サクサクプルリクを出すことができました。

不明点は遠慮せずにすぐに聞いたり相談できる

前述したメンターとの1on1もありますが、定例以外でも不明点はすぐにSlackのメッセージやハドルで聞くことが推奨されています。 オンボーディング資料にも「不明点は都度Slackやハドル、(出社している場合は)対面で確認しましょう!」と明記されており、みなさん快く応じてくれます!

また、ファインディではSlackでtimes(分報)チャンネルを各自持っています。 自分のtimesで疑問をつぶやくといろんな人が助けにきてくれる文化があるので助かっています!

今後の抱負

ファインディのバリューであり、自分の強みでもある「スピード」を大切に爆速で開発をやっていきたいです!

ファインディでは一緒に会社を盛り上げてくれるメンバーを募集中です。興味を持っていただいた方はこちらのページからご応募お願いします。

herp.careers

ファインディでのGitHub Actions自動化の事例

ファインディ株式会社でフロントエンドのリードをしております 新福(@puku0x)です。

GitHub Actionsは、CI/CD以外にも様々な業務の効率化に役立ちます。

この記事では、弊社で実施しているGitHub Actionsを使った自動化について紹介します。

自動化

担当者アサイン

開発フローの中では、Pull requestを作ってからレビューに出すまでにいくつかのタスクを行うことがあります。

弊社では、Pull requestの作成者がAssignee(担当者)となる場合が多いため、↓こちらのActionを用いてアサインの自動化をしています。

github.com

- uses: kentaro-m/auto-assign-action@v2.0.0
  with:
    repo-token: ${{ secrets.GITHUB_TOKEN }}
addAssignees: author
runOnDraft: true

Assigneeのみ自動化しているのは、レビューに出すタイミングをPull requestの作成者側で制御したかったためです。

レビュアーについては、GitHubの標準機能でレビュー用のGitHubチームを作ってランダムアサインするようにしています。

ラベル設定

弊社では、Pull requestをラベルを用いて管理しているチームもあります。

付与するラベルについては、セマンティックバージョニングと相性の良いものが用いられることが多いです。

GitHub - azu/github-label-setup: 📦 Setup GitHub label without configuration.

ラベル設定の自動化は、公式のActionがありますので比較的導入しやすいでしょう。

github.com

actions/labelerは、最近の更新でブランチ名を基にラベルを設定する機能が追加されました。

この例では、ブランチ名の先頭が featfix 等であった場合に対応するラベルを付与するようにしています。

'Type: Feature':
  - head-branch: ['^feat']

'Type: Bug':
  - head-branch: ['^fix', '^bug']

モノレポの場合、ファイルのパスに対応するラベルを設定すると、どのプロジェクトに影響するか判断しやすくなります。

'Scope: App1':
  - changed-files:
    - any-glob-to-any-file:
      - apps/app1/**/*
      - libs/app1/**/*

'Scope: App2':
  - changed-files:
    - any-glob-to-any-file:
      - apps/app2/**/*
      - libs/app2/**/*

actions/labelerは、Pull requestのタイトルを基にしたラベル設定には、2024年9月現在だと対応していないようです。

その場合は、手動でGitHubのAPIを呼ぶシェルを組む必要があります。

run: |
  pr_title=$(curl -s -H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" \  -H "Accept: application/vnd.github.v3+json" \
  "https://api.github.com/repos/Findy/***/pulls/${{ github.event.pull_request.number }}" \  | jq -r '.title')
  if [[ $pr_title =~ ^feat ]]; then
    pr_type='Feature'
  fi
  curl -X POST -H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" \
  -H "Accept: application/vnd.github.v3+json" -d '{"labels": ["Type: '"$pr_type"'"]}' \
  "https://api.github.com/repos/Findy/***/issues/${{ github.event.pull_request.number }}/labels"

いつか公式のActionにも欲しいですね!

リリース

手順の多いリリース作業も、弊社では自動化を取り入れて負担を減らしています。

ここではフロントエンド系のリポジトリに採用されているものを紹介します。

  1. バージョニング用ワークフローを実行
  2. バージョニング用Pull requestが自動生成される
  3. バージョニング用Pull requestをマージ
  4. バージョニング用Pull requestのマージを起点にリリース用Pull requestが自動生成される
    (プロダクトによってはここでStaging環境へのデプロイも実行されます)
  5. リリース用Pull requestをレビュー後、マージ
  6. リリース用Pull requestのマージを起点に本番デプロイ

開発者は「ワークフローの起動」と「自動生成されるPull requestのマージ×2」というシンプルな手順で本番デプロイまでできるようになります。

また、Conventional Commits に準拠したコミットメッセージを採用しており、自動バージョニングやリリースノートの自動生成といった恩恵も得られています。

デプロイ頻度はFour Keysの指標にも入っていることから、チームの健康状態を知る手掛かりになります。可能な限り高い頻度でデプロイできるよう、仕組みはしっかりと整備していきましょう💪

参考: https://dev.to/puku0x/github-actions-1mi5

QAチェック項目の抽出

リリースの際に、QA担当者がチェックすべき項目をPull requestの履歴から自動抽出しているチームもあります。

まず、.github/PULL_REQUEST_TEMPLATE.md に次のような項目を設定しておきます。

次に、リリース時に起動するGitHub Actionsから、チェック済みの項目を抽出するスクリプトを起動します。

def category_by_pull(pull)
  return :planner_qa_pr if body.include? "- [x] 企画側QA"
  return :developer_qa_pr if body.include? "- [x] 開発側QA"
  return :other_pr
end

リリース用のPull requestの本文に反映されるため、QA担当者が何を見るべきかがわかりやすくなります。

定期実行

cron が使えるのもGitHub Actionsの良いところです。

on:
  schedule:
    - cron: '30 0 * * 1-5' # 平日09:30 (JST)

休日・祝日の考慮が必要な場合は、次のように前段に判定用のジョブを仕込んで needs で繋ぎます。

check:
  outputs:
    is_holiday: ${{ steps.check_holiday.outputs.result }}
  steps:
    - run: npm install @holiday-jp/holiday_jp
    - uses: actions/github-script@v7
       id: check_holiday
       env:
         TZ: 'Asia/Tokyo' # タイムゾーン固定必須
       with:
         script: |
           const holidayJp = require('@holiday-jp/holiday_jp');
           return holidayJp.isHoliday(new Date());

some_job:
  needs: check
  if: needs.check.outputs.is_holiday == 'false'

outputsstring で返ってくるため、boolean で扱いたい場合は fromJson(needs.check.outputs.is_holiday) のように変換すると良いでしょう。

まとめ

この記事では、GitHub Actionsを使った様々な自動化の手法を紹介しました。

公式が提供するActionの他にも、世の中には有用なActionがたくさんあります。

サードパーティ製のActionの利用については、「要件を満たせるか」「セキュリティ上の懸念はないか」「継続的なメンテナンスが期待できるか」等が選定の基準となるでしょう。

前回の記事では GitHub Actions高速化の事例 を書いておりますので、合わせてご覧いただけたらと思います。

弊社の他のGitHub Actions活用事例は、次のスライドで紹介しております。

こちらの発表については、connpassのイベントページにアーカイブ動画へのリンクを載せております。皆様の参考となれば幸いです。 findy.connpass.com

ファインディでは一緒に会社を盛り上げてくれるメンバーを募集中です。興味を持っていただいた方はこちらのページからご応募お願いします。

herp.careers

GitHub Copilotの効果は本物?論文から読み解く開発生産性の真実

はじめに

こんにちは。プロセス改善・アジャイルコーチで、Tech Blog編集長の高橋(@Taka_bow)です。

皆さんは、2021年6月に生まれたGitHub Copilotを利用していますか?

この生成AIベースのコーディング支援ツールは、コードの自動補完や生成、関数の自動生成、エラー修正支援など、開発者の作業を多面的にサポートします。

ファインディでは2023年3月から導入し、開発チーム全員が日常的に活用しています。Findy Team+で効果を測定した結果、コーディングの効率化やコミュニケーションコストの削減、さらには開発者の満足度向上など、多くの利点が確認されました。

今回は、このようなソフトウェア開発における生成AIの影響を分析した最新の論文を紹介します。GitHub Copilotが開発プロセスにもたらす変化や、開発者の生産性への影響についての研究が書かれた、興味深い論文です。

生成AIが高度なスキルを要する仕事に与える影響

2024年9月5日、GitHub Copilotに関する1つの論文がプレプリントサーバーのひとつSSRN(Social Science Research Network)に公開されました。

papers.ssrn.com

直訳すると

「生成AIが高度なスキルを要する仕事に与える影響:ソフトウェア開発者を対象とした3つのフィールド実験からの証拠」

といったところでしょうか。

査読前論文なので、現在は誰でも読むことが出来ます。

この論文は、Kevin Zheyuan Cui氏(プリンストン大学)、Mert Demirer氏(マサチューセッツ工科大学)、Sonia Jaffe氏(マイクロソフト)、Leon Musolff氏(ペンシルベニア大学ウォートン校)、Sida Peng氏(マイクロソフト)、およびTobias Salz氏(マサチューセッツ工科大学)によって執筆されたもので、大規模な実験の結果を分析した科学的アプローチの成果が記されています。

実験の概要

この研究では、GitHub Copilotの効果を検証するため、大規模なランダム化比較試験が行われました。実験の舞台となったのは、Microsoft、Accenture、そして匿名のFortune 100エレクトロニクス製造会社の3社です。

驚くべきことに、この実験には実に4,867人もの開発者が参加しました。

参加者は2つのグループに分けられ、一方にはGitHub Copilotが提供され、もう一方は従来の開発手法を継続しました。この比較により、GitHub Copilotが本当に開発者の生産性を向上させるのか、客観的に検証することが目的でした。

また、各社の実験期間は次の通りです。

  1. Microsoft:2022年9月初旬から2023年5月3日まで(約7ヶ月間)
  2. Accenture:2023年7月末から2023年12月まで(約4ヶ月間)
  3. 匿名の大手企業(Fortune 100):2023年10月から2ヶ月間(段階的にロールアウト)

このような実験の設計により、異なる企業環境や期間での GitHub Copilotの効果を包括的に評価することが可能となりました。

具体的な成果

実験結果は、GitHub Copilotの効果を明確に示しています。

GitHub Copilotを使用した開発者グループでは、次のような顕著な改善が見られました。

  • タスク完了数: 平均で26.08%増加(標準誤差: 10.3%)
  • コミット数: 13.55%増加(標準誤差: 10.0%)
  • コードコンパイル回数: 38.38%増加(標準誤差: 10.0%)

これらの数字は、GitHub Copilotが開発作業全体の効率を確実に向上させていることを示しています。特筆すべきは、経験の浅いジュニア開発者への効果です。このグループでは、

  1. GitHub Copilotの採用率がより高く
  2. 生産性の向上がより顕著

であったことが報告されています。このことから、GitHub Copilotが特にキャリア初期の開発者のスキル向上と生産性増加に大きく貢献する可能性が示唆されています。

シニア開発者には控えめな効果

この研究で特に注目すべきは、GitHub Copilotがジュニア開発者とシニア開発者に与えた影響の違いです。

ジュニア開発者への影響

GitHub Copilotは、経験の浅い開発者に対して特に大きな効果を示しました。

  • 新しいコードの書き方や構文を効率よく学習
  • タスクの進捗が大幅に向上
  • プルリクエスト数が40%増加(シニア開発者は7%)

これらの結果から、GitHub Copilotはジュニア開発者にとって単なる補助ツールを超えた学習ツールとしての役割を果たしていると考えられます。

シニア開発者への影響

一方、シニア開発者に対する影響は比較的小さいものでした。これには次のような要因が考えられます。

  • すでに確立された作業スタイルがある
  • 新しいツールの採用に対する慎重さ

詳細な比較

次の表は、ジュニアとシニア開発者におけるGitHub Copilotの効果の違いを示しています。

項目 ジュニア開発者 シニア開発者
プルリクエスト増加率 40% 7%
コミット数増加率 21% 16%
ビルド数増加率 29% 13%
GitHub Copilot採用率 82.1% (±2.1pp) 76.8% (±2.1pp)
採用後1ヶ月後の継続使用率 84.3% 74.8%
GitHub Copilot提案受け入れ率 25.2% 24.7%

注:この研究では、会社での採用時の職位や在職期間に基づいて開発者を「ジュニア」と「シニア」に分類しています。具体的な基準については詳細が明らかにされていません。

ツール採用パターンの違い

実験結果から、GitHub Copilotの初期採用率は予想外に低かったことが分かりました。

Microsoftでは最初の2週間で採用率が42.5%にとどまり、リマインダー後に64%まで上昇。Accentureでは全体で約60%の採用率でした。

この結果は、新しいツールの導入には単なる提供以上のものが必要だということを示しています。適切なトレーニングやサポートが不可欠で、段階的な導入や定期的なリマインダー、効果的な使用法の教育セッションなどが有効な戦略となりそうです。

これらの知見は、GitHub Copilotに限らず、新技術の導入時に直面する一般的な課題を反映しています。単にツールを導入し、現場任せにするだけでは、効果的に活用できないでしょう。急速に進化する開発環境では、新ツールを戦略的に導入し、継続的にサポートすることが、組織の競争力を保つうえで極めて重要です。

補足:Accentureの実験初期のデータ破棄(論文付録D)

Accentureの実験には意外な展開がありました。2023年4月に同社が実施した大規模なレイオフ(19,000人の従業員削減)により、当初の実験が中断を余儀なくされたのです。

このレイオフは実験にも大きな影響を与えました。

  • 実験参加者の42%が影響を受ける
  • データの質に問題が生じる
  • GitHub Copilotの使用状況や採用データの記録が不十分に

結果として、この初期実験のデータは信頼性に欠けるものとなりました。しかし、204人の開発者に絞って行った分析では、次のような傾向が見られました。

  • プルリクエスト数: 39.18%減少 (標準誤差: 36.78%, 統計的に有意ではない)
  • コミット数: 43.04%増加 (標準誤差: 38.80%)
  • ビルド数: 12.33%増加 (標準誤差: 53.60%)

これらの結果は統計的な信頼性が低く、実験結果としては参考程度にとどめるべきでしょう。

おわりに:試されるのは「人間」

この研究から、GitHub Copilotがソフトウェア開発者の生産性向上に確かな効果をもたらすことが明らかになりました。特に、ジュニア開発者への顕著な効果は注目に値します。

一方で、シニア開発者への効果が限定的だった点も興味深い発見です。これは、経験豊富な開発者がすでに高いスキルを持ち、AIのサポートをそれほど必要としていない可能性を示唆しています。

しかし、ジュニア開発者がAIの提案を鵜呑みにするリスクも考慮する必要があります。ここで、シニア開発者によるコードレビューの重要性が一層高まると言えるでしょう。

調査会社の米ガートナーが発表した内容によると、AI コードアシスタント(生成AI)に関するマジック・クアドラントと共に、次のような予測がなされていました。

戦略的計画の仮説

  • 2027年までに、ソフトウェア開発ライフサイクル(SDLC)のあらゆるフェーズを拡張するためにAIを活用するプラットフォームエンジニアリングチームの割合は、5%から40%に増加する。
  • 2027年までに、80%の企業がAIで拡張されたテストツールをソフトウェアエンジニアリングツールチェーンに統合しており、これは2023年初頭の約15%から大幅な増加となる。
  • 2027年までに、AI生成コードに対する”ヒューマン・オーバーサイト”(人間がAIに対して動きを見たり止めたりできる)*1 が不足しているために、本番環境に流出するソフトウェア欠陥が25%に達し、2023年の1%未満から大幅に増加する。
  • 2028年までに、90%の企業のソフトウェアエンジニアがAIコードアシスタントを使用するようになり、2024年初頭の14%未満から増加する。
  • 2028年までに、生成AI(GenAI)の使用により、レガシーアプリケーションのモダナイゼーションコストが2023年の水準から30%削減される。

Figure 1: Magic Quadrant for AI Code Assistants https://www.gartner.com/resources/808000/808075/Figure_1_Magic_Quadrant_for_AI_Code_Assistants.png?reprintKey=1-2IKO4MPE

ここでも、人間側によるチェックが不足することでソフトウェア欠陥の上昇が予測されており、結局のところ、AIツールの活用と人間の経験や判断力のバランスが、質の高い開発プロセスの鍵となりそうです。

私たちに求められるのは、技術の進化を単に観察するだけでなく、それを最大限に活用しつつ、人間ならではの創造性や洞察力を発揮していくことです。この新しい時代の開発環境で、私たちはどのような価値を生み出していけるでしょうか。その答えを、皆さんと一緒に見つけていきたいと思います。

お知らせ!

現在、私と一緒にイネイブリングチームの立ち上げを行うメンバーを探しています!

イネイブリングチームは、単なる開発支援を超えた重要な役割を担います。

  • 組織全体のエンジニアリング力を向上
  • 開発スキル向上のためのトレーニングやワークショップを実施
  • プロセス改善の提案とコーチングを行い、開発生産性とDevExを向上
  • 社内外のエンジニアを対象とした活動を展開

このチームで、ファインディの成長エンジンとなりませんか?興味がある方は、ぜひこちらをクリックしてみてください↓

herp.careers

他にも、ファインディでは一緒に働くメンバーを募集中です。

herp.careers

*1:AIの文献で良く出てくる"human oversight"は適した日本語訳がなく、一旦このように訳した

ファインディでのGitHub Actions高速化の事例

ファインディ株式会社でフロントエンドのリードをしております 新福(@puku0x)です。

弊社では、数年前に社内のCI環境をすべてGitHub Actionsに移行しました。

この記事では、弊社のGitHub Actions活用事例の内、CI高速化についてご紹介します。

なぜCI高速化に力を入れるのか

当ブログをはじめ弊社では、たびたびCI高速化の大切さについて言及しています。

これはなぜでしょうか?

開発が進むにつれて、コードベースが肥大化し、CIの待ち時間が増えていくのは皆さんにも経験があると思います。

CIの待ち時間が長いとついレビューを放置してしまいがちです。 レビューが遅いとブランチの生存期間が伸び、コンフリクトの発生確率が上がります。 コンフリクトを解決しても、CIが遅い状態ではまた同じことの繰り返しとなるでしょう。

GitHubの調査では、開発者は多くの時間をCI待ちに費やしていると報告されています。

github.blog

見方を変えると、CI高速化はコーディングの効率化と同程度のインパクトがあると言えます。

チームの開発生産性を支える基盤として、弊社はCI高速化に力を入れているのです。

CI高速化

キャッシュの活用

弊社では、actions/cache を使って、依存関係のインストールを省く工夫を取り入れています。

ここでは例として、フロントエンド系のリポジトリのワークフローを紹介します。

- uses: actions/setup-node@v4
  id: setup_node
  with:
    node-version: 20

- uses: actions/cache@v4
  id: cache
  with:
    path: node_modules
    key: ${{ runner.arch }}-${{ runner.os }}-node-${{ steps.setup_node.outputs.node-version }}-npm-${{ hashFiles('**/package-lock.json') }}

- if: steps.cache.outputs.cache-hit != 'true'
  run: npm ci

フロントエンド周りのCIを組んだことのある方はピンと来たかと思います。

このワークフローでは、node_modules ディレクトリをキャッシュしています。

npm公式では非推奨とされていますよね?

なぜこのような書き方でも大丈夫なのでしょうか?その秘密はキャッシュのキーにあります。

key: ${{ runner.arch }}-${{ runner.os }}-node-${{ steps.setup_node.outputs.node-version }}-npm-${{ hashFiles('**/package-lock.json') }}

キャッシュキーとして、OSやNode.jsのバージョン、パッケージマネージャーの種別などが細かく設定されています。

node_modules ディレクトリのキャッシュが非推奨とされる理由は、異なる環境で実行されることによるファイルの不整合を防ぐためです。これに気を付けていればキャッシュしても良いのです。
※最近のGitHub ActionsではArmランナーが利用できるため、キャッシュキーにCPUアーキテクチャを追加するとより堅牢になるでしょう。

node_modules がキャッシュヒットしなかった場合を考慮して、.npm ディレクトリのキャッシュも含めると次のようになります。

- uses: actions/setup-node@v4
  id: setup_node
  with:
    node-version: 20

- uses: actions/cache@v4
  id: cache
  with:
    path: node_modules
    key: ${{ runner.arch }}-${{ runner.os }}-node-${{ steps.setup_node.outputs.node-version }}-npm-${{ hashFiles('**/package-lock.json') }}

- uses: actions/cache@v4
  if: steps.cache.outputs.cache-hit != 'true'
  with:
    path: |
      ~/.npm
    key: ${{ runner.arch }}-${{ runner.os }}-node-${{ steps.setup_node.outputs.node-version }}-npm-${{ hashFiles('**/package-lock.json') }}
    restore-keys: ${{ runner.arch }}-${{ runner.os }}-node-${{ steps.setup_node.outputs.node-version }}-npm-

- if: steps.cache.outputs.cache-hit != 'true'
  run: npm ci

弊社の場合では、これでおよそ20秒〜30秒ほど高速化できました。

ジョブの並列化

バックエンドのテストを例に挙げます。このワークフローでは、matrix 機能を用いてテストを10並列で動作させるようにしました。

strategy:
  matrix:
    ci_node_index: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
steps:
  - name: Test
    env:
      CI_NODE_TOTAL: ${{ strategy.job-total }}
      CI_NODE_INDEX: ${{ matrix.ci_node_index }}
    run: |
      # get spec files order by filesize
      TEMP_FILE_PATH=$(mktemp)
      git ls-tree -r -t -l --full-name HEAD | grep '_spec.rb' | sort -n -k 4 | awk '{ print $5 }' | ./scripts/ci/rspec_split_files.sh > $TEMP_FILE_PATH

      # echo outputs
      echo "====SPEC FILES COUNT===="
      cat $TEMP_FILE_PATH | tr ' ' '\n' | wc -l
      echo "====SPEC FILES===="
      cat $TEMP_FILE_PATH | tr ' ' '\n'

      # run rspec
      bundle exec parallel_rspec -- --format progress -- $(cat $TEMP_FILE_PATH)
#!/bin/bash

i=0
ret=()

while read -r line
do
  if [ $[i % $[CI_NODE_TOTAL]] = $[CI_NODE_INDEX] ] ; then
    ret+=($line)
  fi
  let i++
done

echo ${ret[@]}

単純にテストを均等配分するのではなく、ファイルサイズでソートするという工夫が施されています。これは、テスト実行時間がファイルサイズに比例するという仮定に基づいています。

これらの工夫により、実行時間が従来の約半分になるまで高速化できました 🚀

詳細は↓こちらの記事をご覧ください。 tech.findy.co.jp

Larger Runners

基本的には並列化でCI高速化を目指しますが、難しい場合はLarger Runnersを使うのも手です。
(並列化の可否の判定は、テスト対象ファイルの分割を外部から制御可能かどうかで決めています)

Larger Runnersは、契約しているプランが「GitHub Teamプラン」または「GitHub Enterprise Cloudプラン」の場合に利用可能です。 最大で64コアまでスペックアップできるらしいです。いつか使ってみたいですね!

docs.github.com

Armランナーについては先日GAとなったこともあり、積極的に移行を検討するようになりました。

github.blog

3割程度のコスト削減ができることから、既に社内のいくつかのプロジェクトではLinux Armランナーに完全移行しています。

2024年9月現在では、ruby/setup-ruby などサードパーティの対応が進んでいないものもあります。移行の際は動作検証を十分にしておくと良いでしょう。

参考までに、弊社のフロントエンドでの高速化の例を示します。

Build Test
2コア 15m8s 12m7s
4コア 8m38s 6m56s

スペックアップするとコストは増えますが、その分CIの待ち時間の削減が期待できます。実質的な負担に大きな変化が無い場合は強気でスペックアップしていきましょう 💪

まとめ

いかがでしたでしょうか?

この記事では、弊社のGitHub Actions活用事例の内、CI高速化についてご紹介しました。

CIの待ち時間については、「継続的デリバリー」の書籍を参考に 10分以内 を目指すと良いでしょう。

www.kadokawa.co.jp

実際に弊社では、これらの取り組みを行う前は1PRあたり15分〜20分ほどかかっていたCIが、10分以内の完了を目指して取り組んできた結果、平均5分程度まで高速化できた例もあります。

弊社にはCIの整備に関心の高いメンバーが多く在籍しております。勉強会等でお会いする機会がありましたらぜひお声がけください。

こちらの発表については、connpassのイベントページにアーカイブ動画へのリンクを載せております。 findy.connpass.com

次回へ続きます!👋

ファインディでは一緒に会社を盛り上げてくれるメンバーを募集中です。興味を持っていただいた方はこちらのページからご応募お願いします。

herp.careers

【エンジニアの日常】エンジニア達の人生を変えた一冊 Part1

こんにちは。

Findy で Tech Lead をやらせてもらってる戸田です。

突然ですが皆さんは本を読みますか?

エンジニアという職業柄、技術書やビジネス書など、様々なジャンルの本を読む機会が多いのではないでしょうか?

そこで今回は、人生を変えた一冊と題して、弊社エンジニア達のお気に入りの一冊を紹介していきます。

それでは見ていきましょう!

人生を変えた一冊

戸田

ソフトウェア・ファースト あらゆるビジネスを一変させる最強戦略

及川卓也さん著の本で、DX(デジタルトランスフォーメーション)の本質を理解するためには必読の一冊です。

2024年9月には内容を大幅改定した第2版が発売予定とのことで、こちらも合わせてチェックしておきたいですね。

内容としては、日本のIT史の振り返りから始まり、現在の問題点の指摘、そしてDXの在り方、進め方について詳しく解説されています。

また、これからの時代の強い開発組織の在り方や作り方にも言及されており、エンジニアだけではなくマネージャーや経営者の方にも是非読んで欲しい一冊になっています。

実際に読み進めていくと共感できる部分が多く、「わかっているけど中々実行に移すことができない」という方にヒントを届けてくれるような内容でした。

この本が世に出た当時、自分は30代に入ったばかりで、いわゆるマネージャーとしてのキャリアを少しかじっていた頃でした。

経営陣がやって欲しいことと開発組織がやりたいことがズレている感覚が少なからずあり、この本を読んだことによってそれらがクリアになり、実際に実行に移すことが出来たことがありました。

自分が抱いていた感覚というものは当時所属していた組織特有のものではなく、社会全体の問題であるということを再確認できたため、逆に割り切って行動に移すための勇気を貰うことができました。

おそらくこの本と出会っていなかったら、今でも違和感と葛藤して何も進められないままだったと思います。そういうこともあり、エンジニア人生のターニングポイントとなった1冊になったと思います。

ジョナサン・アイブ

1冊と言っていながら、もう1冊の紹介をさせてくださいw

かのスティーブ・ジョブズが絶対的な信頼を寄せたデザイナー、ジョナサン・アイブ氏の生い立ち、学生時代、アップル入社後のiMac、iPhone、iPad、MacBook Airなど数々の革新的な製品づくりでの試行錯誤、社内での争いまでを描いた一冊です。

モノづくりに対する思考や姿勢、デザインに対する考え方など、エンジニアにも多くのヒントを与えてくれる内容になっています。

この本が世に出た当時、自分は20代中盤くらいで若く、これから何をしてキャリアを考えるべきなのか模索していた頃でした。その時にこの本と出会い、何気なしに読んでいくとアイブ氏のモノづくりに対する姿勢に驚かされました。

詳細は本を読んでいただきたいのですが、例えば新製品のデザインをする際、彼は数百、数千パターンのプロトタイプを作るそうです。

そのパターンなのですが、素人からみたらパッと見だと全く同じデザインに見えるそうです。しかしこれらは全て数ミリ単位で違うそうで、その違いを比べつつ、最終的なデザインに辿り着くそうです。iPhoneやMacbookなどのデザインも最初はこのようにして生まれたとのことで驚かされました。

これを読んだ時、自分が悩んでいたことが実はまだ甘い考えだったと気付かされました。世界的プロダクトを生んだデザイナーだとしても、まず最初に泥暗いことをやり切っているからです。

自分程度のエンジニアが今の段階でウダウダ悩んでいる暇があったら、目の前のことに集中して1個ずつ泥暗いことをやり切り続け、引き出しを増やすことに集中しようと決意できました。

おそらくこの本と出会っていなかったら、今でもウダウダ悩んで手を動かしていなかったかもしれません。この本もまた、エンジニア人生のターニングポイントとなった1冊になったと思います。

高橋

ファインディでエンジニア兼プロセス改善コーチをしている高橋(@Taka_bow)です。

1兆ドルコーチ シリコンバレーのレジェンド ビル・キャンベルの成功の教え

シリコンバレーの伝説的コーチでありスティーブ・ジョブズの親友でもあったビル・キャンベル。

『1兆ドルコーチ』は、彼の様々な教えを記録した本です。著者は元Google会長のエリック・シュミット、元Google SVPのジョナサン・ローゼンバーグ、元Googleで経営コンサルタントのアラン・イーグルの3名。(すでに著者がすごい面子!)

この3人のみならず、ビルの指導を仰いだ起業家たちの多くが今日のテクノロジー業界を牽引しています。現在のGAFAMの隆盛は、ビルの影響力なくしては語れないと言われています。

私が好きなエピソードの1つに、Googleがマネジャーを「全廃」し管理職のいない組織を作った直後の、ラリー・ペイジとビルのやりとりです。

ビルは言います。

「ここにはマネジャーを置かないとダメだ」

ラリーは答えにつまった。ちょうどマネジャーを全廃したばかりで、彼は結構満足していたのだった。(後略)

二人はどちらも譲らず、しばらく堂々めぐりの議論を続けた。とうとうビルはラリーの流儀にならって、それならエンジニアに直接聞いてみればいいと言った。(中略)ビルはその一人に、マネジャーがほしいかと訪ねた。

ええ、という返事だった。

なぜだ?

「何かを学ばせてくれる人や、議論に決着をつけてくれる人が必要だから」

その日彼らは数人のソフトウェアエンジニアと話したが、答えはほとんど同じだった。

このエピソード1は、たとえテック企業でもマネージャーがきわめて重要な存在であることを示しています。エンジニア組織のマネジメントで悩みがあると、今でも読み返します。

FIndy バックエンドエンジニアの森 @jiskanulo です。

アジャイルサムライ――達人開発者への道

アジャイル開発を進める上でのチーム作り、見積もり計画、日々の開発と多岐にわたって解説があり入門書としておすすめです。

アジャイルサムライ日本語訳版が出版された2011年当時、IT業界のエンジニアが集まり各章を読み合わせる輪読会のコミュニティが日本各地で生まれました。 このコミュニティは次第に盛り上がり、翌2012年には原著者のJonathan Rasmussonさんを日本にお招きして参加者100人超えの大イベント Agile Samurai Dojo Gathering 2012 を開催するに至りました。 蒔かれた種子は今も世界でも芽吹いているでしょう。

私個人の当時の思い出を記します。 2010年に当時勤めていた企業を退職、数ヶ月の無職期間を経て新しい会社に勤めていました。 ユニットテストを導入して安全に開発するための仕組みづくり、営業メンバーの業務効率化のためのツール作成、社内サーバーの管理やデータセンターへのラッキングなどなど会社とプロダクトに貢献するべく取り組んでいました。

そんな日々を1年ほど過ごし、ただ作業をこなすだけで1日終わってしまう作業者になっているなと感じていました。  一人でできることは限界があるとも感じており、チームを組んでよりよい課題解決のやり方を模索しどうすればいいプロダクトを作れるのか、そもそもいいプロダクトとは…と色々なことに思い悩んでいました。

思い悩んでいるなかでアジャイルサムライに出会い、この本を通じてコミュニティに参加して他の方と交流を深めることで同じような悩みを抱えている仲間がたくさんいることを知りました。

ファインディ社に入社してから、この本にある「達人開発者」の振る舞いをあらためて心がけようとしています。

まとめ

いかがでしたでしょうか?

現在、ファインディでは一緒に働くメンバーを募集中です。

興味がある方はこちらから ↓ herp.careers


  1. (引用)エリック・シュミット. ジョナサン・ローゼンバーグ. アラン・イーグル. 櫻井 祐子 (翻訳). 1兆ドルコーチ シリコンバレーのレジェンド ビル・キャンベルの成功の教え. ダイヤモンド社, 2019/11/14, p.63