Compare commits
15 Commits
master
...
coverage-c
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ec568a8682 | ||
|
|
829bd10190 | ||
|
|
21926a5e7d | ||
|
|
78e98633e0 | ||
|
|
7436a56daa | ||
|
|
96f5618266 | ||
|
|
25b58a6a5d | ||
|
|
1c13cdc80e | ||
|
|
22a9598b0f | ||
|
|
10ef5432cc | ||
|
|
6fe95f9b39 | ||
|
|
eb7a4513da | ||
|
|
e86bde2331 | ||
|
|
9247c263a3 | ||
|
|
d7c0892c88 |
@ -3,5 +3,3 @@ Gemfile
|
|||||||
Gemfile.lock
|
Gemfile.lock
|
||||||
LICENSE
|
LICENSE
|
||||||
README.md
|
README.md
|
||||||
screenshots
|
|
||||||
.github
|
|
||||||
|
|||||||
10
CHANGELOG.md
10
CHANGELOG.md
@ -1,14 +1,6 @@
|
|||||||
# Changelog
|
# 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
|
## v1.0.0
|
||||||
|
|
||||||
- Create check run in github
|
- Create check run in github
|
||||||
- Simplecov
|
- Adapter for brakeman report
|
||||||
|
|||||||
@ -1,8 +1,7 @@
|
|||||||
FROM ruby:2.6.5-alpine
|
FROM ruby:2.6.5-alpine
|
||||||
|
|
||||||
RUN apk add --update nodejs
|
RUN gem install brakeman
|
||||||
|
|
||||||
COPY lib /action/lib
|
COPY lib /action/lib
|
||||||
COPY bin /action/bin
|
|
||||||
|
|
||||||
CMD ["ruby", "/action/lib/index.rb"]
|
CMD ["ruby", "/action/lib/index.rb"]
|
||||||
|
|||||||
1
Gemfile
1
Gemfile
@ -3,6 +3,7 @@
|
|||||||
source 'https://rubygems.org'
|
source 'https://rubygems.org'
|
||||||
|
|
||||||
group :development do
|
group :development do
|
||||||
|
gem 'brakeman'
|
||||||
gem 'rubocop'
|
gem 'rubocop'
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@ -4,6 +4,7 @@ GEM
|
|||||||
addressable (2.7.0)
|
addressable (2.7.0)
|
||||||
public_suffix (>= 2.0.2, < 5.0)
|
public_suffix (>= 2.0.2, < 5.0)
|
||||||
ast (2.4.0)
|
ast (2.4.0)
|
||||||
|
brakeman (4.7.1)
|
||||||
coderay (1.1.2)
|
coderay (1.1.2)
|
||||||
crack (0.4.3)
|
crack (0.4.3)
|
||||||
safe_yaml (~> 1.0.0)
|
safe_yaml (~> 1.0.0)
|
||||||
@ -51,6 +52,7 @@ PLATFORMS
|
|||||||
ruby
|
ruby
|
||||||
|
|
||||||
DEPENDENCIES
|
DEPENDENCIES
|
||||||
|
brakeman
|
||||||
pry
|
pry
|
||||||
rspec
|
rspec
|
||||||
rubocop
|
rubocop
|
||||||
|
|||||||
36
README.md
36
README.md
@ -1,44 +1,18 @@
|
|||||||
## Coverage check
|
## Brakeman github action
|
||||||
|
|
||||||
A GitHub Action that check minimum coverage percentage!
|
Check your 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
|
### Usage
|
||||||
|
|
||||||
#### Lcov
|
|
||||||
|
|
||||||
```yml
|
|
||||||
- uses: devmasx/coverage-check-action@v1.2.0
|
|
||||||
with:
|
|
||||||
type: lcov
|
|
||||||
result_path: coverage/example.lcov
|
|
||||||
min_coverage: 90
|
|
||||||
token: ${{ github.token }}
|
|
||||||
```
|
|
||||||
|
|
||||||
#### [Simplecov](https://github.com/colszowka/simplecov)
|
#### [Simplecov](https://github.com/colszowka/simplecov)
|
||||||
|
|
||||||
```yml
|
```yml
|
||||||
- uses: devmasx/coverage-check-action@v1.2.0
|
- uses: devmasx/coverage-check-action@coverage-check
|
||||||
with:
|
with:
|
||||||
type: simplecov
|
|
||||||
result_path: coverage/.last_run.json
|
result_path: coverage/.last_run.json
|
||||||
|
token: ${{secrets.GITHUB_TOKEN}}
|
||||||
|
type: simplecov
|
||||||
min_coverage: 90
|
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
|
## Screenshots
|
||||||
|
|||||||
14
action.yml
14
action.yml
@ -1,23 +1,21 @@
|
|||||||
name: "Coverage check"
|
name: "Brakeman linter"
|
||||||
description: "A GitHub Action that check minimum coverage percentage!"
|
description: "A GitHub Action that lints your Ruby code with Brakeman!"
|
||||||
author: Miguel Savignano
|
author: Miguel Savignano
|
||||||
branding:
|
branding:
|
||||||
icon: "check-square"
|
icon: "check-square"
|
||||||
color: "green"
|
color: "red"
|
||||||
inputs:
|
inputs:
|
||||||
type:
|
type:
|
||||||
description: "lcov | simplecov"
|
description: "simplecov | jest"
|
||||||
required: true
|
required: true
|
||||||
default: "lcov"
|
default: "simplecov"
|
||||||
token:
|
token:
|
||||||
description: "Github token for create checks"
|
description: "Github token for create checks"
|
||||||
required: true
|
required: true
|
||||||
|
default: "World"
|
||||||
min_coverage:
|
min_coverage:
|
||||||
description: "Minimum coverage"
|
description: "Minimum coverage"
|
||||||
default: "80"
|
default: "80"
|
||||||
report_name:
|
|
||||||
description: "Name of the github action check"
|
|
||||||
default: "Coverage"
|
|
||||||
result_path:
|
result_path:
|
||||||
description: "Json with coverage result"
|
description: "Json with coverage result"
|
||||||
required: true
|
required: true
|
||||||
|
|||||||
@ -1,129 +0,0 @@
|
|||||||
/*
|
|
||||||
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])
|
|
||||||
@ -1,46 +1,33 @@
|
|||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
class CoverageReport
|
class CoverageReport
|
||||||
class << self
|
def self.generate(type, report_path, data)
|
||||||
def generate(type, report_path, data)
|
if type == 'simplecov'
|
||||||
if type == 'simplecov'
|
simplecov(report_path, data)
|
||||||
simplecov(report_path, data)
|
elsif type == 'jest'
|
||||||
elsif type == 'lcov'
|
jest(report_path, data)
|
||||||
lcov(report_path, data)
|
else
|
||||||
else
|
raise 'InvalidCoverageReportType'
|
||||||
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
|
end
|
||||||
|
|
||||||
|
def self.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 self.jest(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
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def read_json(path)
|
||||||
|
JSON.parse(File.read(path))
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@ -1,10 +1,11 @@
|
|||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
class GithubCheckRunService
|
class GithubCheckRunService
|
||||||
def initialize(report, github_data, report_name, report_adapter)
|
CHECK_NAME = 'Coverage'
|
||||||
|
|
||||||
|
def initialize(report, github_data, report_adapter)
|
||||||
@report = report
|
@report = report
|
||||||
@github_data = github_data
|
@github_data = github_data
|
||||||
@report_name = report_name
|
|
||||||
@report_adapter = report_adapter
|
@report_adapter = report_adapter
|
||||||
@client = GithubClient.new(@github_data[:token], user_agent: 'coverage-action')
|
@client = GithubClient.new(@github_data[:token], user_agent: 'coverage-action')
|
||||||
end
|
end
|
||||||
@ -17,7 +18,6 @@ class GithubCheckRunService
|
|||||||
@summary = @report_adapter.summary(@report)
|
@summary = @report_adapter.summary(@report)
|
||||||
@annotations = @report_adapter.annotations(@report)
|
@annotations = @report_adapter.annotations(@report)
|
||||||
@conclusion = @report_adapter.conslusion(@report)
|
@conclusion = @report_adapter.conslusion(@report)
|
||||||
@percent = @report_adapter.lines_covered_percent(@report)
|
|
||||||
|
|
||||||
@client.patch(
|
@client.patch(
|
||||||
"#{endpoint_url}/#{id}",
|
"#{endpoint_url}/#{id}",
|
||||||
@ -33,7 +33,7 @@ class GithubCheckRunService
|
|||||||
|
|
||||||
def create_check_payload
|
def create_check_payload
|
||||||
{
|
{
|
||||||
name: @report_name,
|
name: CHECK_NAME,
|
||||||
head_sha: @github_data[:sha],
|
head_sha: @github_data[:sha],
|
||||||
status: 'in_progress',
|
status: 'in_progress',
|
||||||
started_at: Time.now.iso8601
|
started_at: Time.now.iso8601
|
||||||
@ -42,13 +42,13 @@ class GithubCheckRunService
|
|||||||
|
|
||||||
def update_check_payload
|
def update_check_payload
|
||||||
{
|
{
|
||||||
name: @report_name,
|
name: CHECK_NAME,
|
||||||
head_sha: @github_data[:sha],
|
head_sha: @github_data[:sha],
|
||||||
status: 'completed',
|
status: 'completed',
|
||||||
completed_at: Time.now.iso8601,
|
completed_at: Time.now.iso8601,
|
||||||
conclusion: @conclusion,
|
conclusion: @conclusion,
|
||||||
output: {
|
output: {
|
||||||
title: "#{@report_name} #{@percent}%",
|
title: CHECK_NAME,
|
||||||
summary: @summary,
|
summary: @summary,
|
||||||
annotations: @annotations
|
annotations: @annotations
|
||||||
}
|
}
|
||||||
|
|||||||
@ -17,14 +17,13 @@ end
|
|||||||
sha: ENV['GITHUB_SHA'],
|
sha: ENV['GITHUB_SHA'],
|
||||||
token: ENV['INPUT_TOKEN'],
|
token: ENV['INPUT_TOKEN'],
|
||||||
owner: ENV['GITHUB_REPOSITORY_OWNER'] || @event_json.dig('repository', 'owner', 'login'),
|
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')
|
||||||
}
|
}
|
||||||
|
|
||||||
@coverage_type = ENV['INPUT_TYPE']
|
@coverage_type = ENV['INPUT_TYPE']
|
||||||
@report_path = ENV['INPUT_RESULT_PATH']
|
@report_path = ENV['INPUT_RESULT_PATH']
|
||||||
@report_name = ENV['INPUT_REPORT_NAME']
|
|
||||||
@data = { min: ENV['INPUT_MIN_COVERAGE'] }
|
@data = { min: ENV['INPUT_MIN_COVERAGE'] }
|
||||||
|
|
||||||
@report = CoverageReport.generate(@coverage_type, @report_path, @data)
|
@report = CoverageReport.generate(@coverage_type, @report_path, @data)
|
||||||
|
|
||||||
GithubCheckRunService.new(@report, @github_data, @report_name, ReportAdapter).run
|
GithubCheckRunService.new(@report, @github_data, ReportAdapter).run
|
||||||
|
|||||||
@ -18,16 +18,16 @@ class ReportAdapter
|
|||||||
[]
|
[]
|
||||||
end
|
end
|
||||||
|
|
||||||
def lines_covered_percent(report)
|
|
||||||
@lines_covered_percent ||= report.dig('lines', 'covered_percent')
|
|
||||||
end
|
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def table_head
|
def table_head
|
||||||
"| Type | covered | minimum |\n| ----- | ------- | ------- |"
|
"| Type | covered | minimum |\n| ----- | ------- | ------- |"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def lines_covered_percent(report)
|
||||||
|
@lines_covered_percent ||= report.dig('lines', 'covered_percent')
|
||||||
|
end
|
||||||
|
|
||||||
def lines_minimum_percent(report)
|
def lines_minimum_percent(report)
|
||||||
@lines_minimum_percent ||= report.dig('lines', 'minumum_percent')
|
@lines_minimum_percent ||= report.dig('lines', 'minumum_percent')
|
||||||
end
|
end
|
||||||
|
|||||||
@ -1,15 +0,0 @@
|
|||||||
# 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
193
spec/fixtures/example.lcov
vendored
@ -1,193 +0,0 @@
|
|||||||
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
|
|
||||||
170
spec/fixtures/report.json
vendored
Normal file
170
spec/fixtures/report.json
vendored
Normal file
@ -0,0 +1,170 @@
|
|||||||
|
{
|
||||||
|
"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
5
spec/fixtures/simplecov.json
vendored
@ -1,5 +0,0 @@
|
|||||||
{
|
|
||||||
"result": {
|
|
||||||
"covered_percent": 80.5
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -7,8 +7,7 @@ describe GithubCheckRunService do
|
|||||||
{ 'lines' => { 'covered_percent' => 80, 'minumum_percent' => 80 } }
|
{ 'lines' => { 'covered_percent' => 80, 'minumum_percent' => 80 } }
|
||||||
end
|
end
|
||||||
let(:github_data) { { sha: 'sha', token: 'token', owner: 'owner', repo: 'repository_name' } }
|
let(:github_data) { { sha: 'sha', token: 'token', owner: 'owner', repo: 'repository_name' } }
|
||||||
let(:report_name) { 'Coverage' }
|
let(:service) { GithubCheckRunService.new(report, github_data, ReportAdapter) }
|
||||||
let(:service) { GithubCheckRunService.new(report, github_data, report_name, ReportAdapter) }
|
|
||||||
|
|
||||||
it '#run' do
|
it '#run' do
|
||||||
stub_request(:any, 'https://api.github.com/repos/owner/repository_name/check-runs/id')
|
stub_request(:any, 'https://api.github.com/repos/owner/repository_name/check-runs/id')
|
||||||
|
|||||||
@ -6,4 +6,3 @@ require 'pry'
|
|||||||
require './lib/report_adapter'
|
require './lib/report_adapter'
|
||||||
require './lib/github_check_run_service'
|
require './lib/github_check_run_service'
|
||||||
require './lib/github_client'
|
require './lib/github_client'
|
||||||
require './lib/coverage_report'
|
|
||||||
|
|||||||
Reference in New Issue
Block a user