Skip to content

Commit

Permalink
Merge pull request #1580 from klausbadelt/github-reporter
Browse files Browse the repository at this point in the history
Github Actions output format
  • Loading branch information
presidentbeef committed May 2, 2021
2 parents 386ac82 + 4983efe commit a0227fc
Show file tree
Hide file tree
Showing 7 changed files with 79 additions and 3 deletions.
4 changes: 4 additions & 0 deletions lib/brakeman.rb
Expand Up @@ -250,6 +250,8 @@ def self.get_formats_from_output_format output_format
[:to_sarif]
when :sonar, :to_sonar
[:to_sonar]
when :github, :to_github
[:to_github]
else
[:to_text]
end
Expand Down Expand Up @@ -283,6 +285,8 @@ def self.get_formats_from_output_files output_files
:to_sarif
when /\.sonar$/i
:to_sonar
when /\.github$/i
:to_github
else
:to_text
end
Expand Down
2 changes: 1 addition & 1 deletion lib/brakeman/options.rb
Expand Up @@ -233,7 +233,7 @@ def create_option_parser options

opts.on "-f",
"--format TYPE",
[:pdf, :text, :html, :csv, :tabs, :json, :markdown, :codeclimate, :cc, :plain, :table, :junit, :sarif, :sonar],
[:pdf, :text, :html, :csv, :tabs, :json, :markdown, :codeclimate, :cc, :plain, :table, :junit, :sarif, :sonar, :github],
"Specify output formats. Default is text" do |type|

type = "s" if type == :text
Expand Down
5 changes: 4 additions & 1 deletion lib/brakeman/report.rb
Expand Up @@ -6,7 +6,7 @@
class Brakeman::Report
attr_reader :tracker

VALID_FORMATS = [:to_html, :to_pdf, :to_csv, :to_json, :to_tabs, :to_hash, :to_s, :to_markdown, :to_codeclimate, :to_plain, :to_text, :to_junit]
VALID_FORMATS = [:to_html, :to_pdf, :to_csv, :to_json, :to_tabs, :to_hash, :to_s, :to_markdown, :to_codeclimate, :to_plain, :to_text, :to_junit, :to_github]

def initialize tracker
@app_tree = tracker.app_tree
Expand Down Expand Up @@ -48,6 +48,9 @@ def format format
when :to_sonar
require_report 'sonar'
Brakeman::Report::Sonar
when :to_github
require_report 'github'
Brakeman::Report::Github
else
raise "Invalid format: #{format}. Should be one of #{VALID_FORMATS.inspect}"
end
Expand Down
31 changes: 31 additions & 0 deletions lib/brakeman/report/report_github.rb
@@ -0,0 +1,31 @@
# Github Actions Formatter
# Formats warnings as workflow commands to create annotations in GitHub UI
class Brakeman::Report::Github < Brakeman::Report::Base
def generate_report
# @see https://docs.github.com/en/actions/reference/workflow-commands-for-github-actions#setting-a-warning-message
errors.concat(warnings).join("\n")
end

def warnings
all_warnings
.map { |warning| "::warning file=#{warning_file(warning)},line=#{warning.line}::#{warning.message}" }
end

def errors
tracker.errors.map do |error|
if error[:exception].is_a?(Racc::ParseError)
# app/services/balance.rb:4 :: parse error on value "..." (tDOT3)
file, line = error[:exception].message.split(':').map(&:strip)[0,2]
"::error file=#{file},line=#{line}::#{clean_message(error[:error])}"
else
"::error ::#{clean_message(error[:error])}"
end
end
end

private

def clean_message(msg)
msg.gsub('::','').squeeze(' ')
end
end
4 changes: 3 additions & 1 deletion test/tests/brakeman.rb
Expand Up @@ -287,6 +287,8 @@ def test_output_format
output_format_tester({:output_format => :to_markdown}, [:to_markdown])
output_format_tester({:output_format => :text}, [:to_text])
output_format_tester({:output_format => :to_text}, [:to_text])
output_format_tester({:output_format => :github}, [:to_github])
output_format_tester({:output_format => :to_github}, [:to_github])
output_format_tester({:output_format => :others}, [:to_text])

output_format_tester({:output_files => ['xx.html', 'xx.pdf']}, [:to_html, :to_pdf])
Expand All @@ -298,7 +300,7 @@ def test_output_format
output_format_tester({:output_files => ['xx.xx', 'xx.xx']}, [:to_text, :to_text])
output_format_tester({:output_files => ['xx.cc', 'xx.table']}, [:to_codeclimate, :to_table])
output_format_tester({:output_files => ['xx.plain', 'xx.text']}, [:to_text, :to_text])
output_format_tester({:output_files => ['xx.html', 'xx.pdf', 'xx.csv', 'xx.tabs', 'xx.json', 'xx.md']}, [:to_html, :to_pdf, :to_csv, :to_tabs, :to_json, :to_markdown])
output_format_tester({:output_files => ['xx.html', 'xx.pdf', 'xx.csv', 'xx.tabs', 'xx.json', 'xx.md', 'xx.github']}, [:to_html, :to_pdf, :to_csv, :to_tabs, :to_json, :to_markdown, :to_github])
end

def test_output_format_errors_raised
Expand Down
29 changes: 29 additions & 0 deletions test/tests/github_output.rb
@@ -0,0 +1,29 @@
require_relative '../test'

class TestGithubOutput < Minitest::Test
def setup
@@report ||= github_report
end

def test_report_format
assert_equal 33, @@report.lines.count
@@report.lines.each do |line|
assert line.start_with?('::'), 'Every line must start with `::`'
assert_equal 2, line.scan('::').count, 'Every line must have exactly 2 `::`'
end
end

def test_for_errors
assert_equal 2, @@report.lines.count {|line| line.start_with?('::error') }
assert_includes @@report, 'file=app/services/balance.rb,line=4'
end

private

def github_report
tracker = Brakeman.run("#{TEST_PATH}/apps/rails6")
tracker.error Racc::ParseError.new('app/services/balance.rb:4 :: parse error on value "..." (tDOT3)')
tracker.error StandardError.new('Something went wrong')
tracker.report.to_github
end
end
7 changes: 7 additions & 0 deletions test/tests/report_generation.rb
Expand Up @@ -142,6 +142,13 @@ def test_markdown_debug_sanity
@@tracker.options[:debug] = false
end

def test_github_sanity
report = @@report.to_github

assert report.is_a? String
assert report.include? "::warning"
end

def test_bad_format_type
assert_raises RuntimeError do
@@report.format(:to_something_else)
Expand Down

0 comments on commit a0227fc

Please sign in to comment.