目次
はじめに
OCX開発チームに所属しているアプリケーションエンジニアのokunoです。
多くの開発チームがライブラリのバージョン管理に頭を悩ませているのではないでしょうか。
私たちのチームも同様で、バージョンアップに気付く人が少数派だったり、実際に問題が発生したら対応したり、対応する頃には影響範囲が大きくなっていて確認が大変だったりと、 属人化やセキュリティリスクや非効率が課題となっていました。
これらの課題を解決するために、ライブラリのアップデート作業を自動化するアプローチを進めることにしました。
しかし、新たに浮かび上がったのが 自動化のリスクをどう管理するか という課題です。
というのも、以前はライブラリの自動アップデートのために Renovate というツールを使っていましたが、自動アップデートされたライブラリが原因でエラーが発生しました。
これをきっかけに、ツールと運用を全面的に見直すことにしました。
そこで現在は Dependabot を導入すると共に設定や運用プロセスを見直し、
セキュリティ向上と運用効率化を実現しました。
本記事では Dependabot 導入の背景や設定、得られた成果を紹介します。
背景
ここ数ヶ月、私のチームでは Renovate
というツールでライブラリの自動アップデートを運用していました。
ところがある日、Staging環境で自社のサービス(OCX)を操作していたらエラーが発生。
調査の結果、Renovate がライブラリを自動アップデートした際、
適用されたバージョンはサービスと互換性がないことが判明しました。
Renovate は便利ですが、運用設計や制御設定が不十分だったので、
一時的な対策として自動アップデートを無効化しました。
しかし、
自動アップデートを有効化しなければ セキュリティを守れない
自動アップデートを有効化したままでは 障害リスクを避けられない
このジレンマを解消するため、ツールを含めてプロセス全体の見直しを行うことにしました。
前提
開発環境
- ソース管理: GitHub Enterprise
- 対象リポジトリ: 組織のプライベートリポジトリ
- リポジトリ構成: Monorepo
- マージ方法: Merge Queue
- アーキテクチャ: モジュラーモノリス(シングルモジュール)
- 対象ライブラリ: Go言語のライブラリ
リポジトリ構成
root ├── .github ├── dockerfiles ├── go │ ├── services │ ├── batch │ ├── pkg │ └── go.mod
ツール選定
GitHubネイティブツールの Dependabot
を選定しました。
理由は以下の要件を満たし、かつ GitHub Actions と連携しやすいと思ったからです。
- メジャーバージョンはアップデートしないこと:GitHub Actions で対応
- 指定したライブラリはアップデートしないこと:GitHub Actions で対応
- 設定がシンプルで運用が楽なこと(最重要)
運用設計
全体フロー
- Dependabot のアップデート検知とプルリク作成
・毎週月曜8時、Dependabot がライブラリのアップデートを検知し、プルリクを自動作成する。 - GitHub Actions による自動マージ判定
・自動作成されたプルリクが条件を満たしていれば、mainブランチに自動マージする。
自動マージの条件
以下の条件を全て満たすプルリクのみ、mainブランチへ自動マージする。
- マイナーバージョン以下のアップデート
・後方互換性が失われるリスクを避けるため、メジャーバージョンのアップデートは対象外とする。 - 除外リストに該当しないライブラリ
・利用箇所のテストカバレッジが不十分で、影響範囲の大きいライブラリは、除外リストに定義して対象外とする。 - コンフリクトなし&CI成功
・プルリク内でコンフリクトが発生せず、自動テストなどのCIが成功した場合のみ対象とする。
手動対応フロー
- 確認と手動マージ
・自動マージされなかったプルリクには担当者を割り当て、影響範囲を確認する。
・問題がなければmainブランチに手動マージする。 - 継続的な改善
・初めての運用となるため、実際に進める中で新たな改善点が見つかったら状況に応じて柔軟に方法を見直す。
実装例
Dependabot の設定
以下は Dependabot が週1でライブラリのアップデートを検知し、プルリクを作成するための設定ファイルです。
Go
のついでに GitHub Actions
と Docker(ローカル開発用)
も自動アップデートの対象としました。
# .github/dependabot.yml version: 2 registries: github-private: type: git url: https://github.com username: x-access-token password: ${{secrets.DEPENDABOT_TOKEN}} # repo権限ありのPAT updates: - package-ecosystem: "gomod" registries: - github-private directory: "/go" schedule: interval: "weekly" day: "monday" time: "08:00" timezone: "Asia/Tokyo" commit-message: prefix: "chore" open-pull-requests-limit: 20 - package-ecosystem: "github-actions" registries: - github-private directory: "/" schedule: interval: "weekly" day: "monday" time: "08:00" timezone: "Asia/Tokyo" commit-message: prefix: "chore" - package-ecosystem: "docker" registries: - github-private directory: "/dockerfiles" schedule: interval: "weekly" day: "monday" time: "08:00" timezone: "Asia/Tokyo" commit-message: prefix: "chore"
GitHub Actoins のソースコード
以下は Dependabot が作成したプルリクを、条件付きでmainブランチに自動マージするためのワークフローです。
# .github/workflows/dependabot-auto-merge.yml name: Dependabot Auto-merge # Dependabot に secrets を参照させるため pull_request_target を使用しています。 # ※ mainブランチのコンテキストで実行される on: pull_request_target defaults: run: shell: bash concurrency: group: ${{ github.workflow }}-${{ github.event.pull_request.head.ref }} cancel-in-progress: true jobs: auto-merge: # Dependabot が作成したプルリクエストのみ処理対象 if: github.event.pull_request.user.login == 'dependabot[bot]' runs-on: ubuntu-latest timeout-minutes: 5 steps: - name: Generate App token id: app-token uses: actions/create-github-app-token@v1 with: app-id: ${{ secrets.APP_ID }} private-key: ${{ secrets.PRIVATE_KEY }} owner: ${{ github.repository_owner }} - name: Dependabot metadata id: dependabot-metadata uses: dependabot/fetch-metadata@v2 with: github-token: ${{ steps.app-token.outputs.token }} # メジャーバージョンは自動マージしない - name: No major version updates run: | if [[ "${{ steps.dependabot-metadata.outputs.update-type }}" == "version-update:semver-major" ]]; then echo "Major version update found: ${{ steps.dependabot-metadata.outputs.dependency-names }}" exit 1 fi # 特定のライブラリは自動マージしない(除外リスト) - name: Do not update the specified library run: | IGNORE_LIBRARIES=( "github.com/bbsakura" "gorm.io/gorm" "gorm.io/driver/postgres" ) for LIB in "${IGNORE_LIBRARIES[@]}"; do if [[ "${{ steps.dependabot-metadata.outputs.dependency-names }}" == *"$LIB"* ]]; then echo "Ignored library found: $LIB" exit 1 fi done # mainブランチに自動マージする - name: Enable Auto-merge run: | gh pr review --approve "$PR_URL" gh pr merge --auto --squash "$PR_URL" env: PR_URL: ${{ github.event.pull_request.html_url }} GH_TOKEN: ${{ steps.app-token.outputs.token }}
成果
直近の成果
項目 | 結果 | ベネフィット |
---|---|---|
検知されたアップデート総数 | 80件 | バージョンアップを早期把握 |
自動マージされた件数 | 71件(自動マージ率88%) | 手動作業を削減、工数効率化 |
セキュリティ対応件数(CVE) | 5件 | 脆弱性の対応漏れを防止 |
自動マージされなかった件数 | 9件 | 本番障害を未然に防止 |
自動マージされなかった9件については、互換性や自動テスト失敗の確認が必要なものです。
これによりサービスのセキュリティを向上させつつ、障害リスクをゼロに抑えました!
今後の改善点
- 自動アップデート対象の拡大
現在、特定のライブラリ利用箇所についてはテストカバレッジが不足しているため、自動アップデート対象から除外している。
今後はテストコードを拡充することで、より多くのライブラリを自動アップデート対象に含められるようにしたい。 - 全体最適化の推進
現状、フロントエンド(JS/React)や他チームもライブラリのアップデート作業を実施する必要がある。
これらのプロセスも自動化し、全社的な効率化と最適化を目指したい。
さいごに
この取り組みにより、セキュリティ向上や障害リスク軽減を実現しつつ、
ライブラリのアップデート検知から適用までのリードタイムを削減することにより、
サービス価値向上とチーム生産性向上に貢献できました。
私たちのOCX開発チームは サービス価値向上とチーム生産性向上 を常に目指し、
日々の開発だけでなく、こうした改善活動にも積極的に取り組んでいます。
例えば、オンプレからクラウドへの移行、システムアーキテクチャの改善、ER図やテーブル設計書の自動生成、AIを活用したコードレビューの自動化など、様々な施策を進めています。
これらの活動を支えているのは、
目的と方向性をすり合わせ、挑戦する人には無限の裁量が与えられる という文化です。
「良いサービスやチーム作りに挑戦したい!」 と思う方は、ぜひ私たちのチームに来てください! → 応募はこちらから