Skip to content

Commit

Permalink
Return zero exit status on error
Browse files Browse the repository at this point in the history
  • Loading branch information
tessereth committed May 10, 2018
1 parent b138932 commit 632df1c
Show file tree
Hide file tree
Showing 8 changed files with 90 additions and 5 deletions.
2 changes: 2 additions & 0 deletions .buildkite/pipeline.yml
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ steps:
show_first: 3
context: simple-annotation
style: default
fail_on_error: true

# Add test summary, including failure details
- label: ":pencil: details"
Expand Down Expand Up @@ -87,3 +88,4 @@ steps:
show_first: 3
context: verbose-annotation
style: info
fail_on_error: false
3 changes: 3 additions & 0 deletions .rubocop.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,3 +31,6 @@ Metrics/PerceivedComplexity:

Style/GuardClause:
Enabled: false

Layout/MultilineMethodCallIndentation:
EnforcedStyle: indented
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,8 @@ Other formatter options are:

* `context:` The Buildkite annotation context. Defaults to `test-summary`.
* `style:` Set the annotation style. Defaults to `error`.
* `fail_on_error:` Whether the command should return non-zero exit status on failure. Defaults to `false` so failing
to annotate a build does not cause the entire pipeline to fail.

## Developing

Expand Down
12 changes: 11 additions & 1 deletion hooks/command
Original file line number Diff line number Diff line change
@@ -1,9 +1,19 @@
#!/bin/bash

set -euo pipefail
set -eEuo pipefail

DOCKER_REPO=tessereth/test-summary-buildkite-plugin

on_failure() {
echo "Command failed with exit status: $?"
if [[ "$BUILDKITE_PLUGIN_TEST_SUMMARY_FAIL_ON_ERROR" != "true" ]]; then
echo "Suppressing failure so pipeline can continue (if you do not want this behaviour, set fail_on_error to true)"
exit 0
fi
}

trap on_failure ERR

# cd to plugin directory
cd "$( dirname "${BASH_SOURCE[0]}" )/.."
TAG=$(git describe --tags --exact-match 2> /dev/null || true)
Expand Down
4 changes: 2 additions & 2 deletions lib/test_summary_buildkite_plugin/input.rb
Original file line number Diff line number Diff line change
Expand Up @@ -72,8 +72,8 @@ def job_id_regex
class OneLine < Base
def file_contents_to_failures(str)
str.split("\n")[crop.start..crop.end]
.reject(&:empty?)
.map { |line| Failure::Unstructured.new(line) }
.reject(&:empty?)
.map { |line| Failure::Unstructured.new(line) }
end

private
Expand Down
21 changes: 20 additions & 1 deletion lib/test_summary_buildkite_plugin/runner.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,25 @@ def initialize(options)
end

def run
markdown = inputs.map { |input| formatter.markdown(input) }.compact.join("\n\n")
markdown = inputs.map { |input| input_to_markdown(input) }.compact.join("\n\n")
if markdown.empty?
puts('No errors found! 🎉')
else
annotate(markdown)
end
end

def input_to_markdown(input)
formatter.markdown(input)
rescue StandardError => e
if fail_on_error
raise
else
log_error(e)
nil
end
end

def annotate(markdown)
Agent.run('annotate', '--context', context, '--style', style, stdin: markdown)
end
Expand All @@ -36,5 +47,13 @@ def context
def style
options[:style] || 'error'
end

def fail_on_error
options[:fail_on_error] || false
end

def log_error(err)
puts "#{err.class}: #{err.message}\n\n#{err.backtrace.join("\n")}"
end
end
end
2 changes: 2 additions & 0 deletions plugin.yml
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,8 @@ configuration:
type: string
style:
type: string
fail_on_error:
type: boolean
required:
- inputs
additionalProperties: false
49 changes: 48 additions & 1 deletion spec/test_summary_buildkite_plugin/runner_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,9 @@

RSpec.describe TestSummaryBuildkitePlugin::Runner do
let(:params) { { inputs: inputs } }
let(:runner) { described_class.new(params) }

subject(:run) { described_class.new(params).run }
subject(:run) { runner.run }

context 'with no failures' do
let(:inputs) do
Expand Down Expand Up @@ -54,4 +55,50 @@
end
end
end

context 'formatter raises exceptions' do
let(:inputs) do
[
{
label: 'rspec',
type: 'junit',
artifact_path: 'rspec*'
},
{
label: 'eslint',
type: 'oneline',
artifact_path: 'eslint*'
}
]
end

let(:formatter) { spy }

before do
allow(runner).to receive(:formatter).and_return(formatter)
allow(formatter).to receive(:markdown).with(an_instance_of(TestSummaryBuildkitePlugin::Input::JUnit))
.and_raise('life sucks')
allow(formatter).to receive(:markdown).with(an_instance_of(TestSummaryBuildkitePlugin::Input::OneLine))
.and_return('awesome markdown')
end

context 'without fail_on_error' do
it 'continues' do
run
expect(agent_annotate_commands.first).to include(stdin: 'awesome markdown')
end

it 'logs the error' do
expect { run }.to output(/life sucks/).to_stdout
end
end

context 'with fail_on_error' do
let(:params) { { inputs: inputs, fail_on_error: true } }

it 'raises error' do
expect { run }.to raise_error('life sucks')
end
end
end
end

0 comments on commit 632df1c

Please sign in to comment.