satococoa's blog

Web や iOS アプリを作るエンジニアの日記です

Kubernetes の CronJob で bundle update して PR 投げてくれるようにした

bundle update を定期的に実行し差分がある場合は pull request を投げる、というよくある仕組みを k8s の cronjob で実装しました。

clone ( or pull ) -> 何らかの処理を行う (ここでは bundle update) -> [差分があったら] -> commit & push -> Pull Request を出す、という処理は今回の bundle update に限らず汎用的に使えるものだと思うので、コマンドラインツールとして Go で実装しました。

github.com

あとは任意のコンテナの中で上記 prbot のバイナリを取得して実行すれば OK。

以下のような manifest を書きます。 Clone や PullRequest の送信に GitHub の Personal Access Token が必要になるので取得して Secrets として登録しておいてください。

apiVersion: batch/v1beta1
kind: CronJob
metadata:
  name: bundle-update
spec:
  schedule: "0 2 * * WED" # cron式
  jobTemplate:
    spec:
      template:
        spec:
          restartPolicy: Never
          containers:
          - image: library/ruby
            name: ruby
            command: [ "/bin/sh" ]
            args:
            - "-c"
            - |2
              set -e
              wget https://github.com/satococoa/prbot/releases/download/v${PRBOT_VERSION}/prbot_${PRBOT_VERSION}_linux_amd64.tar.gz
              tar -xvzf prbot_${PRBOT_VERSION}_linux_amd64.tar.gz
              mv prbot /bin/prbot
              chmod +x /bin/prbot
              gem install bundler
              prbot
            env:
            - name: PRBOT_VERSION
              value: "0.1.2"
            - name: GITHUB_REPOSITORY
              value: "org/repository"
            - name: GITHUB_ACCESS_TOKEN
              valueFrom:
                secretKeyRef:
                  name: bundle-update-secret
                  key: githubAccessToken
            - name: BASE_BRANCH
              value: "master"
            - name: COMMAND
              value: "bin/bundle update"
            - name: TITLE
              value: "pull request のタイトル"
            - name: AUTHOR_NAME
              value: "prbot"
            - name: AUTHOR_EMAIL
              value: "prbot@example.com"

以上です。 使うイメージについては native extension を含む gem なんかが含まれる場合は library/ruby じゃビルドできないかもしれないので、実際にアプリケーションを動かすコンテナで実行する方が確実だと思います。 library/rubybuildpack-deps を基に作られていて mysql-client なんかは入ってるため、僕の場合は library/ruby で大丈夫でした。

学び

  • GoReleaser が超便利。
    • マルチプラットフォーム向けにビルドして バイナリを GitHub の Release にアップロードして、さらに Docker イメージとか Homebrew 用のレシピとかも作れちゃう。
  • buildpack-deps という Docker image を知れた。