ブログ

FLYWHEEL Standard のご紹介

こんにちは。ソフトウェアエンジニアの yuku です。
これは FLYWHEEL Advent Calendar 2019 6 日目の記事です。
フライウィールではエンジニアや各リポジトリが従うべきさまざまな標準を FLYWHEEL Standard として定め、GitHub 上で公開しています。今回の記事ではどういうモチベーションから FLYWHEEL Standard を整備するに至ったのか、この取組は一体何を目指しているのか、そして定めたことでどういうことが起き始めているのか、といったことを紹介します。

背景・モチベーション

フライウィールはまだ人数も少ないので、活発に開発されているリポジトリの数はそんなに多くありません。しかし、リポジトリごとに開発環境のセットアップ手順が大きく異なるため、開発に参加するためにはまず README を読みながら一つ一つ手順を踏んでいかなければならず、しかも README の記述が古くなっていて、メイン開発者の人に助けを求めなければならないことが多々ありました。加えてセットアップ時にシステムグローバルにツールをインストールするものもあり、他のリポジトリとローカルマシン上で共存できなくなる懸念もあります。
フライウィールはチームに分かれてソフトウェアを開発しています。簡単に言えば、隣のチームのプロジェクトに気軽にコントリビュートすることが難しい状態になりつつありました。
普段は自分がメインで取り組んでいるプロジェクトのリポジトリで作業をすることが多いですが、隣のチームの開発にももっと気軽に参加できるようにしたいですよね。実際にプルリクエストを送るかはさておき、それができるようにしておくことにはメリットがあります:

  • コードを見れる人が増えれば、不測の事態が発生したときに対応できる可能性が高まります。
  • 自分の開発環境がいつなんどき壊れるとも知れません。そのような時に環境を復旧することが容易になります。
  • 新しく入ってきた人がキャッチアップすることも容易になります。
  • (こうして外に向けて取り組みを発信することができます)

このような現状認識のもと、エンジニアが集まるミーティングで問題意識と目指したい姿を話したところ、すんなりと納得してもらえたので、 FLYWHEEL Standard の策定に着手しました。

スタンダード

2019 年 12 月 6 日時点で 2 つのスタンダードが定められています:

Setup Scripts

このスタンダードでは各リポジトリが bin/setup というスクリプトを提供しなければならないことを定めています。開発者はこのスクリプトを実行するだけで開発環境の構築が終わります。
しかしここで問題になるのが bin/setup を書くのが難しい、あるいは面倒くさいという事です。仮に Docker を使うとして、リポジトリごとに毎回 Docker をインストールするコードを書くのはあまりに冗長です。
そこで次に紹介する Local Environment スタンダードが出てきます。さまざまなリポジトリで共通して使われるツールをスタンダードで定義して、個々のリポジトリの bin/setup はそれらが存在する前提で記述してよいということにしました。
flywheel-jp/flywheel-standard リポジトリそのものが bin/setup をもっていて、これを実行することで Local Environment を満たすようにマシンがセットアップされるようにしました。これによって理論上 FLYWHEEL Standard に準拠しているリポジトリであれば:

  1. まず flywheel-jp/flywheel-standard の bin/setup を実行する
  2. 準拠しているリポジトリの bin/setup を実行する

の 2 ステップで環境構築が完了します(という世界を目指している)。
ちなみに bin/setup は Rails が標準で生成する同名のスクリプトに由来しています。

Local Environment

このスタンダードでは各リポジトリが開発者のローカル環境に対して期待していいことを定めています。
全てを Docker の中で行う、という人も世の中にはいますが、フライウィールでは全員が Mac を使っているためそこまで極端なことはせず、各プログラミング言語でよく使われるバージョンマネージャを指定するようにしています。こうすることで、 Python や Node.js の処理系はリポジトリ毎にバージョンを自由に決められるようにしつつ、リポジトリ間での競合しないようにしています。
Java だけは例外的に使えそうなバージョンマネージャが存在しなかったため Java 8 に固定されています。いずれかのタイミングでバージョンを上げなければならず、それが問題になりつつあります。
ミドルウェアは基本的に Docker を使うようにしています。

今後の予定

こうしてスタンダードを 2 つほど定めましたが、この 2 つで冒頭で述べたモチベーションの 5 割は達成できるのではないかと考えています。では残りの 5 割は何かと言うと:

  • CD の推進。ローカル環境からデプロイしているプロダクトがいくつかあります。デプロイのための環境は権限管理など特殊な要素が入りやすいため、ローカルからデプロイしていると他の人が手出ししにくくなります。
  • 言語ごとのコーディング規約などの統一。

ルールが多くなりすぎると逆に窮屈になってしまい、結果的にみんなが準拠してくれなくなってしまいます。それではスタンダードとして意味がないので、最低限のルールに留めたいと考えています。

その他の工夫

せっかくスタンダードを決めても、リポジトリがスタンダードに準拠しているか分からなければあまり意味がありません。ということで、 FLYWHEEL Standard に準拠していることを示す画像を shields.io を使って用意しました(少し下にある Slack のスクリーンショットを参照)。

何が起きつつあるか

最後に FLYWHEEL Standard を定めたことでどういうことが起きつつあるか、簡単に紹介します。
Local Environment と Setup Scripts を定めたのは数ヶ月前ですが、策定後すぐにはリポジトリを準拠させようという動きは、そのままではあまり生まれませんでした。今開発している人からすれば別に困っていないので、わざわざ時間をとって準拠させる必要がないのですね。
そこで、まずは自分が関わっているリポジトリを順次準拠させてまわることにしました。そして準拠するたびに Slack で宣伝をしていると、気がつけば少しずつスタンダードやっていこうという雰囲気になっていました。このへんの手軽さは小さな組織だからこそかなと思います。
flywheel-standard に準拠したところを slack で共有している様子
となりのチームに気軽にコントリビュートする、という観点でも効果が現れ始めているように感じます。具体的な話は書くことができませんが、私がメインでやっているフロントエンドのプロジェクトに、サーバサイドを担当しているエンジニアが出張してきてコードを書いてくれたりしています。
スタンダードを設定したことで、システムグローバルにツールをばかすかインストールするのはやっぱりダメだよね、みたいなことが再認識されてきたこともいい影響の一つかも知れません。これまでは環境構築のコストを避けるために、良くないと分かりつつやってしまっていた場面が散見されていました。

終わりに

冒頭のモチベーションでも書いたように、 今後新しく入ってくる人が素早く開発を始められるようにすることも FLYWHEEL Standard の大きな目的の一つです。フライウィールではデータの力で世界に貢献したいエンジニアを募集しています!