Compare commits

...
This repository has been archived on 2023-10-25. You can view files and clone it, but cannot push or open issues or pull requests.

15 Commits

Author SHA1 Message Date
09178ef7bf
Some Docu 2021-04-14 12:58:17 +02:00
71b4a02b05
more corrections 2021-04-14 12:42:11 +02:00
8d4f7c6ab3
typo 2021-04-14 12:23:41 +02:00
abd4aff55b
properly get default values for report_name
rename field to report_name
2021-04-14 12:10:17 +02:00
f6604dcfa9
name variable from github config 2021-04-14 11:47:19 +02:00
Miguel Savignano
0bc53bbf5c update README with github token instructions 2020-12-21 22:12:53 +01:00
Miguel Savignano
4a754f8957 update CHANGELOG and README 2020-10-04 19:13:35 +02:00
Abimael Martell
b8506db951
Add percentage on result title (#4)
* Add percentage to action name

* Test with percentage in output title
2020-10-04 19:10:13 +02:00
Miguel Savignano
2454e13902 update action yml 2019-11-03 02:15:13 +01:00
Miguel Savignano
d734a59c05
Lcov report (#2)
* execute node bin

* calculate percentage for lcov file

* install node in docker image

* use relative path to bin folder

* update readme
2019-11-03 02:05:38 +01:00
Miguel Savignano
6dc7a86bd5 fix read json 2019-11-03 01:14:20 +01:00
Miguel Savignano
deeb00a902 update readme 2019-11-02 23:40:11 +01:00
Miguel Savignano
b657d2995c update readme 2019-11-02 23:31:51 +01:00
Miguel Savignano
17563c3632 update action description 2019-11-02 23:31:01 +01:00
Miguel Savignano
6ae146e422
Coverage check (#1)
* adapter for coverage

* report adapter

* generate coverage report

* use inputs
2019-11-02 23:25:41 +01:00
26 changed files with 505 additions and 293 deletions

View File

@ -3,3 +3,5 @@ Gemfile
Gemfile.lock
LICENSE
README.md
screenshots
.github

View File

@ -8,4 +8,4 @@ Style/Documentation:
Enabled: false
Metrics/LineLength:
Max: 120
Max: 150

View File

@ -1,6 +1,14 @@
# Changelog
## v1.2.0
- Added the coverage percent to result title on Check [#4](https://github.com/devmasx/coverage-check-action/pull/4)
## v1.1.0
- Lcov
## v1.0.0
- Create check run in github
- Adapter for brakeman report
- Simplecov

View File

@ -1,7 +1,8 @@
FROM ruby:2.6.5-alpine
RUN gem install brakeman
RUN apk add --update nodejs
COPY lib /action/lib
COPY bin /action/bin
CMD ["ruby", "/action/lib/index.rb"]

View File

@ -3,7 +3,6 @@
source 'https://rubygems.org'
group :development do
gem 'brakeman'
gem 'rubocop'
end

View File

@ -4,7 +4,6 @@ GEM
addressable (2.7.0)
public_suffix (>= 2.0.2, < 5.0)
ast (2.4.0)
brakeman (4.7.1)
coderay (1.1.2)
crack (0.4.3)
safe_yaml (~> 1.0.0)
@ -52,7 +51,6 @@ PLATFORMS
ruby
DEPENDENCIES
brakeman
pry
rspec
rubocop

View File

@ -1,34 +1,47 @@
## Brakeman github action
## Coverage check
Brakeman is a static analysis tool which checks Ruby on Rails applications for security vulnerabilities.
[See more](https://github.com/presidentbeef/brakeman)
A GitHub Action that check minimum coverage percentage!
This action requires a Github token with `checks:write` scope to allow create the check run using the Github API v3.
But no need to generate any new token, you can use the Github action token (`${{ github.token }}`)
### Usage
#### Lcov
```yml
- name: Brakeman
uses: devmasx/brakeman-linter-action@v1.0.0
env:
GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}}
- uses: devmasx/coverage-check-action@v1.2.0
with:
type: lcov
result_path: coverage/example.lcov
min_coverage: 90
token: ${{ github.token }}
```
### Custom report
#### [Simplecov](https://github.com/colszowka/simplecov)
```yml
- name: Install gems
run: |
gem install brakeman -v 4.5.0
- name: brakeman report
run: |
brakeman -f json > tmp/brakeman.json || exit 0
- name: Brakeman
uses: devmasx/brakeman-linter-action@v1.0.0
env:
GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}}
REPORT_PATH: tmp/brakeman.json
- uses: devmasx/coverage-check-action@v1.2.0
with:
type: simplecov
result_path: coverage/.last_run.json
min_coverage: 90
token: ${{ github.token }}
```
#### Report name
```yml
- uses: devmasx/coverage-check-action@v1.2.0
with:
type: lcov
result_path: coverage/example.lcov
min_coverage: 90
token: ${{ github.token }}
report_name: "My Github Action Check Name"
```
## Screenshots
![example GitHub Action UI](./screenshots/action.png)
![example Pull request](./screenshots/pull_request.png)
![Success](./screenshots/success.png)
![Fail](./screenshots/fail.png)

View File

@ -1,9 +1,26 @@
name: "Brakeman linter"
description: "A GitHub Action that lints your Ruby code with Brakeman!"
name: "Coverage check"
description: "A GitHub Action that check minimum coverage percentage!"
author: Miguel Savignano
branding:
icon: "check-square"
color: "green"
inputs:
type:
description: "lcov | simplecov"
required: true
default: "lcov"
token:
description: "Github token for create checks"
required: true
min_coverage:
description: "Minimum coverage"
default: "80"
report_name:
description: "Name of the github action check"
default: "Coverage"
result_path:
description: "Json with coverage result"
required: true
runs:
using: "docker"
image: "Dockerfile"
branding:
icon: "check-square"
color: "red"

129
bin/lcov-parse.js Normal file
View File

@ -0,0 +1,129 @@
/*
Copyright (c) 2012, Yahoo! Inc. All rights reserved.
Code licensed under the BSD License:
http://yuilibrary.com/license/
*/
var fs = require('fs'),
path = require('path');
/* istanbul ignore next */
var exists = fs.exists || path.exists;
var walkFile = function (str, cb) {
var data = [], item;
['end_of_record'].concat(str.split('\n')).forEach(function (line) {
line = line.trim();
var allparts = line.split(':'),
parts = [allparts.shift(), allparts.join(':')],
lines, fn;
switch (parts[0].toUpperCase()) {
case 'TN':
item.title = parts[1].trim();
break;
case 'SF':
item.file = parts.slice(1).join(':').trim();
break;
case 'FNF':
item.functions.found = Number(parts[1].trim());
break;
case 'FNH':
item.functions.hit = Number(parts[1].trim());
break;
case 'LF':
item.lines.found = Number(parts[1].trim());
break;
case 'LH':
item.lines.hit = Number(parts[1].trim());
break;
case 'DA':
lines = parts[1].split(',');
item.lines.details.push({
line: Number(lines[0]),
hit: Number(lines[1])
});
break;
case 'FN':
fn = parts[1].split(',');
item.functions.details.push({
name: fn[1],
line: Number(fn[0])
});
break;
case 'FNDA':
fn = parts[1].split(',');
item.functions.details.some(function (i, k) {
if (i.name === fn[1] && i.hit === undefined) {
item.functions.details[k].hit = Number(fn[0]);
return true;
}
});
break;
case 'BRDA':
fn = parts[1].split(',');
item.branches.details.push({
line: Number(fn[0]),
block: Number(fn[1]),
branch: Number(fn[2]),
taken: ((fn[3] === '-') ? 0 : Number(fn[3]))
});
break;
case 'BRF':
item.branches.found = Number(parts[1]);
break;
case 'BRH':
item.branches.hit = Number(parts[1]);
break;
}
if (line.indexOf('end_of_record') > -1) {
data.push(item);
item = {
lines: {
found: 0,
hit: 0,
details: []
},
functions: {
hit: 0,
found: 0,
details: []
},
branches: {
hit: 0,
found: 0,
details: []
}
};
}
});
data.shift();
if (data.length) {
cb(null, data);
} else {
cb('Failed to parse string');
}
};
var parse = function (file, cb) {
exists(file, function (x) {
if (!x) {
return walkFile(file, cb);
}
fs.readFile(file, 'utf8', function (err, str) {
walkFile(str, cb);
});
});
};
var path = process.argv[2]
parse(path, function (err, data) {
console.log(JSON.stringify(data, null, 2))
});
// console.log(process.argv[2])

46
lib/coverage_report.rb Normal file
View File

@ -0,0 +1,46 @@
# frozen_string_literal: true
class CoverageReport
class << self
def generate(type, report_path, data)
if type == 'simplecov'
simplecov(report_path, data)
elsif type == 'lcov'
lcov(report_path, data)
else
raise 'InvalidCoverageReportType'
end
end
def simplecov(report_path, data)
report = read_json(report_path)
minumum_percent = data[:min]
covered_percent = report.dig('result', 'covered_percent')
{ 'lines' => { 'covered_percent' => covered_percent, 'minumum_percent' => minumum_percent } }
end
def lcov(report_path, data)
lcov_result = execute_lcov_parse(report_path)
minumum_percent = data[:min]
{ 'lines' => { 'covered_percent' => lcov_covered_percent(lcov_result), 'minumum_percent' => minumum_percent } }
end
private
def lcov_covered_percent(lcov_result)
lines = lcov_result.map { |r| r['lines']['details'] }.flatten
total_lines = lines.count.to_f.round(2)
covered_lines = lines.select { |r| r['hit'] >= 1 }.count.to_f
((covered_lines / total_lines) * 100).round(2)
end
def execute_lcov_parse(report_path)
bin_path = "#{File.dirname(__FILE__)}/../bin"
JSON.parse(`node #{bin_path}/lcov-parse.js #{report_path}`)
end
def read_json(path)
JSON.parse(File.read(path))
end
end
end

View File

@ -1,13 +1,12 @@
# frozen_string_literal: true
class GithubCheckRunService
CHECK_NAME = 'Brakeman'
def initialize(report, github_data, report_adapter)
def initialize(report, github_data, report_name, report_adapter)
@report = report
@github_data = github_data
@report_name = report_name
@report_adapter = report_adapter
@client = GithubClient.new(@github_data[:token], user_agent: 'brakeman-action')
@client = GithubClient.new(@github_data[:token], user_agent: 'coverage-action')
end
def run
@ -18,6 +17,7 @@ class GithubCheckRunService
@summary = @report_adapter.summary(@report)
@annotations = @report_adapter.annotations(@report)
@conclusion = @report_adapter.conslusion(@report)
@percent = @report_adapter.lines_covered_percent(@report)
@client.patch(
"#{endpoint_url}/#{id}",
@ -33,7 +33,7 @@ class GithubCheckRunService
def create_check_payload
{
name: CHECK_NAME,
name: @report_name,
head_sha: @github_data[:sha],
status: 'in_progress',
started_at: Time.now.iso8601
@ -42,13 +42,13 @@ class GithubCheckRunService
def update_check_payload
{
name: CHECK_NAME,
name: @report_name,
head_sha: @github_data[:sha],
status: 'completed',
completed_at: Time.now.iso8601,
conclusion: @conclusion,
output: {
title: CHECK_NAME,
title: "#{@report_name} #{@percent}%",
summary: @summary,
annotations: @annotations
}

View File

@ -6,6 +6,7 @@ require 'time'
require_relative './report_adapter'
require_relative './github_check_run_service'
require_relative './github_client'
require_relative './coverage_report'
def read_json(path)
JSON.parse(File.read(path))
@ -14,16 +15,16 @@ end
@event_json = read_json(ENV['GITHUB_EVENT_PATH']) if ENV['GITHUB_EVENT_PATH']
@github_data = {
sha: ENV['GITHUB_SHA'],
token: ENV['GITHUB_TOKEN'],
token: ENV['INPUT_TOKEN'],
owner: ENV['GITHUB_REPOSITORY_OWNER'] || @event_json.dig('repository', 'owner', 'login'),
repo: ENV['GITHUB_REPOSITORY_NAME'] || @event_json.dig('repository', 'name')
repo: ENV['GITHUB_REPOSITORY_NAME'] || @event_json.dig('repository', 'name'),
}
@report =
if ENV['REPORT_PATH']
read_json(ENV['REPORT_PATH'])
else
Dir.chdir(ENV['GITHUB_WORKSPACE']) { JSON.parse(`brakeman -f json`) }
end
@coverage_type = ENV['INPUT_TYPE']
@report_path = ENV['INPUT_RESULT_PATH']
@report_name = ENV['INPUT_REPORT_NAME']
@data = { min: ENV['INPUT_MIN_COVERAGE'] }
GithubCheckRunService.new(@report, @github_data, ReportAdapter).run
@report = CoverageReport.generate(@coverage_type, @report_path, @data)
GithubCheckRunService.new(@report, @github_data, @report_name, ReportAdapter).run

View File

@ -7,40 +7,29 @@ class ReportAdapter
ANNOTATION_LEVEL = { notice: 'notice', warning: 'warning', failure: 'failure' }.freeze
def conslusion(report)
return CONCLUSION_TYPES[:failure] if security_warnings(report).positive?
CONCLUSION_TYPES[:success]
lines_covered_percent(report) >= lines_minimum_percent(report).to_f ? CONCLUSION_TYPES[:success] : CONCLUSION_TYPES[:failure]
end
def summary(report)
"**Brakeman Report**:\n#{security_warnings(report)} security warnings\n#{check_table(report)}"
"**Coverage**:\n\n#{table_head}\n| Lines | #{lines_covered_percent(report)}% | #{lines_minimum_percent(report)}% |\n"
end
def annotations(report)
report['warnings'].map do |error|
{
'path' => error['file'],
'start_line' => error['line'],
'end_line' => error['line'],
'annotation_level' => ANNOTATION_LEVEL[:warning],
'title' => "#{error['confidence']} - #{error['check_name']}",
'message' => error['message']
}
end
def annotations(_report)
[]
end
def lines_covered_percent(report)
@lines_covered_percent ||= report.dig('lines', 'covered_percent')
end
private
def check_table(report)
uniq_checks(report).reduce('') { |memo, check| memo + "- [#{check[:check_name]}](#{check[:link]})\n" }
def table_head
"| Type | covered | minimum |\n| ----- | ------- | ------- |"
end
def uniq_checks(report)
report['warnings'].map { |w| { check_name: w['check_name'], link: w['link'] } }.uniq { |w| w[:check_name] }
end
def security_warnings(report)
report['scan_info']['security_warnings']
def lines_minimum_percent(report)
@lines_minimum_percent ||= report.dig('lines', 'minumum_percent')
end
end
end

Binary file not shown.

Before

Width:  |  Height:  |  Size: 70 KiB

BIN
screenshots/fail.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 87 KiB

BIN
screenshots/success.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

View File

@ -0,0 +1,15 @@
# frozen_string_literal: true
require './spec/spec_helper'
describe CoverageReport do
it '.simplecov' do
result = CoverageReport.simplecov('./spec/fixtures/simplecov.json', min: 80)
expect(result['lines']['covered_percent']).to eq(80.5)
end
it '.lcov' do
result = CoverageReport.lcov('./spec/fixtures/example.lcov', min: 80)
expect(result['lines']['covered_percent']).to eq(85.61)
end
end

193
spec/fixtures/example.lcov vendored Normal file
View File

@ -0,0 +1,193 @@
SF:./app/controllers/application_controller.rb
DA:1,1
DA:2,1
end_of_record
SF:./app/controllers/posts_controller.rb
DA:1,1
DA:2,1
DA:6,1
DA:7,1
DA:12,1
DA:16,1
DA:17,1
DA:21,1
DA:26,1
DA:27,0
DA:29,0
DA:30,0
DA:31,0
DA:32,0
DA:34,0
DA:35,0
DA:42,1
DA:43,0
DA:44,0
DA:45,0
DA:46,0
DA:48,0
DA:49,0
DA:56,1
DA:57,0
DA:58,0
DA:59,0
DA:60,0
DA:64,1
DA:66,1
DA:67,0
DA:71,1
DA:72,0
end_of_record
SF:./app/helpers/application_helper.rb
DA:1,1
end_of_record
SF:./app/helpers/posts_helper.rb
DA:1,1
end_of_record
SF:./app/models/application_record.rb
DA:1,1
DA:2,1
end_of_record
SF:./app/models/post.rb
DA:1,1
end_of_record
SF:./config/application.rb
DA:1,1
DA:3,1
DA:7,1
DA:9,1
DA:10,1
DA:12,1
end_of_record
SF:./config/boot.rb
DA:1,1
DA:3,1
DA:4,1
end_of_record
SF:./config/environment.rb
DA:2,1
DA:5,1
end_of_record
SF:./config/environments/test.rb
DA:1,1
DA:8,1
DA:13,1
DA:16,1
DA:17,1
DA:22,1
DA:23,1
DA:26,1
DA:29,1
DA:32,1
DA:34,1
DA:39,1
DA:42,1
end_of_record
SF:./config/initializers/application_controller_renderer.rb
end_of_record
SF:./config/initializers/assets.rb
DA:4,1
DA:9,1
end_of_record
SF:./config/initializers/backtrace_silencers.rb
end_of_record
SF:./config/initializers/content_security_policy.rb
end_of_record
SF:./config/initializers/cookies_serializer.rb
DA:5,1
end_of_record
SF:./config/initializers/filter_parameter_logging.rb
DA:4,1
end_of_record
SF:./config/initializers/inflections.rb
end_of_record
SF:./config/initializers/mime_types.rb
end_of_record
SF:./config/initializers/wrap_parameters.rb
DA:7,1
DA:8,2
end_of_record
SF:./config/routes.rb
DA:1,1
DA:3,1
DA:4,1
DA:5,1
DA:6,1
end_of_record
SF:./spec/helpers/posts_helper_spec.rb
DA:1,1
DA:13,1
DA:14,1
end_of_record
SF:./spec/models/post_spec.rb
DA:1,1
DA:3,1
DA:4,1
end_of_record
SF:./spec/requests/posts_spec.rb
DA:1,1
DA:3,1
DA:4,1
DA:5,1
DA:6,1
DA:7,1
end_of_record
SF:./spec/routing/posts_routing_spec.rb
DA:1,1
DA:3,1
DA:4,1
DA:5,1
DA:6,1
DA:9,1
DA:10,1
DA:13,1
DA:14,1
DA:17,1
DA:18,1
DA:22,1
DA:23,1
DA:26,1
DA:27,1
DA:30,1
DA:31,1
DA:34,1
DA:35,1
end_of_record
SF:./spec/views/posts/edit.html.erb_spec.rb
DA:1,1
DA:3,1
DA:4,1
DA:5,1
DA:8,1
DA:9,1
DA:11,1
end_of_record
SF:./spec/views/posts/index.html.erb_spec.rb
DA:1,1
DA:3,1
DA:4,1
DA:5,1
DA:11,1
DA:12,1
end_of_record
SF:./spec/views/posts/new.html.erb_spec.rb
DA:1,1
DA:3,1
DA:4,1
DA:5,1
DA:8,1
DA:9,1
DA:11,1
end_of_record
SF:./spec/views/posts/show.html.erb_spec.rb
DA:1,1
DA:3,1
DA:4,1
DA:5,1
DA:8,1
DA:9,1
end_of_record

View File

@ -1,34 +0,0 @@
[
{
"path": "app/controllers/posts_controller.rb",
"start_line": 29,
"end_line": 29,
"annotation_level": "warning",
"title": "High - Evaluation",
"message": "User input in eval"
},
{
"path": "app/controllers/posts_controller.rb",
"start_line": 18,
"end_line": 18,
"annotation_level": "warning",
"title": "High - MassAssignment",
"message": "Parameters should be whitelisted for mass assignment"
},
{
"path": "app/controllers/posts_controller.rb",
"start_line": 19,
"end_line": 19,
"annotation_level": "warning",
"title": "High - MassAssignment",
"message": "Parameters should be whitelisted for mass assignment"
},
{
"path": "app/controllers/posts_controller.rb",
"start_line": 13,
"end_line": 13,
"annotation_level": "warning",
"title": "Medium - SQL",
"message": "Possible SQL injection"
}
]

View File

@ -1,5 +1,5 @@
**Brakeman Report**:
4 security warnings
- [Evaluation](https://brakemanscanner.org/docs/warning_types/dangerous_eval/)
- [MassAssignment](https://brakemanscanner.org/docs/warning_types/mass_assignment/)
- [SQL](https://brakemanscanner.org/docs/warning_types/sql_injection/)
**Coverage**:
| Type | covered | minimum |
| ----- | ------- | ------- |
| Lines | 80% | 80% |

View File

@ -1,170 +0,0 @@
{
"scan_info": {
"app_path": "/home/masx/developer/dockerize-rails",
"rails_version": "5.2.2",
"security_warnings": 4,
"start_time": "2019-11-01 22:07:50 +0100",
"end_time": "2019-11-01 22:07:50 +0100",
"duration": 0.166390277,
"checks_performed": [
"BasicAuth",
"BasicAuthTimingAttack",
"ContentTag",
"CookieSerialization",
"CreateWith",
"CrossSiteScripting",
"DefaultRoutes",
"Deserialize",
"DetailedExceptions",
"DigestDoS",
"DynamicFinders",
"EscapeFunction",
"Evaluation",
"Execute",
"FileAccess",
"FileDisclosure",
"FilterSkipping",
"ForgerySetting",
"HeaderDoS",
"I18nXSS",
"JRubyXML",
"JSONEncoding",
"JSONParsing",
"LinkTo",
"LinkToHref",
"MailTo",
"MassAssignment",
"MimeTypeDoS",
"ModelAttrAccessible",
"ModelAttributes",
"ModelSerialize",
"NestedAttributes",
"NestedAttributesBypass",
"NumberToCurrency",
"PermitAttributes",
"QuoteTableName",
"Redirect",
"RegexDoS",
"Render",
"RenderDoS",
"RenderInline",
"ResponseSplitting",
"RouteDoS",
"SQL",
"SQLCVEs",
"SSLVerify",
"SafeBufferManipulation",
"SanitizeMethods",
"SelectTag",
"SelectVulnerability",
"Send",
"SendFile",
"SessionManipulation",
"SessionSettings",
"SimpleFormat",
"SingleQuotes",
"SkipBeforeFilter",
"SprocketsPathTraversal",
"StripTags",
"SymbolDoSCVE",
"TranslateBug",
"UnsafeReflection",
"ValidationRegex",
"WithoutProtection",
"XMLDoS",
"YAMLParsing"
],
"number_of_controllers": 2,
"number_of_models": 2,
"number_of_templates": 7,
"ruby_version": "2.6.3",
"brakeman_version": "4.7.1"
},
"warnings": [
{
"warning_type": "Dangerous Eval",
"warning_code": 13,
"fingerprint": "490f917262d1384df60e24097536f6c9039e5f5ba11fe11bf0981109cd286fc5",
"check_name": "Evaluation",
"message": "User input in eval",
"file": "app/controllers/posts_controller.rb",
"line": 29,
"link": "https://brakemanscanner.org/docs/warning_types/dangerous_eval/",
"code": "eval(params)",
"render_path": null,
"location": {
"type": "method",
"class": "PostsController",
"method": "create"
},
"user_input": "params",
"confidence": "High"
},
{
"warning_type": "Mass Assignment",
"warning_code": 70,
"fingerprint": "5b486a498b14e1a12361c50863e2770c966799c9d5c6b6b9ab9bd8797c28a986",
"check_name": "MassAssignment",
"message": "Parameters should be whitelisted for mass assignment",
"file": "app/controllers/posts_controller.rb",
"line": 18,
"link": "https://brakemanscanner.org/docs/warning_types/mass_assignment/",
"code": "params.permit!",
"render_path": null,
"location": {
"type": "method",
"class": "PostsController",
"method": "new"
},
"user_input": null,
"confidence": "High"
},
{
"warning_type": "Mass Assignment",
"warning_code": 70,
"fingerprint": "5b486a498b14e1a12361c50863e2770c966799c9d5c6b6b9ab9bd8797c28a986",
"check_name": "MassAssignment",
"message": "Parameters should be whitelisted for mass assignment",
"file": "app/controllers/posts_controller.rb",
"line": 19,
"link": "https://brakemanscanner.org/docs/warning_types/mass_assignment/",
"code": "params.permit!",
"render_path": null,
"location": {
"type": "method",
"class": "PostsController",
"method": "new"
},
"user_input": null,
"confidence": "High"
},
{
"warning_type": "SQL Injection",
"warning_code": 0,
"fingerprint": "6e457f0a360661641a71555352f13a7cb2d983916b936007fce4e3826b837402",
"check_name": "SQL",
"message": "Possible SQL injection",
"file": "app/controllers/posts_controller.rb",
"line": 13,
"link": "https://brakemanscanner.org/docs/warning_types/sql_injection/",
"code": "User.where(\"#{params[:query]}\")",
"render_path": null,
"location": {
"type": "method",
"class": "PostsController",
"method": "show"
},
"user_input": "params[:query]",
"confidence": "Medium"
}
],
"ignored_warnings": [
],
"errors": [
],
"obsolete": [
]
}

5
spec/fixtures/simplecov.json vendored Normal file
View File

@ -0,0 +1,5 @@
{
"result": {
"covered_percent": 80.5
}
}

View File

@ -3,9 +3,12 @@
require './spec/spec_helper'
describe GithubCheckRunService do
let(:brakeman_report) { JSON(File.read('./spec/fixtures/report.json')) }
let(:report) do
{ 'lines' => { 'covered_percent' => 80, 'minumum_percent' => 80 } }
end
let(:github_data) { { sha: 'sha', token: 'token', owner: 'owner', repo: 'repository_name' } }
let(:service) { GithubCheckRunService.new(brakeman_report, github_data, ReportAdapter) }
let(:report_name) { 'Coverage' }
let(:service) { GithubCheckRunService.new(report, github_data, report_name, ReportAdapter) }
it '#run' do
stub_request(:any, 'https://api.github.com/repos/owner/repository_name/check-runs/id')

View File

@ -3,12 +3,8 @@
require './spec/spec_helper'
describe ReportAdapter do
let(:brakeman_report) do
JSON(File.read('./spec/fixtures/report.json'))
end
let(:spec_annotations) do
JSON(File.read('./spec/fixtures/output/annotations.json'))
let(:report) do
{ 'lines' => { 'covered_percent' => 80, 'minumum_percent' => 80 } }
end
let(:spec_summary) do
@ -18,17 +14,17 @@ describe ReportAdapter do
let(:adapter) { ReportAdapter }
it '.conslusion' do
result = adapter.conslusion(brakeman_report)
expect(result).to eq('failure')
result = adapter.conslusion(report)
expect(result).to eq('success')
end
it '.summary' do
result = adapter.summary(brakeman_report)
result = adapter.summary(report)
expect(result).to eq(spec_summary)
end
it '.annotations' do
result = adapter.annotations(brakeman_report)
expect(result).to eq(spec_annotations)
result = adapter.annotations(report)
expect(result).to eq([])
end
end

View File

@ -6,3 +6,4 @@ require 'pry'
require './lib/report_adapter'
require './lib/github_check_run_service'
require './lib/github_client'
require './lib/coverage_report'