Circle CI で bundle outdated を実行し、結果を JUnit フォーマットの xml にすることでレポートを生成します。
budle outdated 関連はいろんな人が自動化していて、特に新規性はないのですが
JUnit フォーマットの xml を自前で作成してみるのを試したくてこのお題にしました。
※JUnit XML 形式はCircle CI など多くのCIサービスのテストや静的解析の実行時に
レポート表示がサポートされていることが多いです。
(全ては把握してないので曖昧な表現)
eslint junit のサンプル
参考事例として ESLint が出力するJUnitフォーマットの出力を確認してみます。
ESLint は標準でJUnitフォーマットをサポートしています。
例えば以下のようなコマンドで JUnit フォーマットの結果を出力できます。
$ eslint --format=junit ./src
実際に出力されるXMLを確認してみます。
- testsuite はファイル単位
- testcase は個別の警告単位。エラーメッセージに詳細と行数を記載
<?xml version="1.0" encoding="UTF-8"?> <testsuites> <testsuite package="org.eslint" time="0" tests="2" errors="2" name="/path/to/eslint_ci_test/src/hoge.js"> <testcase time="0" name="org.eslint.semi"> <failure message="Missing semicolon."><![CDATA[line 10, col 37, Error - Missing semicolon. (semi)]]></failure> </testcase> <testcase time="0" name="org.eslint.indent"> <failure message="Expected indentation of 8 spaces but found 10."><![CDATA[line 11, col 11, Error - Expected indentation of 8 spaces but found 10. (indent)]]></failure> </testcase> </testsuite> <testsuite package="org.eslint" time="0" tests="2" errors="2" name="/path/to/eslint_ci_test/src/index.js"> <testcase time="0" name="org.eslint.semi"> <failure message="Missing semicolon."><![CDATA[line 10, col 37, Error - Missing semicolon. (semi)]]></failure> </testcase> <testcase time="0" name="org.eslint.indent"> <failure message="Expected indentation of 8 spaces but found 10."><![CDATA[line 11, col 11, Error - Expected indentation of 8 spaces but found 10. (indent)]]></failure> </testcase> </testsuite> </testsuites>
サンプル
Gemfile
source "https://rubygems.org" gem 'eto', '~> 1.0.0' gem 'kosi', '~> 0.0.1' gem 'ruboty-generator', '~> 1.0.0'
script/bundle_outdated.rb
require 'open3' require 'erb' class BundleOutdated JUNIT_XML_TEMPLATE = <<-EOS.freeze <?xml version="1.0" encoding="UTF-8"?> <testsuites> <testsuite name="outdated"> <%=testcases%> </testsuite> </testsuites> EOS def self.outdated_gems Open3.capture2('bundle outdated --porcelain').first[1..-1] end def self.generate(testcases) ERB.new(JUNIT_XML_TEMPLATE).result(binding) end def self.generate_testsuite(gem) gem.match(/(.+)\s\((.+)\)/) name = $1 description = $2 <<-EOS.chomp <testcase time="0" name="#{name}"> <failure message="#{description}"><![CDATA[https://rubygems.org/gems/#{name}]]></failure> </testcase> EOS end end outdated_gems = BundleOutdated.outdated_gems testcases = outdated_gems.each_line.map(&:chomp).each_with_object([]) do |gem, memo| memo << BundleOutdated.generate_testsuite(gem) end exit(0) if testcases.size.zero? puts BundleOutdated.generate(testcases.join("\n")) exit(1)
circle.yml
machine: timezone: Asia/Tokyo ruby: version: 2.3.1 test: pre: - mkdir $CIRCLE_TEST_REPORTS/bundle_outdated - ruby $HOME/$CIRCLE_PROJECT_REPONAME/script/bundle_outdated.rb > $CIRCLE_TEST_REPORTS/bundle_outdated/bundle_outdated.xml
実行
Circle CIにpushして動作確認しました