Skip to content

Commit 1aacc79

Browse files
committed
Use our preferred format
1 parent a2bfe68 commit 1aacc79

File tree

3 files changed

+43
-53
lines changed

3 files changed

+43
-53
lines changed

hooks/command

+7-5
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22

33
set -euo pipefail
44

5-
PLUGIN_DIR="$(cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd)/.."
65
MAX_SIZE=1024 # in KB
76

87
echo "--- :junit: Download the junits"
@@ -30,14 +29,17 @@ buildkite-agent artifact download \
3029

3130
echo "--- :junit: Processing the junits"
3231

32+
# Move ruby code to current dir so we can mount it
33+
plugin_ruby_dir="$(cd "$( dirname "${BASH_SOURCE[0]}" )/../ruby" && pwd)"
34+
ruby_dir="$(pwd)/$(mktemp -d "junit-annotate-plugin-ruby-tmp.XXXXXXXXXX")"
35+
cp -R "${plugin_ruby_dir}" "${ruby_dir}"
36+
3337
docker \
3438
--log-level "error" \
3539
run \
3640
--rm \
37-
--volume "$artifacts_dir:/junits" \
38-
--volume "$PLUGIN_DIR/ruby:/src" \
39-
--env "BUILDKITE_PLUGIN_JUNIT_ANNOTATE_JOB_UUID_FILE_PATTERN=${BUILDKITE_PLUGIN_JUNIT_ANNOTATE_JOB_UUID_FILE_PATTERN:-}" \
40-
--env "BUILDKITE_PLUGIN_JUNIT_ANNOTATE_FAILURE_FORMAT=${BUILDKITE_PLUGIN_JUNIT_ANNOTATE_FAILURE_FORMAT:-}" \
41+
--volume "${artifacts_dir}:/junits" \
42+
--volume "${ruby_dir}/ruby:/src" \
4143
ruby:2.7-alpine ruby /src/bin/annotate /junits \
4244
> "$annotation_path"
4345

plugin.yml

-7
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,6 @@ configuration:
77
properties:
88
artifacts:
99
type: string
10-
job-uuid-file-pattern:
11-
type: string
12-
failure-format:
13-
type: string
14-
enum:
15-
- classname
16-
- file
1710
fail-build-on-error:
1811
type: boolean
1912
context:

ruby/bin/annotate

+36-41
Original file line numberDiff line numberDiff line change
@@ -11,19 +11,6 @@ junits_dir = ARGV[0]
1111
abort("Usage: annotate <junits-dir>") unless junits_dir
1212
abort("#{junits_dir} does not exist") unless Dir.exist?(junits_dir)
1313

14-
job_pattern = ENV['BUILDKITE_PLUGIN_JUNIT_ANNOTATE_JOB_UUID_FILE_PATTERN']
15-
job_pattern = '-(.*).xml' if !job_pattern || job_pattern.empty?
16-
17-
failure_format = ENV['BUILDKITE_PLUGIN_JUNIT_ANNOTATE_FAILURE_FORMAT']
18-
failure_format = 'classname' if !failure_format || failure_format.empty?
19-
20-
class Failure < Struct.new(:name, :failed_test, :body, :job, :type, :message)
21-
end
22-
23-
junit_report_files = Dir.glob(File.join(junits_dir, "**", "*"))
24-
testcases = 0
25-
failures = []
26-
2714
def text_content(element)
2815
# Handle mulptiple CDATA/text children elements
2916
text = element.texts().map(&:value).join.strip
@@ -44,58 +31,66 @@ def message_content(element)
4431
end
4532
end
4633

34+
class Failure < Struct.new(:body, :message, :type, :file, :name, :suite_name)
35+
def self.from(element, testcase, testsuite)
36+
new(
37+
text_content(element),
38+
message_content(element),
39+
element.attributes['type'],
40+
testcase.attributes['file'],
41+
testcase.attributes['name'],
42+
testsuite.attributes['name']
43+
)
44+
end
45+
end
46+
47+
junit_report_files = Dir.glob(File.join(junits_dir, "**", "*"))
48+
stats = { skipped: 0, failures: 0, tests: 0, assertions: 0, time: 0.0 }
49+
failures = []
50+
4751
junit_report_files.sort.each do |file|
4852
next if File.directory?(file)
4953

