はじめに:アップデートできていますか?
作ったきりで一度もライブラリをアップデートしていない、そんなプロダクトも多いのではないでしょうか。新規ライブラリの利用が古いライブラリへの依存により実現しないことなど、損失が発生するケースは多々あります。脆弱性対策のアップデートをして、新たな不具合を発生させていては本末転倒です。それらを理解していても、必要に迫られるまでアップデートは後回しにされることが多いと思います。しかし、アップデートが必要になった時には大規模アップデートとなり、エラーと隣り合わせの状態で、祈りながらリリースされることも多いのではないでしょうか?
本記事では Dependabot、GitHub Actions、Sentry を利用してアップデートを半自動化し、実現可能な工数で祈らず継続的にアップデートする手法を提案します。
本記事のまとめ
以下の 3 ステップでの継続的なアップデートを提案します。
- 情報を集める:Dependabot を設定する
- アップデートを検証する:ビルド差分を比較する
- 監視する:Sentry でエラーを検知する
情報を集める:Dependabot を設定する
まず、アップデート情報を定期的に取得する必要があります。これに関しては優れた解決策がすでに用意されています。筆者のチームでは GitHub 公式の Dependabot を利用することにしました。Dependabot は更新を通知してくれるだけではなく、リリースノートが記載されたアップデート Pull Request の作成まで行ってくれます。

アップデートを検証する:ビルド差分を比較する
Dependabot が Pull Request を作成してくれるとしても、全ての Pull Request のリリースノートを読み影響範囲を特定しテストを行うとすると、検証にかなり多くの工数を割くことになります。
そこで、コードベースでアップデートを検証する仕組みを整え、一部のアップデートについては自動検証を可能にしました。
フロントエンドではユーザーに配信するファイル(ビルド成果物)が全く同じであれば、リグレッションが発生しないことの証明になります。さらに、多くのビルド環境では Tree shaking (Dead Code Elimination) の仕組みがあり、ライブラリの利用していない部分の変更に関しては、ビルド成果物には反映されません。つまり、実際には多くのライブラリアップデートはビルド成果物をコードベースで比較し差分がないことをもって検証を完了できるのです。*1
筆者のチームでは Dependabot の作成した Pull Request に対して、アップデート前後のビルド成果物を比較する CI を設定し、それが通過していればそのままリリースに進める運用としました。実際にチームのプロダクトでは 120 件あったマイナーアップデートの内、73 件は差分が生じておらず、人力での検証をスキップしてリリースできました。
実際には GitHub Actions で以下のように実装しました。*2
name: Dependabot diff on: push: branches: - 'dependabot/npm_and_yarn/**' jobs: diff: timeout-minutes: 10 if: github.actor == 'dependabot[bot]' runs-on: ubuntu-latest steps: - uses: actions/setup-node@v3 with: node-version: '16' # アップデート後のビルド - uses: actions/checkout@v3 with: ref: ${{ github.ref }} - name: Install run: | npm ci - name: Build run: | npm run build mv build /tmp/head # アップデート前のビルド - uses: actions/checkout@v3 with: ref: main - name: Install run: | npm ci - name: Build run: | npm run build mv build /tmp/base # 比較 - name: Diff run: | diff -r /tmp/head /tmp/base
監視する:Sentry でエラーを検知する
実際に運用してきた中で、リリースノートを読み影響範囲を調査し修正を加えたとしても、エラーがないことの確証を得られないケースは多くありました。また、Tree shaking 可能な形で配信されておらずアップデートの度に差分が生じてしまうライブラリも多いです。そこで、そのようなアップデートに関しては、社内環境にリリースして1週間程度監視した後、新規エラーが検出されていないことを確認できれば社外向けにリリース可とする運用にしました。
エラー検知には Sentry を使用しました。設定すればアプリケーション内で発生したエラーを検知して送信、集計、レポートを作成することまで自動化することができます。
参考: docs.sentry.io techblog.cartaholdings.co.jp
おわりに
以上、祈らないアップデートを提案しました。筆者のチームでは、実際にこれらの仕組みを導入してから半年以上継続的にアップデートが行われています。一部メジャーバージョンの更新を除き、ほとんどのライブラリが最新になっています。
継続的なアップデートを!