問題を早期発見して開発体験を上げる試み

はじめに

こんにちは。2022 年 7 月に入社したエンジニアの浅見(@astatsuya1)です。
今回は 20%ルールで実施した問題の早期発見をして開発体験を上げるために行ったことを紹介します。

コミューンの 20%ルールとは

業務時間の 20%を技術課題の改善に充てる事ができる取り組みです。詳しくはコミューンの20%ルールって何??に詳しく書かれているので、よろしければこちらもご覧下さい。

何をやるか考えた

入社して 2 ヶ月程経過し、commmune の開発スタイルに慣れてくると同時に、commmune が抱える技術的な強みや改善点が見えてきました。
大きな課題解決に取り掛かかりたい気持ちもありましたが、大きくなるまで残ってしまう課題を解決するにはそれなりの時間と気合いと技術力が必要です。
そこで 20 %ルールを活用し、時間と気合いがなくても出来る開発環境の改善をしようと考えました。

commmune の開発における問題と課題

問題:問題の発覚が遅くなると多くの人を巻き込んでしまう

commmune の実装開始からリリースまでのフローを説明すると

  1. ローカル環境で開発、テスト
  2. プルリクエストを出して他のメンバーがコードレビューをする
  3. 修正が必要であれば 1 に戻る、なければ開発環境に取り込む
  4. 開発環境でセルフチェック
  5. 修正が必要であれば開発環境を切り戻して 1 に戻る、なければ最大 3 つの変更が開発環境に取り込まれたタイミングで E2E テストを実施
  6. 問題があれば全ての変更を切り戻して 1 に戻る、なければ本番環境へリリース
  7. 本番環境でセルフチェック
  8. 修正点があれば全て切り戻して 1 に戻る、なければリリース完了

数週間に 1 度の頻度でリリースをするプロダクトも珍しくないと思いますが、commmune のウェブアプリは 1 日に数回リリースをしています。
いつでもリリース出来るようにするためには、開発環境が正しく動いている状態を維持する必要があるので、問題があったらすぐに切り戻しをしています。
問題発覚が後になるほどやり直す作業、関わる人が増えて行くという問題があります。

課題:出来るだけローカル環境で問題を検知したい

プルリクエスト上で 実行される CI で問題を検知する仕組みは既にあるので、開発環境に取り込む前にはある程度の問題を検知できていました。
しかし、コードレビューをしようとしたら CI が落ちていることや、繰り返しコメントされていることがいくつかありました。
1. ローカル環境で開発、テストで出来るだけ多くの問題を検知、解決出来れば関わる人も最小限に留まるので、ここで出来るだけ多くの問題を検知、解決することが課題だと感じました。

施策 ①:検知する項目を増やす

まずはコードレビュー時に繰り返しコメントされていた項目を検知出来るようにします。

リントでチェックする項目を増やす

commmune ではリンターに ESLint を使っています。
よく プルリクエストを レビューする時に見かけていた、意図せずに混入していたコードをチェックする設定を加えます。

ローカル開発のみでしか使用しないconsole.logに警告を出す

no-consoleという設定を追加しました。consoleでも意図的に残しているログもあるので、それらは許可しました。

// .eslintrc.json
{
  ...

  "rules": {
  ...

  "no-console": ["warn", { "allow": ["info", "warn", "error", "dir", "table"] }],
  }
}

ローカル開発でのみしか使用しないtest.only, test.skipに警告を出す

これらが残っていると実行されないテストがあるので危険な状態です。eslint-plugin-no-only-tests という便利なプラグインがあるので追加しました。

