Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add GitHub Actions annotations #34

Merged
merged 2 commits into from
Jan 11, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 21 additions & 8 deletions lib/puppet-lint.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
require 'puppet-lint/configuration'
require 'puppet-lint/data'
require 'puppet-lint/checks'
require 'puppet-lint/report/github'
require 'puppet-lint/bin'
require 'puppet-lint/monkeypatches'

Expand Down Expand Up @@ -121,6 +122,16 @@ def format_message(message)
puts " #{message[:reason]}" if message[:kind] == :ignored && !message[:reason].nil?
end

# Internal: Format a problem message and print it to STDOUT so GitHub Actions
# recognizes it as an annotation.
#
# message - A Hash containing all the information about a problem.
#
# Returns nothing.
def print_github_annotation(message)
puts PuppetLint::Report::GitHubActionsReporter.format_problem(path, message)
end

# Internal: Get the line of the manifest on which the problem was found
#
# message - A Hash containing all the information about a problem.
Expand Down Expand Up @@ -158,15 +169,17 @@ def report(problems)

message[:KIND] = message[:kind].to_s.upcase

if message[:kind] == :fixed || [message[:kind], :all].include?(configuration.error_level)
if configuration.json
message['context'] = get_context(message) if configuration.with_context
json << message
else
format_message(message)
print_context(message) if configuration.with_context
end
next unless message[:kind] == :fixed || [message[:kind], :all].include?(configuration.error_level)

if configuration.json
message['context'] = get_context(message) if configuration.with_context
json << message
else
format_message(message)
print_context(message) if configuration.with_context
end

print_github_annotation(message) if configuration.github_actions
end
puts JSON.pretty_generate(json) if configuration.json

Expand Down
1 change: 1 addition & 0 deletions lib/puppet-lint/configuration.rb
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,7 @@ def defaults
self.json = false
self.show_ignored = false
self.ignore_paths = ['vendor/**/*.pp']
self.github_actions = ENV.key?('GITHUB_ACTION')
end
end
end
27 changes: 27 additions & 0 deletions lib/puppet-lint/report/github.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# frozen_string_literal: true

class PuppetLint
module Report
# This formatter formats report data as GitHub Workflow commands resulting
# in GitHub check annotations when run within GitHub Actions.
class GitHubActionsReporter
ESCAPE_MAP = { '%' => '%25', "\n" => '%0A', "\r" => '%0D' }.freeze

def self.format_problem(file, problem)
format(
"\n::%<severity>s file=%<file>s,line=%<line>d,col=%<column>d::%<message>s (check: %<check>s)\n",
:severity => problem[:kind],
:file => file,
:line => problem[:line],
:column => problem[:column],
:message => github_escape(problem[:message]),
:check => problem[:check]
)
end

def self.github_escape(string)
string.gsub(Regexp.union(ESCAPE_MAP.keys), ESCAPE_MAP)
end
end
end
end
23 changes: 22 additions & 1 deletion spec/puppet-lint/configuration_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,10 @@
end

it 'should be able to set sane defaults' do
subject.defaults
override_env do
ENV.delete('GITHUB_ACTION')
subject.defaults
end
Comment on lines +52 to +55
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Annotating my own code: technically this is redundant now that there's ENV.delete() in spec_helper.rb, but it doesn't hurt to be explicit.


expect(subject.settings).to eq(
'with_filename' => false,
Expand All @@ -58,9 +61,27 @@
'log_format' => '',
'with_context' => false,
'fix' => false,
'github_actions' => false,
'show_ignored' => false,
'json' => false,
'ignore_paths' => ['vendor/**/*.pp']
)
end

it 'detects github actions' do
override_env do
ENV['GITHUB_ACTION'] = 'action'
subject.defaults
end

expect(subject.settings['github_actions']).to be(true)
end

def override_env
old_env = ENV.clone
yield
ensure
ENV.clear
ENV.update(old_env)
end
Comment on lines +80 to +86
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wasn't quite sure about this, but I wrote it on the train without internet access.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this comment resolvable?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well, it works. I just don't know if this is the desired solution in this repo.

end
3 changes: 3 additions & 0 deletions spec/spec_helper.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
# Disable GitHub Actions reporting since it breaks the test suite
ENV.delete('GITHUB_ACTION')
Comment on lines +1 to +2
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This isn't the cleanest, but I couldn't find a good way to consistently set the setting. Right now I don't think it would break anything.


if ENV['COVERAGE'] == 'yes' && RUBY_VERSION.start_with?('2.6.')
require 'simplecov'
SimpleCov.start do
Expand Down