定期的にライブラリの依存関係をアップデートしてPull Requestする

tl;dr

  • Cron for GitHubで定期的にCIサーバーのフックを起動する
  • CI側では、特定のブランチの場合のみ起動するスクリプトを用意する
  • 自分のやりたい操作をして、git_httpsable-push, pull_request_create でPull Requestを送る
Interval Dependency Update
定期的にDependency UpdateのPull Requestを送る

フックの起動

Cron for GitHubのschedulerはこのように設定した。

bundle exec cron-for-github clear --slug=metarubygems/carrion_crow --namespace=cron_for_tachikoma --verbose && bundle exec cron-for-github ping --slug=metarubygems/carrion_crow --namespace=cron_for_tachikoma --verbose

Cron for GitHubの使い方はリンク先を参照する。

キモはnamespaceの指定で、cron_for_tachikoma/XXXXXというブランチを定期的に作るようにする。 CI側ではこのブランチを監視する。

CI側スクリプト (CircleCI)

CI側では、テスト後にスクリプトを実行。なお、例はCircleCIの場合。

test:
  post:
    - bin/run-tachikoma.sh

実行するスクリプト。 特定のブランチを監視して、あとは曜日で起動するしないの頻度を決めている。 この場合、日曜のみ起動。 環境変数 GITHUB_ACCESS_TOKENtoken を入れている。

#!/usr/bin/env bash
set -ev

# only sunday
if [[ "${CIRCLE_BRANCH}" != "master" && "${CIRCLE_BRANCH}" =~ ^cron_for_tachikoma/.* && $(date +%w) -eq 0 ]]; then
  # gem prepare
  gem install --no-document git_httpsable-push pull_request-create

  # git prepare
  git config user.name sanemat
  git config user.email foo@example.com
  HEAD_DATE=$(date +%Y%m%d_%H-%M-%S)
  HEAD="tachikoma/update-${HEAD_DATE}"

  # checkout
  git checkout -b "${HEAD}" origin/master

  # bundle install
  bundle --no-deployment --without nothing --jobs 4

  # bundle update
  bundle update

  git add Gemfile.lock
  git commit -m "Bundle update ${HEAD_DATE}"

  # git push via https
  git httpsable-push origin "${HEAD}"

  # pull request
  pull-request-create
fi

exit 0

Git HTTPSable Pushや PullRequest Create はリンク先を参照する。

以上により、 定期的にライブラリの依存関係をアップデートしてPull Request 出来るようになった。

TravisCIの場合

(Edited: 2015-03-17 15:15)

pull request以外はmasterのbuildしか対象にしていない場合、.travis.ymlcron_for_tachikoma監視する。

branches:
  only:
  - master
  - /^cron_for_tachikoma\/.*/

if pull request以外のところを変更する。 TravisCIのgit checkoutの方式によりorigin/masterが居ないので、git checkout -b "${HEAD}" "${TRAVIS_BRANCH}"にする。 もしくはgit checkout -b "${HEAD}"にする。

#!/usr/bin/env bash
set -ev

# only sunday
if [[ -n "${TRAVIS_PULL_REQUEST}" && "${TRAVIS_PULL_REQUEST}" == "false" && "${TRAVIS_BRANCH}" =~ ^cron_for_tachikoma/.* && $(date +%w) -eq 0 ]]; then
  # gem prepare
  gem install --no-document git_httpsable-push pull_request-create

  # git prepare
  git config user.name sanemat
  git config user.email foo@example.com
  HEAD_DATE=$(date +%Y%m%d_%H-%M-%S)
  HEAD="tachikoma/update-${HEAD_DATE}"

  # checkout (for TravisCI)
  git checkout -b "${HEAD}" "${TRAVIS_BRANCH}"

  # bundle install
  bundle --no-deployment --without nothing --jobs 4

  # bundle update
  bundle update

  git add Gemfile.lock
  git commit -m "Bundle update ${HEAD_DATE}"

  # git push
  git httpsable-push origin "${HEAD}"

  # pull request
  pull-request-create
fi

exit 0

備考

反対に、webhook ping用のブランチである cron_for_tachikoma/XXXXX ではテストをスキップする、というのを入れておかないと、 テストのキューが多く詰まるような環境では悪い影響出る可能性があるので注意。

他言語でも

実行するスクリプトの中身はシェルスクリプトでコマンドが並んでいるだけなので、もちろん言語非依存。 composer updateでもpod updateでもOK。 どんなコマンドオプションだとCIサーバー上で動かしやすいのかは、 Tachikoma gem 見るといけそう。

まとめ

  • ライブラリを組み合わせて、CIサーバーから依存関係アップデートしたPull Requestを定期的に送る事ができるようになった

使ってみたをブログやqiitaに書いてもらえると助かる!フィードバックください!! 他にも使い道がありそう。


参照