// .eslintrc.json
{
  ...
  "plugins": [
    "no-only-tests"
  ],
  "rules": {
  ...

  "no-only-tests/no-only-tests": [
    "warn",
    {
      "focus": ["only", "skip"]
    }
  ]
}

英語のスペルチェックをする

英語のスペルチェックをするためにCSpellを導入しました。
導入するとエラーが出てしまいましたが、全て修正してから導入するのは大変なので、まずは全てのエラーは無視して、これ以降スペルミスを混入させないようにしました。
進んでいるプロジェクトに導入する際の工夫はこちらに備忘録を書いているので、導入を考えている方は参考にしていただければと思います。

施策 ②:ローカルでも出来るだけ早く検知出来るようにする

ローカル開発中に問題を検知出来るタイミングを整理すると

  1. コードを書く時
  2. 書いたコードを保存する時
  3. コミットする時
  4. プッシュする時

上記 4 つになります。この中でも出来るだけ早いタイミングで問題に気がつけると原因の特定が容易になり開発体験が上がります。
極端な例ですが、1 分間で書いた 5 行のコードの中に問題があると分かれば、原因を探すのは 5 行です。
一方で 3 日かけて書いた 500 行のコードのどこかに問題があると、どこが問題なのかを探す作業が発生します。
出来るだけ早く問題に気がつけるメリットはここにもあります。

コードを書く時のチェック

Visual Studio Code の拡張を共有

commmune は各自好きな環境で開発していますが、多くのメンバーが Visual Studio Code を使っています。
Visual Studio Code には開発の手助けをする便利な拡張機能がありますが、拡張の存在を知らなければ便利さに気がつくことは出来ません。
.vscode/extensions.jsonというファイルに開発で必要な拡張を書いて共有します。先程名前の上がった ESLint, CSpell の拡張もあります。
こちらに記載した拡張は拡張機能の検索窓で@recommendedと入力すると全て見つける事ができます。
人によって有効にしたくない拡張があるかもしれません。その場合はインストールして無効化すれば良いので、便利だと思った拡張はどんどん共有して良いと思います。

推奨されている拡張一覧を検索

詳しい設定方法はこちらをご覧ください。

書いたコードを保存する時のチェック

差分があったファイルに関連するテストを実行

commmune ではテストツールに jest を使用しています。変更するたびにテスト実行コマンドを入力するのは手間がかかり、実行を忘れることがあります。
watch モードで常に jest を起動しておけばその心配はなくなります。
こちらは jest 標準の機能を使えば最後のコミット以降変更した箇所に関連があるテストのみを自動で実行してくれます。

// package.json
{
  test:watch: jest --watch
}

コミットをする時のチェック

リント、スペルチェックを実行

コードを書いた時点でエラーが出ていても気が付かずにコミットしてしまうこともあるので、ここでも問題がないか確認します。
元々 huskylint-staged を使ってフォーマットの確認は行っていましたが、リントとスペルミスの確認も行うようにしました。

// .lintstagedrc.js
const baseConfig = {
'*.{js,json,tsx,ts,md,yml}': ['prettier --cache --write', 'cspell --cache --no-must-find-files'],
'*.{tsx,ts}': ['eslint --cache --max-warnings=0'],
}

重要なオプションを解説すると

  • CSpell の --no-must-find-filesオプションは、cspell の監視対象となっていないファイルのみをコミットしようとするとエラーになるのを防ぐために必須オプションと言えます。
  • ESLint の --max-warnings=0オプションは、ESLint の警告が 1 つでもある場合にコミットさせないオプションです。

push するときのチェック

型チェック、テストを実行

プッシュ の前には TypeScript の型チェックとテストの実行をします。
プルリクエストをオープンする時に実行される CI でも同じことを確認しているのですが、なぜわざわざ同じことをローカルでも行うかというと

  • コードレビューをする際に CI のテストが通っていないことがよくあった
  • ローカルで実行する型チェックとテストの実行は私の環境では 数 10 秒で終わるのでそこまでストレスではない
  • プッシュ する前に最新の開発ブランチを取り込むことがよくあり、取り込んだ結果型エラーやテストに失敗する可能性がある

という理由からです。コードレビューが始まると実装者以外の人の時間も使うことになるので、その前に問題解決出来るという大きなメリットがあります。

問題があってもコミットやプッシュしたいときはどうする?

安心して下さい。--no-verifyオプションを付与すればチェックをスキップできます。

git commit -m 'commit message' --no-verify
git push --no-verify

もちろん思考停止で--no-verifyを付与したら無意味になるので望ましくないですが、問題を解決するために他のメンバーにコードを見てもらいたいとき等は、各項目のチェックを気軽にスキップ出来ます。
ローカルで行っているチェックは問題の早期発見による開発体験の向上のためで、最終的に正しいことの保証は CI が行うという考えが根底にあるので、チェックのスキップ自体は問題ではないという考えです。

導入後の変化と今後の展望

期待した通り今回ローカルでチェックするようにしたことがコードレビュー中にコメントすることはほぼなくなりました。
修正とレビューの往復が減り、実装者、レビュワー共に他のことに時間を使えるようになり、開発体験が向上したと思います。
今後新たにコードレビュー中に繰り返しコメントされることが増えてきた場合、可能な限りリントでチェック出来るように設定変更していくつもりです。

まとめ

今回紹介した開発体験向上の施策はどれも短い時間で簡単に導入することが出来ました。
1 度設定してしまえばほぼメンテナンスコストがかかることなく開発の手助けをしてくれるありがたい存在です。
20%ルールという制度のおかげで「もっとこうしたらいい開発が出来そうなんだよな〜」と思っていたことが 1 ヶ月程度で実現出来ました。
技術課題を解決してより良いサービスを作っていこうと思える良い経験になったので、今後も有効活用していきたいと思います。

おわりに

コミューンではエンジニアを募集中です!少しでも興味のある方は気軽にカジュアル面談に申し込んでみてください!

commmune-careers.studio.site