「Finatextの考える最強のGitHubリポジトリ選手権」を開催しました

--

Photo by Rubaitul Azad on Unsplash

0. はじめに

こんにちは!2023年度、Finatextに新卒入社したTakuma Kobayashiと申します。

突然ですが皆さんは、普段リポジトリをどれくらい弄っていますか?コードレビューやCI、コード生成なんかは定常的なタスクの代表として扱われることも多いと思いますが、そういう繰り返しはなんとかして簡素化、自動化したくなるのがエンジニアの性ではないでしょうか。

そこで、「Finatextの考える最強のGitHubリポジトリ選手権」と題し、普段バラバラに開発を行っているチームがGitHub周りの知見を共有する会を開催しました。この記事では、当日の内容をピックアップしてお届けします!

1. 「Finatextの考える最強のGitHubリポジトリ選手権」とは

1–1. 企画概要

フロント・バックなど開発のジャンルは問わず、普段の開発プロセスをいい感じにするために各チームが行っていることを発表します。現時点で完成していなくても、理想形でもよし。ルールはたった一つ、

  • 0からでも数日で導入できるくらいのコンパクトなものに限る

です。選手権と銘打ってますが特に順位はつけず、独自に発展を遂げている各チームの知見を合流させ、全社的に開発体験を向上させることが目的です!

1–2. 参加チーム・人数

当日は証券ドメインから2チーム、データドメインから2チーム、そしてPlatform Teamの計5チームが参加し、聴講者も含めてインターナルスペースいっぱいのエンジニアが集まりました。

↓Platform Teamについてはこちらもご覧ください↓

2. 発表ピックアップ

ここからは、証券ドメインの2チームの発表内容を、私とエンジニアの山﨑からそれぞれ紹介します。

2–1. チームA(発表者:小林)

改めまして小林です。私はもともとFinatextグループで長期インターンをしておりまして、データドメインでPDFからのデータ抽出などを担当した後、証券ドメインでサーバーサイドエンジニアとしてAPI開発やCI/CD整備などを行っていました。選手権の開催時点ではまだインターン生でしたが、メンターの強い勧めもあり、開発体験の向上のために発表者としての参加を決めました。

チームAはFinatextの証券プラットフォーム「BaaS」の開発・保守を行っているチームです。BaaSはいくつかのマイクロサービスによって構成されており、それぞれのサービスが汎用的な機能を提供しています。

↓BaaSの詳しい説明はこちら↓

チームAからは、以下の3つを発表しました。

①GitHub Actionsを用いたPRとBacklogステータスの同期

Finatextではプロジェクト管理にnulabのBacklogというサービスを利用しています。運用上の取り決めとしてチケットとPRの切り分け単位は一致していることが多く、それ即ちPRのマージがチケットのcloseに結びつく、ということになります。

ここで、従来は開発の進捗があるたびに手動でステータスを更新したり、PRのリンクをコメントしたりしていたのですが、この作業に漏れが起こる場合があり、運用の課題を抱えていました。

運用がルールベース化しているのなら、自動化したいのがエンジニアの常。Backlog APIとGitHub Actionsを組み合わせて、PRステータスとチケットステータスをリンクさせるworkflowを作成しました。

PRオープン時、PRのリンクをBacklogチケットにコメント
PRクローズ時に、Backlogチケットのステータスを完了にする

画像のようにPRタイトルに課題キー(Backlogでは{プロジェクトコード}-{チケット番号}の形で与えられる)を付けておくと、それをキャッチして該当チケットの情報を取得します。今回はPRがOpenになったときにチケットに対応PRのリンクをコメントし、PRがマージされたときにチケットステータス「完了」に変更するようにしてみました。

Backlog APIを叩くトリガーとなるPRの例
Backlog APIを叩くトリガーとなるPRの例
Backlogチケットに表示されるログ

他にもさまざまな機能が用意されているため応用が可能であり、例えば担当者の変更など、さまざまなユースケースが考えられます。ブランチやPRの情報を利用してAPIを叩くだけなのでカスタマイズ性も高く、開発とタスク管理をより密に行うことが期待されます!

一点、参加者からのコメントで、Jiraというプロジェクト管理ツールでは機能としてGitHubとの連携があり、似たようなことがデフォルトで可能という指摘がありました。個人的には、Jiraはユーザー単位の課金なのが辛そう(Backlogはプロジェクト単位)だなと思っているのですが、第二の選択肢としてはアリそうです。

②ブランチ戦略

Gitを扱う上での一大テーマとして、「ブランチの扱い」があると思います。ブランチ戦略におけるデファクトスタンダードであるところのGitflowでは、main から develop を生やしてfeatureを取り込んでいき、releaseはまた別で管理する、とされていますが、こうするとmaindevelopの差分がどんどん大きくなってしまい、最後developを取り込むときに苦労する、というケースは少なくありません。

そこでBaaSチームでは、トランクベース開発(に近いブランチ戦略)を採用しています。すなわち、細かい修正単位でmainから開発ブランチを切り、レビューが済んだらすぐにマージし、開発環境にデプロイしています。本番環境へのリリースはreleaseタグを用いて行っており、検証の済んでいない変更が入っている場合にはrevertなどの対応をとっています。

BaaSチームで主に用いられているブランチ戦略の模式図

この戦略をとる場合、開発者はブランチ差分の大きさを気にする必要はほとんどありません。また、変更が大きくなりそうな場合は、外側の層(Service層など)から順に入れていく、feature flagを用いるなどしてアプリケーションロジックに影響がないようにする、といった対応を取ることができます。

ブランチ戦略には一長一短があり、さらにある程度大規模の開発を長時間行わないとメリデメが見えてきづらいですが、チームやプロダクトの性質に合った開発手法を模索していけるといいですね。

