表題の通りですが、作りました。
CircleCIで失敗したテストをローカルで流したいのだけれど、わざわざCircleCIのページを見に行くのもあれだし、どうせならガバッと実行したいな〜と思ってCircleCI APIを叩いて取得できるんじゃないかな?と思って調査してみたらできました。
Railsプロジェクトの準備
gemのインストール
gem circleciとgem gitをインストールします。 circleciは、CircleCI APIにアクセスするためのgemで、直接REST Clientとかを使うより便利です。 gitは、現在のブランチ名を取得するために使っています。
また、dotenv-railsを使っていることを前提とします(環境変数をたくさん使うので)
Gemfileに追記します。
group :development, :test do gem 'circleci' gem 'git', require: false gem 'dotenv-rails' end
bundle install
しましょう。
.envにCircleCIのトークンなどの設定
.envファイルに、CircleCIにアクセスするための環境変数を設定します。 これらは自分の環境に合わせて変更をお願いします。
CIRCLE_PROJECT_USERNAME='username' CIRCLE_PROJECT_REPONAME='reponame' CIRCLE_TOKEN='******'
config/initializers/circleci.rbの作成
if Rails.env.development? || Rails.env.test? CircleCi.configure do |config| config.token = ENV['CIRCLE_TOKEN'] end end
Rails Runnerの作成
scriptディレクトリに以下のファイルを追加します。gistで公開しています。
gist959f476c8d0df95f96709bb65264f10f
使い方
ヘルプを見る
ヘルプは-h
または--help
で見れます。どんな引数を使うのかなどがわかります。
$ bin/rails runner script/circleci_failed_spec_files.rb -h Usage: circleci_failed_spec_files [options] -n, --build_num VALUE CircleCI Build number(default: nil) -l, --[no-]line output lines(default: false) -j, --job_name VALUE job name(default: build) -b, --branch VALUE git branch name(default: current_branch) -t, --vcs_type VALUE vcs_type(default: github) -h, --help Prints this help
--build_num(-n)
CircleCIのビルド番号を指定します。これが指定されている場合は、対象のビルド番号から落ちているテストのファイル一覧を取得します。対象のビルドが成功している場合は、何も返しません。
--[no-]line(-l)
戻ってきたファイル一覧を1行ごとに表示するか、スペース区切りで取得するかです。デフォルトはスペース区切りです。
スペース区切りの場合は直接rspecに渡すときに便利で、行ごと表示の場合はpecoやCircleCIで加工する際などに便利です。
--job_name(-j)
Workflowを使っている場合に実際にテストをしているジョブの名前を指定します。
--branch(-b)
gitのブランチ名を指定します。デフォルトだと現在のブランチを自動で取得します。
--vcs_type(-t)
バージョン管理システムのタイプを指定します。デフォルトはgithubです。bitbucketを使っている場合は、-vcs_type bitbucketとする必要があります。
使い方のサンプル(基本編)
Workflowを使っていない場合
基本はこれでいいです。
$ bin/rails runner script/circleci_failed_spec_files.rb
Workflowを使っている場合
実際にテストしているjobの名前がtestとしますと、以下の通りです。
$ bin/rails runner script/circleci_failed_spec_files.rb -j test
実際に利用する
現在のブランチで失敗したテストをローカルで実行する
$ bin/rspec $(bin/rails runner script/circleci_failed_spec_files.rb)
他のブランチで失敗したテストをローカルで実行する
$ bin/rspec $(bin/rails runner script/circleci_failed_spec_files.rb -b feature-xxx)
ビルド番号を指定してローカルで実行する
$ bin/rspec $(bin/rails runner script/circleci_failed_spec_files.rb -n 1234)
応用編
pecoに渡す
私はfish使いなのでfishの関数を定義しました。
function peco_pipe_rspec peco | read line if test -n "$line" commandline "bin/rspec $line" end set -e line end
そして、これにオプション--lineをつけて渡します。
$ bin/rails runner script/circleci_failed_spec_files.rb --line | peco_pipe_rspec # 選ぶと… $ bin/rspec spec/features/xxx_spec.rb # エンター押して実行!
CircleCIで落ちたテストが複数ファイルあった場合、全部流すと時間がかかるのでこれは便利です。
おまけ
昨日書いたのですが、fishでCommand Substitutionsを使うと戻り値を1つの文字列と認識してしまうので、工夫が必要です。
$ bin/rspec (bin/rails runner script/circleci_failed_spec_files.rb | string split " ")
これでバッチリ!
導入が多少面倒ですが、便利です。CircleCIのほうでもこれを使って全体テストを流す前に落ちたテストを実行するようにしました。それについては別記事を書こうと思います。また、余裕ができたらgemにしようと思います。
追記:書きました。