で書いてた
今回作ったorbのインテグレーションテストも頑張ってるのですが、長くなるので別の機会に書こうと思います
の件です。
https://github.com/sue445/circleci-ruby-orbs/blob/1.2.0/.circleci/config.yml の解説をします
注)タイトルは半分釣りです
- tl;dr;
- orbのテストについて
- YAMLのシンタックスチェック
- ローカルテスト
- インテグレーションテスト
- 【おまけ】スモークテスト用のブランチを自動で削除する
- 【おまけ】orbリリース時に自動でgitのtagをpushしたい
tl;dr;
- 何をテストしたいかによって難易度が変わる
orbのテストについて
https://github.com/CircleCI-Public/config-preview-sdk/blob/master/docs/orbs-testing.md より抜粋
You can think of orb testing at 4 levels, in increasing levels of complexity and scope.
- Schema Validation - this can be done with a single CLI command and checks if the orb is well-formed YAML and conforms to the orb schema.
- Expansion Testing - this can be done by scripting the CircleCI CLI and tests whether the elements of the orb generate the configuration you intended when processing configuration containing those elements.
- Runtime Testing - this requires setting up separate tests and running them inside a CircleCI build.
- Integration Testing - this is likely only needed for fairly advanced orbs or orbs designed specifically as public, stable interfaces to 3rd-party services. Doing orb integration tests requires a custom build and your own external testing environments for whatever systems you are integration with.
英語は苦手なので 今回は和訳することが目的ではないので具体的にどんなテスト手法があるのかを紹介します
YAMLのシンタックスチェック
実際のソース
https://github.com/sue445/circleci-ruby-orbs/blob/1.2.0/.circleci/config.yml#L7-L14
一番お手軽ですが、ymlファイルの検証だけで実際にジョブを動かさないためテストとしては不十分です
ローカルテスト
CircleCI Orbs 入門 | tsub's blog の「Orb のテスト実行」が詳しいです
実際のソース
- https://github.com/sue445/circleci-ruby-orbs/blob/1.2.0/.circleci/config.yml#L109-L114
- https://github.com/sue445/circleci-ruby-orbs/blob/1.2.0/test/bundle-install_test.yml
だいたいの場合はこれでいいのですが、orb実行のために他にファイルが必要な場合( ruby-orbs/bundle-install
の場合Gemfile)には不向きです
理由
local-test-build
で起動したコンテナにリポジトリのファイルを送る手段が(たぶん)ないため- config.yml内のシェルでファイルを作ろうとしても、CircleCIだと
<<
がparameterのタグとして使われてるためcat Gemfile << EOS
のようなシェルの記法が使えない
インテグレーションテスト
https://github.com/CircleCI-Public/artifactory-orb ではスモークテストのためのリポジトリ( https://github.com/eddiewebb/artifactory-orb-test )を作っていました。
それを参考にruby-orbsでも https://github.com/sue445/circleci-ruby-orbs-test のようなリポジトリとCircleCIのプロジェクトを作っています
circleci-ruby-orbs(メインのリポジトリ)とcircleci-ruby-orbs-test(スモークテスト用のリポジトリ)を連携させて下図のようなインテグレーションテストを実現しています。(文字が小さくなってすいません。。。)
仕組み
- 【ローカル】トピックブランチをpush
- 【circleci-ruby-orbs】
sue445/ruby-orbs@dev:${CIRCLE_SHA1}
(CIRCLE_SHA1はビルド実行時のgitのリビジョン)でorbをリリース - 【circleci-ruby-orbs】smoke_testジョブでcircleci-ruby-orbs-testのリポジトリをcloneする
- 【circleci-ruby-orbs】cloneしたcircleci-ruby-orbs-testで
smoke_test/{CIRCLE_SHA1}
のようなブランチを作る - 【circleci-ruby-orbs】circleci-ruby-orbs-testが
sue445/ruby-orbs@dev:${CIRCLE_SHA1}
を使ってビルドするようなコミットを作る - 【circleci-ruby-orbs】circleci-ruby-orbs-testにpush
- 【circleci-ruby-orbs-test】circleci-ruby-orbsのCircleCIから下記画像のようなコミットがpushされてくるので、circleci-ruby-ops-test側のCircleCIがビルドを実行する
- 【circleci-ruby-orbs】circleci-ruby-orbs-testのビルドをポーリングして、ビルドが終了するまで待つ
【おまけ】スモークテスト用のブランチを自動で削除する
circleci-ruby-orbs-testには smoke_test/xxxxx
のようなブランチが大量に作られるので、それを定期的に削除するCircleCIのジョブを作ってます
- https://github.com/sue445/circleci-ruby-orbs-test/blob/ef297545d8546160142e34660dbacb68fbe71492/.circleci/branch_cleaner.rb
- https://github.com/sue445/circleci-ruby-orbs-test/blob/ef297545d8546160142e34660dbacb68fbe71492/.circleci/config.yml#L40-L48
今の設定だと12時間に1回、12時間以上前に作られたブランチを自動で削除するようにしています
【おまけ】orbリリース時に自動でgitのtagをpushしたい
orb-tools/increment
を使えばorbの自動リリースは簡単にできるのですが、リポジトリ的にはリリースごとにtagが打たれていた方が後からバージョン間の差分が取りやすいので嬉しいことが多いです。
increment後に自動でgitのtagをpushする方法がないかissueで聞いたところ、
You could run
circleci orb info
to get the latest in an additional step in your flow
というレスをもらったのでそれをCIで実装したのが下記です
- https://github.com/sue445/circleci-ruby-orbs/blob/1.2.0/.circleci/config.yml#L16-L32
- https://github.com/sue445/circleci-ruby-orbs/blob/1.2.0/.circleci/push_latest_version_tag.rb
circleci orb info
をたたいてLatestで返ってきたバージョンのtagを作ってpushしています