bundle update のプルリクエストを毎日自動で作成する
Gemfile.lock を最新に保つため、bundle update を毎日自動でできるようにしたい。
Tachikoma.io というサービスもあるみたいだけど、 private repo は有料っぽいので自作した。
勝手に update されてアプリケーションがバグると困るので、
という手順で行う。
先人の知恵
ここら辺を参考にした。
環境
流れ
- Heroku Scheduler が CircleCI を叩く
- CircleCI で bundle update を実施
- Gemfile.lock 更新があれば CircleCI が GitHub に PR を作成
- PR を人間が確認してマージボタンをポチ
1. 前準備
- CircleCI Token 取得
- https://circleci.com/account/api から Token を発行
- GitHub Personal access tokens 取得
- https://github.com/settings/tokens
- repo に ✔︎ つける
2. rake task 作成
lib/tasks/bundle_update_pull_request.rake
を作成する。
# frozen_string_literal: true namespace :bundle_update_pull_request do desc 'pull request if bundle updated' task check: :environment do project = 'repo-team/repo-rails' branch = 'master' token = 'CircleCI Token' params = '{"build_parameters": {"BUNDLE_UPDATE": true}}' header = { 'Content-Type' => 'application/json' } client = Net::HTTP.new('circleci.com', 443) client.use_ssl = true response = client.post("/api/v1/project/#{project}/tree/#{branch}?circle-token=#{token}", params, header) end end
CircleCI の Nightly Builds を叩くだけの task。
params に '{"build_parameters": {"BUNDLE_UPDATE": true}}'
を渡していて、 CircleCI ではこのパラメータをみて bundle update するのか判断する。
この task は以下のコマンドで実行できる。
$ bundle exec rake bundle_update_pull_request:check
3. circle.yml
circle.yml をこんな感じで書く。
test: post: - > if [ -n "${BUNDLE_UPDATE}" -a "${CIRCLE_BRANCH}" = 'master' ] ; then bundle update fi deployment: master: branch: master commands: - > if [ -n "${BUNDLE_UPDATE}" ] ; then bash script/circleci/create_pull_request_if_needed.sh fi
2 で params に渡した BUNDLE_UPDATE
が true だったら bundle update 実行 + PR 作成するようになっている。
4. create_pull_request_if_needed.sh
script/circleci/create_pull_request_if_needed.sh
を作成する。
#!/bin/bash export BRANCH=bundle-update-`date -u "+%Y%m%d"` if [[ -n `git status -sb 2> /dev/null | grep Gemfile.lock` ]] ; then git config --global user.email git@git.com git config --global user.name 'git' git add Gemfile.lock git commit -m 'Bundle update' git branch -M $BRANCH git push origin $BRANCH bundle exec ruby script/circleci/create_pull_request.rb fi
3 で実行された bundle update で、 Gemfile.lock に差分があれば PR を作成するだけ。
5. create_pull_request.rb
script/circleci/create_pull_request.rb
を作成。
# frozen_string_literal: true require 'octokit' client = Octokit::Client.new(access_token: 'GitHub Personal access tokens') client.create_pull_request( 'repo-team/repo-rails', 'master', ENV['BRANCH'], 'Bundle update', '' )
これで PR が作成される。
ここまでで bundle exec rake bundle_update_pull_request:check
で Bundle update の PR が自動で作成されるようになった。
6. Heroku Scheduler で定期実行
ここでは Heroku を使っているけど、定期実行できればなんでも良い。
動かしてみる
こんな感じで GitHub に毎日 PR がくるようになります。
これを人間が目視で確認して問題なければマージしましょう。
しかし、目視といっても version が変わったことしかわからないので、これを実際に運用するにはテストがしっかりと書かれていて、そのテストが壊れてないことを確認したらマージするようにしないとダメですね。