はじめましての方ははじめまして。21新卒エンジニアの Javakky です。 今回は、リポジトリの依存関係を最新に保つための取り組みを始めたので、そのレポートになります。
背景
私の部署では Scala というプログラミング言語と sbt というビルドツールを利用して開発が行われています。突然ですが、当時の依存関係設定を抜粋してきたので見てみましょう。
DB 周りの依存関係だけでも見事に波線が出てしまっています。 もちろん、DB周りが特殊というわけではなく、多くの依存関係で最新ではない箇所がありました。
そんな中、ある脆弱性が話題になります。
当然弊社も他人事ではなく、急ぎ検証やライブラリのアップデートの対応を行いました。この件に関しては直接当該ライブラリを利用していなかったこと、間接的に依存したライブラリの更新でエラー等が発生しないことが幸いしましたが、各ライブラリに破壊的な変更があった場合には多くのリソースを消費することになっていたかもしれません。 そして、依存関係の更新を蔑ろにすると、小規模でも対応すべき脆弱性について見逃してしまっているかもしれません。
そこで、継続的に依存関係を構築する体制をツール・運用の両面から見直すことになりました。
Scala Steward の導入
まずは導入したツールについての説明です。
今回導入した Scala Steward は、 sbt プロジェクトに更新されていない依存関係を見つけた際に更新するマージリクエストを作成してくれる bot です。
もし、あなたのプロジェクトが GitHub のパブリックリポジトリにあれば、 repos-github.md にプロジェクトを追加するだけで利用することができます。
残念なことに弊社ではソースコードを GitLab で管理しているため、この方法は利用できませんでした。しかし安心して下さい! Scala Steward は docker イメージを提供しているため、 GitLab CI 上でも実行することができます。
CIの設定を行う
公式のドキュメントを参考に、以下のようにタスクを定義しました。
scalaSteward: only: refs: - schedules variables: - $TASK_NAME == "steward" image: name: fthomas/scala-steward:latest entrypoint: [""] variables: EMAIL: 'hogehoge@fuga.co.jp’ # ここに git の commiter にしたいメールアドレスを入れる LOGIN: 'scalasteward' # 任意の名前 script: - ls -la $CI_PROJECT_DIR/ - mkdir --parents "$CI_PROJECT_DIR/.sbt" "$CI_PROJECT_DIR/.ivy2" - ln -sfT "$CI_PROJECT_DIR/.sbt" "$HOME/.sbt" - ln -sfT "$CI_PROJECT_DIR/.ivy2" "$HOME/.ivy2" - /opt/docker/bin/scala-steward --workspace "$CI_PROJECT_DIR/workspace" --process-timeout 30min --do-not-fork --repos-file "$CI_PROJECT_DIR/repos.md" --repo-config "$CI_PROJECT_DIR/.scala-steward.conf" --git-author-email "${EMAIL}" --vcs-type "gitlab" --vcs-api-host "${CI_API_V4_URL}" --vcs-login "${LOGIN}" --git-ask-pass "$CI_PROJECT_DIR/askpass.sh" cache: key: scala-steward paths: - .ivy2/cache - .sbt/boot/scala* - workspace/store
Access Token の生成方法
GitLab で MR を自動生成するには、アクセストークンを作成して渡す必要があります。
今回は1リポジトリが対象で、リポジトリのCIで動作させるため、 GitLabのアクセストークンの安全な選び方・使い方 にあるプロジェクトアクセストークンの使い方を参考にアクセストークンを生成しました。
また、プロジェクトのルートディレクトリに askpass.sh
というファイルを作成してCIから読み込めるようにしました。
#!/usr/bin/env bash echo "${SCALA_STEWARD_TOKEN}"
repos.md の作成
Scala Steward を動作させるには、CIを動かすリポジトリに repos.md
というファイルを作成する必要があります。
- ${プロジェクト名}/${リポジトリ名}
schedules の設定
ここまでで、Scala Steward を実行するためのタスク定義が完了しました。ここからは、実際に定期実行するための設定をしていきます。
実行対象のリポジトリを GitLab ページで開き、左のタスクバーから CI/CD > Schedules を開きます。今回は新規スケジュール作成のため、New Schedule を選択しました。
Variables の設定について説明すると、 SCALA_STEWARD_TOKEN
には先述したアクセストークンを、 TASK_NAME
にはCI設定の時に決めた ‘steward’ をセットしました。
生成されるMR
レビューの体制
さて、ここまでで依存関係の更新を自動で検出することができるようになりました 🎉 次は、私たちはどのようにこの MR をレビューしてマージしているのかについて説明していきます。
まず、担当者は弊チームのエンジニアが交代制で決めることになりました。 レビューについては、追加された全機能について影響がないかを目視で判断することは現実的でないため、以下2点を満たしていれば担当者がマージしてもよいということにしました。
- MRに記載されているリリースノートに、後方互換生を損なうような変更がないこと
- 自動テストにクリアしていること
まれに自動テストが失敗したり、追加の依存関係が必要になることがあるため、その場合には他のメンバーにレビューしてもらうことにしています。
生成頻度の設定については、公式のドキュメントを参考に毎日2個までのMRを生成するように設定しました。
updatePullRequests = "never" updates.limit = 2
まとめ
Scala Steward を導入したことでリポジトリの依存関係を最新に保つ仕組みが完成しました。 sbt プロジェクトを利用している開発者のみなさんもぜひ試してみてください!