5054
STDERR.puts "Parsing #{file.sub(junits_dir, '')}"
51-
job = File.basename(file)[/#{job_pattern}/, 1]
5255
xml = File.read(file)
5356
doc = REXML::Document.new(xml)
5457

55-
REXML::XPath.each(doc, '//testsuite//testcase') do |testcase|
56-
testcases += 1
57-
name = testcase.attributes['name'].to_s
58-
failed_test = testcase.attributes[failure_format].to_s
59-
testcase.elements.each("failure") do |failure|
60-
failures << Failure.new(name, failed_test, text_content(failure), job, :failure, message_content(failure))
61-
end
62-
testcase.elements.each("error") do |error|
63-
failures << Failure.new(name, failed_test, text_content(error), job, :error, message_content(error))
58+
REXML::XPath.each(doc, '//testsuite') do |testsuite|
59+
stats[:assertions] += testsuite.attributes['assertions'].to_i
60+
stats[:failures] += testsuite.attributes['failures'].to_i
61+
stats[:skipped] += testsuite.attributes['skipped'].to_i
62+
stats[:tests] += testsuite.attributes['tests'].to_i
63+
stats[:time] += testsuite.attributes['time'].to_f
64+
65+
testsuite.elements.each("testcase") do |testcase|
66+
testcase.elements.each("failure") do |element|
67+
failures << Failure.from(element, testcase, testsuite)
68+
end
69+
testcase.elements.each("error") do |element|
70+
failures << Failure.from(element, testcase, testsuite)
71+
end
6472
end
6573
end
6674
end
6775

6876
STDERR.puts "--- ❓ Checking failures"
69-
STDERR.puts "#{testcases} testcases found"
77+
STDERR.puts "Ran **#{stats[:tests]}** tests in **#{stats[:time].round(2)}s**."
7078

7179
if failures.empty?
7280
STDERR.puts "There were no failures/errors 🙌"
7381
exit 0
7482
else
75-
STDERR.puts "There #{failures.length == 1 ? "is 1 failure/error" : "are #{failures.length} failures/errors" } 😭"
83+
STDERR.puts "There #{failures.length == 1 ? "is **1*8 failure/error" : "are **#{failures.length}** failures/errors" } 😭"
7684
end
7785

7886
STDERR.puts "--- ✍️ Preparing annotation"
7987

80-
failures_count = failures.select {|f| f.type == :failure }.length
81-
errors_count = failures.select {|f| f.type == :error }.length
82-
83-
puts [
84-
failures_count == 0 ? nil : (failures_count == 1 ? "1 failure" : "#{failures_count} failures"),
85-
errors_count === 0 ? nil : (errors_count == 1 ? "1 error" : "#{errors_count} errors"),
86-
].compact.join(" and ") + ":\n\n"
87-
88+
puts "Ran **#{stats[:tests]}** tests in **#{stats[:time].round(2)}s**."
8889
failures.each do |failure|
8990
puts "<details>"
90-
puts "<summary><code>#{failure.name} in #{failure.failed_test}</code></summary>\n\n"
91-
if failure.message
92-
puts "<p>#{failure.message.chomp.strip}</p>\n\n"
93-
end
91+
puts "<summary><code>#{failure.suite_name}##{failure.name}</code></summary>\n\n"
9492
if failure.body
95-
puts "<pre><code>#{CGI.escapeHTML(failure.body.chomp.strip)}</code></pre>\n\n"
96-
end
97-
if failure.job
98-
puts "in <a href=\"##{failure.job}\">Job ##{failure.job}</a>"
93+
puts "<pre class=\"term\"><code>#{CGI.escapeHTML(failure.message.chomp.strip)}\n\n#{CGI.escapeHTML(failure.body.chomp.strip)}</code></pre>\n\n"
9994
end
10095
puts "</details>"
10196
puts "" unless failure == failures.last

0 commit comments

Comments
 (0)