kubell Creator's Note

ビジネスチャット「Chatwork」のエンジニアのブログです。

ビジネスチャット「Chatwork」のエンジニアのブログです。

読者になる

Scala Steward を CircleCI で定期実行させる方法

こんにちは。cw-kajiwaraです。

privateレポジトリに対してScala StewardをCircleCIで定期実行するようにしてみたので、その設定方法の共有をさせていただきます。

社内レポジトリなどのpublicにできない or したくないレポジトリの依存ライブラリ更新作業を省力化したい方はぜひご覧ください。(社内レポジトリをpublicにして公式botに更新してもらうというのもかっこいい選択だとは思います)

TL;DR

Scala StewardをCircleCIで定期実行させるために必要な手順は以下です。

  • bot用のGitHubアカウントを作成する
  • bot用のGitHubアカウントのAPIトークンを作成する
  • Scala Steward用のレポジトリを作成する
  • Circle CIプロジェクトを作成する
    • 環境変数を設定する
  • Circle CIを実行する
    • Scala Steward適用対象のレポジトリをリストにしたmarkdownファイルを作成する
    • GitHub APIトークンを標準出力するシェルスクリプトを用意する
    • CircleCIの設定ファイルを作成する

Scala Stewardとは

github.com

sbtプロジェクトの依存ライブラリの更新PRを投げてくれるアプリケーションです。 様々なOSSで使われているのでScala Stewardが作成したPRを見かけたことがある方は多いのではと思います。

使い方は2通りです。

publicレポジトリの場合

もし対象のレポジトリがpublicならやることは Scala Steward公式レポジトリにrepos.md更新のPRをマージしてもらうだけ になります。

Scala Stewardはpublicレポジトリを対象としたbotを提供してくれています。

scala-steward (Scala Steward) · GitHub

このbotは公式レポジトリのrepos.mdというファイルに書かれているレポジトリを対象に依存ライブラリのバージョンチェック・PR作成をしてくれるので、 こちらにご自身のレポジトリをrepos.mdに追記したPRを作成してマージしてもらえれば、あとはScala Stewardの公式botがよしなにPRを作成してくれるようになります。

例えば、AkkaをScala Stewardの対象レポジトリに追加する際は以下のPRが出されました。

Scala Steward レポジトリ追加の例
Scala Steward レポジトリ追加の例

privateレポジトリの場合

privateレポジトリで動かす場合はpublicレポジトリの場合と比べて手順が少し増えます。以下は公式が公開しているドキュメントです。

scala-steward/running.md at master · scala-steward-org/scala-steward · GitHub

Scala Stewardはsbtプロジェクトとして構成されており、sbtで実行することやdockerイメージにして実行することが可能です。今回CircleCIで動かすにあたってdockerイメージを作成する方式で利用したので、その方法を説明します。

といってもやることは以下だけです。(環境変数やdockerイメージURLなどは適宜置き換えてください)

  1. 対象のレポジトリをmarkdownファイルに書き込む(repos.mdとします)

  2. GitHub APIトークンを生成する

  3. GitHub APIトークンを標準出力するスクリプトを用意する(token.shとします)

    • shebang + echo "xxxxxxxxxxxxxxx"
  4. Scala StewardのDockerイメージを起動する(${EMAIL}, ${LOGIN}にはGitHubの登録メールアドレス、アカウント名を入れてください)

sbt docker:publishLocal

docker run -v $STEWARD_DIR:/opt/scala-steward -it fthomas/scala-steward:latest \
  --workspace  "/opt/scala-steward/workspace" \
  --repos-file "/opt/scala-steward/repos.md" \
  --default-repo-conf "/opt/scala-steward/default.scala-steward.conf" \
  --git-author-email ${EMAIL} \
  --vcs-api-host "https://api.github.com" \
  --vcs-login ${LOGIN} \
  --git-ask-pass "/opt/scala-steward/token.sh" \
  --sign-commits \
  --env-var FOO=BAR

このようにローカルでScala Stewardを実行することができます。 (依存ライブラリの管理状態によっては大量のPRがくるのでご注意ください。)