③LoopTest、ランニングテスト

システムのテストにはさまざま種類がありますが、CI上で行われるテストは

  • エンジニアの稼働時間内にしか行われない
  • Actionが従量課金制であることを考えると、長いファジングテストなどはやりにくい

というような課題が考えられます。一方で証券システムには

  • 大量の注文を捌くため、トランザクション管理を丁寧にやる必要がある
  • 特定の時間をもって処理が切り替わるケースがそれなりにある

という背景があり、トランザクションや時刻が絡むテストはリッチにしていきたいというインセンティブがありました。

現状はActionsのスケジュールトリガーをcronで指定して土日や深夜にテストを実行したりしているのですが、うるう年や月跨ぎといった特殊なケースまでランニングテストでカバーするのは難しく、時刻をテストのinputとして明示的に入れる仕組みを考える、などが今後の課題です。

2–2. チームB(発表者:山﨑)

初めまして。昨年の9月から証券ドメインでソフトウェアエンジニアをしている山﨑です。普段はサーバーサイドやインフラを担当しています。私が携わっているプロジェクトでは、すでに多くの便利ツールが導入されていたので、その仕組みを改めて理解し直す良い機会だと思い、今回の企画に参加させてもらうことにしました。

チームBでは「BaaS」上に展開する複数の証券サービスの開発・保守を担当しています。今回はそれらのサービスを管理するGitHubリポジトリ内の設定から、良さそうなものを4つほどピックアップしました。

①OpenAPIを使ったコードの自動生成

チームB内のほとんどのプロジェクトでは、フロントエンドとバックエンドのコードを別リポジトリで管理しており、一部のプロジェクトでは、スキーマ駆動開発に近い手法を採っています。

開発の流れとしてはまず、開発者が OpenAPI ファイルと自動生成されたコードを、バックエンドのリポジトリに追加します。フロントエンドのリポジトリで GitHub Actions のワークフローが日時で実行されるようにスケジューリングし、バックエンドのリポジトリに格納された OpenAPI ファイルからフロントエンドのコードを生成します。そして、メインブランチから差分が生じている場合はPRを自動で生成するようにしています。

特にサービスリリース前の開発初期の段階では、一度定義したOpenAPIの定義を変更する場面があるかと思いますが、そのようなときにフロントエンドのコードが追従できていなかった、ということを防ぎやすくなると思います。

swagger更新時に自動生成される、フロントエンド変更のPR

②データベースの情報をドキュメント化

データベースのスキーマ情報は、開発者が実装時に必要になるだけではなく、PMやビジネスサイドの方がデータ分析等をする際に参照したりと、可視化されていると便利なことが多いと思います。

そこで tbls というツールを使って、スキーマやER図などを自動生成し、リポジトリにコミットするようにしています。

また、lintの機能を使ってidやタイムスタンプを管理するカラムを除く、全てのカラムのコメントを必須にしています。まだ運用はできていませんが、将来BIツールなどを使うときにカラムコメント等もインポートできれば、さらにデータが探しやすくなるという狙いがあります。

tblsで生成されるドキュメント。テーブル定義やカラムの説明が書かれている。

③PRのdiff自動修正

上述の自動生成系のファイルの作成や、lintの実行を忘れたままPRを作成していまうことは、開発の際に気を付けていても時折発生していまうかと思います。そのようなときに、わざわざ手元でlint等を実行し直してからプッシュしなくても、GitHub上で差分を自動で生成し、元のPRに対してPRを作成してくれる actions-diff-pr-management というツールを導入しています。

開発時のちょっとしたストレスを減らしてくれるだけではなく、本来コミットされるべき変更がなされないまま、PRがマージされてしまうことを防ぐことができます。

自動生成されるPR。lintやドキュメント生成などの差分が、元のPRに取り込まれる。

④yamlのフォーマット

OpenAPI などの設定を yaml ファイルに書くことは多いかと思いますが、フォーマットを統一するために yq というツールを使っています。

yq は jq のような JSON や yaml を処理をするためのツールですが、inplace オプションを使うことで、フォーマットを修正した後に元のファイルを上書きすることが可能です。

ディレクトリ内のyamlファイルを修正するコマンドの例:

find . -name "*.yml" -type f -print0 | xargs -I{} -0 yq -i '' {}

このようなコマンドをCIに組み込んでいます。

3. 参加した感想

小林

社内イベントとはいえ、LTのようなものに登壇する機会は初めてでしたが、発表というアウトプットそれ自体、またアウトプットを意識してインプットを行うことは、かなり新鮮な刺激になりました。特にブランチ戦略やリッチなテストについては、ある程度大規模な開発で中〜長期間取り組んでみないとわからないことも多いと思うので、実務と絡めながら知見を深めていくことは大切だと感じました。同時に、このような機会がインターン生に対しても広く開かれているFinatextの文化は、自分のようなエンジニアがグッと成長していくのに、これ以上なくピッタリな環境だと思いました!

山﨑

普段は一緒に仕事をすることが少ない、他チームの知見を得ることができて良い機会となりました。「0からでも数日で導入できるくらいのコンパクトなものに限る」という制約があったため、発表内容は比較的小さな工夫が中心となりましたが、それでもこれらの工夫によって、かなりの時間を節約し、開発がしやすくなっていることを改めて実感しました。これらを導入してくれた他のエンジニアに感謝しつつ、自分でもさらに開発がしやすくなる工夫を入れていきたいと思いました。

さいごに

Finatextグループでは、全ドメインでエンジニアを募集しています。以下のページで事業内容や開発環境についてまとめているので、興味がある方はぜひチェックしてみてください!

--

--