Circle CIに導入する

とはいえども、ローカルで都度思い出したときに実行するっていうのはなんだかつらそうです。 こういう仕事はCIで回していきましょう。 ということでCircleCIで定期的に動かす方法を紹介します。

設定の流れ

  • Scala Steward実行用のjobを作る
    • repos.md, token.shを保持するボリューム(のためのダミーコンテナ)を作成する
    • Scala StewardのDockerコンテナを上記のボリュームをマウントして実行する
  • 上記のjobをスケジューリング実行する
    • 毎日0時0分(JST)に起動させる

前準備

  • (bot用)GitHub Accountを作成する

    • 対象レポジトリへのread/write権限をつけておいてください
    • botからのPRとして自動マージなどの判断ができるようになるので、運用する上で便利です
  • GitHub API Tokenを生成する

  • repos.mdを作成する

    • 対象レポジトリをmarkdownに書き込んでください
  • token.shを作成する

    • 以下のようにAPIトークンを標準出力に出すようにしてください
#!/bin/sh
echo ${SCALA_STEWARD_GITHUB_API_KEY}
  • CircleCIに環境変数を登録する

Add Variableボタンから後でScala Stewardに CircleCI から渡すための環境変数を追加してください

f:id:cw-kajiwara:20201002105804p:plain
プロジェクトのパイプライン画面から

f:id:cw-kajiwara:20201002115919p:plain
プロジェクト設定画面から

設定内容

以下が今回使用した設定ファイルです。

version: 2.1
jobs:
  scala-steward:
    docker:
      - image: circleci/golang:1.15.2  
    steps:
      - checkout
      - setup_remote_docker
      - run: 
          name: "Run scala-steward"
          command: |
            # scala-steward コンテナにマウントするためのボリュームを作成する
            docker create -v /opt/scala-steward --name configs alpine:3.11.6 /bin/true
            docker cp $(pwd)/. configs:/opt/scala-steward/
            docker run -it --rm --volumes-from configs --env SCALA_STEWARD_GITHUB_API_KEY=$SCALA_STEWARD_GITHUB_API_KEY fthomas/scala-steward:latest \
              --default-repo-conf "/opt/scala-steward/default.scala-steward.conf" \
              --workspace  "/opt/scala-steward/workspace" \
              --repos-file "/opt/scala-steward/repos.md" \
              --git-author-email $SCALA_STEWARD_GITHUB_EMAIL_ADDRESS \
              --vcs-api-host "https://api.github.com" \
              --vcs-login $SCALA_STEWARD_GITHUB_ACCOUNT_NAME \
              --git-ask-pass "/opt/scala-steward/token.sh" \
              --do-not-fork \
              --env-var AWS_REGION=ap-northeast-1 \

workflows:
  version: 2
  scala-steward-scheduler:
    jobs:
      - scala-steward
    triggers:
      - schedule:
      # JSTにおける毎日0時0分に実行する
          cron: "0 15 * * *"
          filters:
            branches:
              only:
                - "master"

注意点を2点だけ。

  • CircleCIではスケジューラーのタイムゾーンはUTCで固定されているようなので、定期実行したい時点をUTCに変換して設定してください。

  • Scala Stewardは実行する際の--do-not-fork設定のオン・オフの違いで重複するPRが生成されてしまうので統一してください。

これで毎日0時0分(in JST)にScala Stewardが働いてくれるようになります。

おわりに

上記の方法でScala Stewardを定期実行することができますが、レポジトリの依存ライブラリのメンテナンス状況によっては大量のPRが生成されて放置されてしまう、といった 事態になりかねません。 また次の機会に、Scala Stewardの運用をどうしていけばよいか、というところに関してご紹介させていただければと思います。

ということで

Chatworkでは、ユーザーにとってより価値のあるサービスを追求し、大規模な基盤システムの開発運用保守を担うScalaエンジニアを募集しています。

今回のような運用の自動化に関して興味がある方もいらっしゃればぜひ!!

www.wantedly.com