simplecov-buildkite 0.1.1 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +15 -1
- data/README.md +6 -2
- data/lib/simplecov/buildkite.rb +1 -0
- data/lib/simplecov/buildkite/annotation_formatter.rb +100 -13
- data/lib/simplecov/buildkite/profiles.rb +115 -0
- data/lib/simplecov/buildkite/version.rb +1 -1
- metadata +7 -27
- checksums.yaml.gz.sig +0 -2
- data.tar.gz.sig +0 -0
- metadata.gz.sig +0 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0dba2010d4af1552e27b2d57a1a205fdfef160adf7a279d8d3a68cbd5437ae1c
|
4
|
+
data.tar.gz: 24ec9a1c4157638a21f4cf51635223d21ee9ad62381f16e76e829c68062e6b40
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7b2ffb9737e3f51d1432e82a1e3145a55f904e64e3f1ce317d83b249d8de74d9e5ad50bb10e1c7a7ceedfb8be37eb9b643ac3c52537540660b74d2011eee9997
|
7
|
+
data.tar.gz: 0f5f5908680fad034e77c3c14554cfc4f5ee3a4309f30c8bcb1afe1ddfcfc387c7def2ab7d41abdff429a0244a2d0d6d9786224cc8ae3e1e1e6888765d64cfdd
|
data/CHANGELOG.md
CHANGED
@@ -4,6 +4,19 @@ All notable changes to this project will be documented in this file.
|
|
4
4
|
The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
|
5
5
|
and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
|
6
6
|
|
7
|
+
## [Unreleased]
|
8
|
+
- Nothing yet!
|
9
|
+
|
10
|
+
## [0.2.0] - 2020-09-08
|
11
|
+
- git integration: SimpleCov groups are automatically generated based on branch
|
12
|
+
and commit metadata.
|
13
|
+
([#2](https://github.com/ticky/simplecov-buildkite/pull/2),
|
14
|
+
[#8](https://github.com/ticky/simplecov-buildkite/pull/8))
|
15
|
+
- Headers are now in sentence case
|
16
|
+
([#9](https://github.com/ticky/simplecov-buildkite/pull/9))
|
17
|
+
- Update specs for SimpleCov 0.19.0
|
18
|
+
([#12](https://github.com/ticky/simplecov-buildkite/pull/12))
|
19
|
+
|
7
20
|
## [0.1.1] - 2018-05-30
|
8
21
|
### Changed
|
9
22
|
- Output is now enclosed in a `<details>` for a brief summary with expandable
|
@@ -15,7 +28,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
|
|
15
28
|
- Buildkite annotation formatter to consolidate reports from multiple simplecov
|
16
29
|
runs into a Buildkite annotation.
|
17
30
|
|
18
|
-
[Unreleased]: https://github.com/ticky/simplecov-buildkite/compare/v0.
|
31
|
+
[Unreleased]: https://github.com/ticky/simplecov-buildkite/compare/v0.2.0...HEAD
|
32
|
+
[0.2.0]: https://github.com/ticky/simplecov-buildkite/compare/v0.2.0...v0.1.1
|
19
33
|
[0.1.1]: https://github.com/ticky/simplecov-buildkite/compare/v0.1.0...v0.1.1
|
20
34
|
[0.1.0]: https://github.com/ticky/simplecov-buildkite/commits/v0.1.0
|
21
35
|
|
data/README.md
CHANGED
@@ -1,5 +1,7 @@
|
|
1
1
|
# SimpleCov::Buildkite
|
2
2
|
|
3
|
+
[](https://rubygems.org/gems/simplecov-buildkite) [](https://travis-ci.org/ticky/simplecov-buildkite)
|
4
|
+
|
3
5
|
Generate [Buildkite annotations] from your [SimpleCov] coverage reports when running your build on [Buildkite].
|
4
6
|
|
5
7
|
[Buildkite]: https://buildkite.com
|
@@ -34,6 +36,8 @@ require "simplecov"
|
|
34
36
|
require "simplecov-buildkite"
|
35
37
|
|
36
38
|
SimpleCov.start "rails" do
|
39
|
+
load_profile "buildkite"
|
40
|
+
|
37
41
|
formatter SimpleCov::Formatter::MultiFormatter.new([
|
38
42
|
SimpleCov::Formatter::HTMLFormatter,
|
39
43
|
SimpleCov::Buildkite::AnnotationFormatter,
|
@@ -41,9 +45,9 @@ SimpleCov.start "rails" do
|
|
41
45
|
end
|
42
46
|
```
|
43
47
|
|
44
|
-
When run on Buildkite, this will also output a pretty Buildkite annotation:
|
48
|
+
When run on Buildkite with the `"buildkite"` profile enabled, this will also output a pretty Buildkite annotation, with coverage change breakdowns for the current PR or branch and commit:
|
45
49
|
|
46
|
-
<img width="
|
50
|
+
<img width="577" alt="Buildkite build showing a SimpleCov report in a Buildkite annotation" src="https://user-images.githubusercontent.com/282113/42116587-c2e9731e-7bac-11e8-9d2f-50fa7f071f09.png">
|
47
51
|
|
48
52
|
[Rails]: https://rubyonrails.org
|
49
53
|
[RSpec]: http://rspec.info
|
data/lib/simplecov/buildkite.rb
CHANGED
@@ -1,19 +1,63 @@
|
|
1
1
|
module SimpleCov::Buildkite
|
2
2
|
class AnnotationFormatter
|
3
|
+
GIT_ANNOTATION_FORMAT_REGEX = /^Files (?<action>changed|added) in (?<changeset>[a-zA-Z0-9.]+)$/
|
4
|
+
|
3
5
|
def format(result)
|
6
|
+
git_results, general_results = filter_git_groups(ignore_empty_groups(result.groups))
|
7
|
+
.values_at(:git, :general)
|
8
|
+
|
4
9
|
message = <<~MESSAGE
|
5
|
-
|
6
|
-
|
7
|
-
<
|
8
|
-
#{result.groups.map do |name, group|
|
9
|
-
"<li><strong>#{name}</strong>: #{format_element(group)}</li>"
|
10
|
-
end.join("\n")}
|
11
|
-
</ul>
|
12
|
-
</details>
|
10
|
+
#### Coverage
|
11
|
+
|
12
|
+
<dl class="flex flex-wrap m1 mxn2">
|
13
13
|
MESSAGE
|
14
14
|
|
15
|
-
|
16
|
-
|
15
|
+
git_results.to_a.reverse.each do |git_result|
|
16
|
+
name, group = git_result
|
17
|
+
|
18
|
+
matches = name.match GIT_ANNOTATION_FORMAT_REGEX
|
19
|
+
|
20
|
+
type = if matches[:action] == 'added'
|
21
|
+
'New files'
|
22
|
+
else
|
23
|
+
'Files changed'
|
24
|
+
end
|
25
|
+
|
26
|
+
changeset = if matches[:changeset].include?('...')
|
27
|
+
'branch'
|
28
|
+
else
|
29
|
+
'commit'
|
30
|
+
end
|
31
|
+
|
32
|
+
message += format_as_metric "#{type} in #{changeset}",
|
33
|
+
group,
|
34
|
+
changeset: matches[:changeset]
|
35
|
+
end
|
36
|
+
|
37
|
+
message += format_as_metric 'All files', result
|
38
|
+
|
39
|
+
message += <<~MESSAGE
|
40
|
+
</dl>
|
41
|
+
MESSAGE
|
42
|
+
|
43
|
+
if general_results.any?
|
44
|
+
message += <<~MESSAGE
|
45
|
+
<details><summary>Coverage breakdown</summary>
|
46
|
+
|
47
|
+
#{general_results.map do |name, group|
|
48
|
+
"- **#{name}**: #{format_group(group)}"
|
49
|
+
end.join("\n")}
|
50
|
+
|
51
|
+
</details>
|
52
|
+
MESSAGE
|
53
|
+
end
|
54
|
+
|
55
|
+
if ENV['BUILDKITE']
|
56
|
+
system 'buildkite-agent',
|
57
|
+
'annotate',
|
58
|
+
'--context', 'simplecov',
|
59
|
+
'--style', 'info',
|
60
|
+
message
|
17
61
|
else
|
18
62
|
puts message
|
19
63
|
end
|
@@ -21,12 +65,55 @@ module SimpleCov::Buildkite
|
|
21
65
|
|
22
66
|
private
|
23
67
|
|
24
|
-
def
|
25
|
-
|
68
|
+
def ignore_empty_groups(groups)
|
69
|
+
groups.select do |_name, group|
|
70
|
+
(group.covered_lines + group.missed_lines).positive?
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
def filter_git_groups(groups)
|
75
|
+
groups.each_with_object(git: {}, general: {}) do |unzipped_group, cats|
|
76
|
+
name, group = unzipped_group
|
77
|
+
|
78
|
+
if name.match? GIT_ANNOTATION_FORMAT_REGEX
|
79
|
+
cats[:git][name] = group
|
80
|
+
else
|
81
|
+
cats[:general][name] = group
|
82
|
+
end
|
83
|
+
end
|
26
84
|
end
|
27
85
|
|
28
86
|
def format_integer(integer)
|
29
|
-
integer.
|
87
|
+
Kernel.format('%<integer>d', integer: integer).gsub(/(\d)(?=(\d\d\d)+(?!\d))/, "\\1,")
|
88
|
+
end
|
89
|
+
|
90
|
+
def format_float(float)
|
91
|
+
Kernel.format('%<floored_float>g', floored_float: float.floor(2))
|
92
|
+
end
|
93
|
+
|
94
|
+
def format_as_metric(name, element, changeset: nil)
|
95
|
+
metric = <<~METRIC_HEADER
|
96
|
+
<div class="m2"><dt#{changeset.nil? ? '' : " title=\"#{changeset}\""}>#{name}</dt><dd>
|
97
|
+
METRIC_HEADER
|
98
|
+
|
99
|
+
metric += <<~METRIC_VALUE
|
100
|
+
|
101
|
+
**<span class="h2 regular">#{format_float(element.covered_percent)}</span>%**
|
102
|
+
#{format_line_count(element)}
|
103
|
+
|
104
|
+
METRIC_VALUE
|
105
|
+
|
106
|
+
metric += <<~METRIC_FOOTER
|
107
|
+
</dd></div>
|
108
|
+
METRIC_FOOTER
|
109
|
+
end
|
110
|
+
|
111
|
+
def format_group(element)
|
112
|
+
"#{format_float(element.covered_percent)}% coverage: #{format_line_count(element)}"
|
113
|
+
end
|
114
|
+
|
115
|
+
def format_line_count(element)
|
116
|
+
"#{format_integer(element.covered_lines)} of #{format_integer(element.covered_lines + element.missed_lines)} lines"
|
30
117
|
end
|
31
118
|
end
|
32
119
|
end
|
@@ -0,0 +1,115 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module SimpleCov::Buildkite::Profiles
|
4
|
+
def self.run(*args)
|
5
|
+
IO.popen(args, &:read).tap do
|
6
|
+
$?.success? or fail("Command exited with status #{$?.exitstatus}: #{args.join(" ")}")
|
7
|
+
end.chomp
|
8
|
+
end
|
9
|
+
|
10
|
+
def self.git(*args)
|
11
|
+
run 'git',
|
12
|
+
*args
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.git_diff_names(*args, diff_filter: '')
|
16
|
+
git('diff',
|
17
|
+
'--name-only',
|
18
|
+
"--diff-filter=#{diff_filter}",
|
19
|
+
*args).split "\n"
|
20
|
+
end
|
21
|
+
|
22
|
+
def self.git_short_commit(commit)
|
23
|
+
git 'rev-parse',
|
24
|
+
'--short',
|
25
|
+
commit
|
26
|
+
end
|
27
|
+
|
28
|
+
def self.git_merge_base(*refs)
|
29
|
+
git 'merge-base',
|
30
|
+
*refs
|
31
|
+
end
|
32
|
+
|
33
|
+
SimpleCov.profiles.define 'buildkite' do
|
34
|
+
STDERR.puts 'SimpleCov::Buildkite profile initialising...'
|
35
|
+
fail('Not running on Buildkite') unless ENV['BUILDKITE'] == 'true'
|
36
|
+
|
37
|
+
branch_name = ENV['BUILDKITE_BRANCH']
|
38
|
+
|
39
|
+
STDERR.puts "branch_name=#{branch_name}"
|
40
|
+
|
41
|
+
base_branch_name = ENV['BUILDKITE_PULL_REQUEST_BASE_BRANCH']
|
42
|
+
if base_branch_name.nil? || base_branch_name.empty?
|
43
|
+
base_branch_name = ENV['BUILDKITE_PIPELINE_DEFAULT_BRANCH']
|
44
|
+
end
|
45
|
+
|
46
|
+
STDERR.puts "base_branch_name=#{base_branch_name}"
|
47
|
+
|
48
|
+
current_commit = ENV['BUILDKITE_COMMIT']
|
49
|
+
|
50
|
+
STDERR.puts "current_commit=#{current_commit}"
|
51
|
+
|
52
|
+
current_commit_short = git_short_commit(current_commit)
|
53
|
+
|
54
|
+
STDERR.puts "current_commit_short=#{current_commit_short}"
|
55
|
+
|
56
|
+
changed_files_in_commit = git_diff_names(current_commit,
|
57
|
+
diff_filter: 'd')
|
58
|
+
|
59
|
+
STDERR.puts "changed_files_in_commit.count=#{changed_files_in_commit.count}"
|
60
|
+
|
61
|
+
add_group "Files changed in #{current_commit_short}" do |tested_file|
|
62
|
+
changed_files_in_commit.detect do |changed_file|
|
63
|
+
tested_file.filename.end_with?(changed_file)
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
added_files_in_commit = git_diff_names(current_commit,
|
68
|
+
diff_filter: 'A')
|
69
|
+
|
70
|
+
STDERR.puts "added_files_in_commit.count=#{added_files_in_commit.count}"
|
71
|
+
|
72
|
+
add_group "Files added in #{current_commit_short}" do |tested_file|
|
73
|
+
added_files_in_commit.detect do |added_file|
|
74
|
+
tested_file.filename.end_with?(added_file)
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
# Compare with the base branch if it's not this branch
|
79
|
+
if base_branch_name && base_branch_name != branch_name
|
80
|
+
merge_base = git_merge_base(current_commit,
|
81
|
+
base_branch_name)
|
82
|
+
|
83
|
+
merge_base_short = git_short_commit(merge_base)
|
84
|
+
|
85
|
+
STDERR.puts "merge_base=#{merge_base}"
|
86
|
+
STDERR.puts "merge_base_short=#{merge_base_short}"
|
87
|
+
|
88
|
+
changed_files_in_branch = git_diff_names(merge_base,
|
89
|
+
current_commit,
|
90
|
+
diff_filter: 'd')
|
91
|
+
|
92
|
+
STDERR.puts "changed_files_in_branch.count=#{changed_files_in_branch.count}"
|
93
|
+
|
94
|
+
add_group "Files changed in #{merge_base_short}...#{current_commit_short}" do |tested_file|
|
95
|
+
changed_files_in_branch.detect do |changed_file|
|
96
|
+
tested_file.filename.end_with?(changed_file)
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
added_files_in_branch = git_diff_names(merge_base,
|
101
|
+
current_commit,
|
102
|
+
diff_filter: 'A')
|
103
|
+
|
104
|
+
STDERR.puts "added_files_in_branch.count=#{added_files_in_branch.count}"
|
105
|
+
|
106
|
+
add_group "Files added in #{merge_base_short}...#{current_commit_short}" do |tested_file|
|
107
|
+
added_files_in_branch.detect do |added_file|
|
108
|
+
tested_file.filename.end_with?(added_file)
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
112
|
+
rescue RuntimeError => error
|
113
|
+
STDERR.puts error
|
114
|
+
end
|
115
|
+
end
|
metadata
CHANGED
@@ -1,35 +1,15 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: simplecov-buildkite
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jessica Stokes
|
8
8
|
- Samuel Cochran
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
|
-
cert_chain:
|
12
|
-
-
|
13
|
-
-----BEGIN CERTIFICATE-----
|
14
|
-
MIIDKDCCAhCgAwIBAgIBBTANBgkqhkiG9w0BAQUFADA6MQ0wCwYDVQQDDARzajI2
|
15
|
-
MRQwEgYKCZImiZPyLGQBGRYEc2oyNjETMBEGCgmSJomT8ixkARkWA2NvbTAeFw0x
|
16
|
-
NzA3MzEwNTQ3MDVaFw0xODA3MzEwNTQ3MDVaMDoxDTALBgNVBAMMBHNqMjYxFDAS
|
17
|
-
BgoJkiaJk/IsZAEZFgRzajI2MRMwEQYKCZImiZPyLGQBGRYDY29tMIIBIjANBgkq
|
18
|
-
hkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsr60Eo/ttCk8GMTMFiPr3GoYMIMFvLak
|
19
|
-
xSmTk9YGCB6UiEePB4THSSA5w6IPyeaCF/nWkDp3/BAam0eZMWG1IzYQB23TqIM0
|
20
|
-
1xzcNRvFsn0aQoQ00k+sj+G83j3T5OOV5OZIlu8xAChMkQmiPd1NXc6uFv+Iacz7
|
21
|
-
kj+CMsI9YUFdNoU09QY0b+u+Rb6wDYdpyvN60YC30h0h1MeYbvYZJx/iZK4XY5zu
|
22
|
-
4O/FL2ChjL2CPCpLZW55ShYyrzphWJwLOJe+FJ/ZBl6YXwrzQM9HKnt4titSNvyU
|
23
|
-
KzE3L63A3PZvExzLrN9u09kuWLLJfXB2sGOlw3n9t72rJiuBr3/OQQIDAQABozkw
|
24
|
-
NzAJBgNVHRMEAjAAMAsGA1UdDwQEAwIEsDAdBgNVHQ4EFgQU99dfRjEKFyczTeIz
|
25
|
-
m3ZsDWrNC80wDQYJKoZIhvcNAQEFBQADggEBADGiXpvK754s0zTFx3y31ZRDdvAI
|
26
|
-
lA209JIjUlDyr9ptCRadihyfF2l9/hb+hLemiPEYppzG6vEK1TIyzbAR36yOJ8CX
|
27
|
-
4vPkCXLuwHhs6UIRbwN+IEy41nsIlBxmjLYei8h3t/G2Vm2oOaLdbjDXS+Srl9U8
|
28
|
-
shsE8ft81PxSQfzEL7Mr9cC9XvWbHW+SyTpfGm8rAtaqZkNeke4U8a0di4oz2EfA
|
29
|
-
P4lSfmXxsd1C71ckIp0cyXkPhyTtpyS/5hq9HhuUNzEHkSDe36/Rd1xYKV5JxMC2
|
30
|
-
YAttWFUs06lor2q1wwncPaMtUtbWwW35+1IV6xhs2rFY6DD/I6ZkK3GnHdY=
|
31
|
-
-----END CERTIFICATE-----
|
32
|
-
date: 2018-05-30 00:00:00.000000000 Z
|
11
|
+
cert_chain: []
|
12
|
+
date: 2020-09-08 00:00:00.000000000 Z
|
33
13
|
dependencies:
|
34
14
|
- !ruby/object:Gem::Dependency
|
35
15
|
name: simplecov
|
@@ -65,14 +45,14 @@ dependencies:
|
|
65
45
|
requirements:
|
66
46
|
- - "~>"
|
67
47
|
- !ruby/object:Gem::Version
|
68
|
-
version: '
|
48
|
+
version: '13.0'
|
69
49
|
type: :development
|
70
50
|
prerelease: false
|
71
51
|
version_requirements: !ruby/object:Gem::Requirement
|
72
52
|
requirements:
|
73
53
|
- - "~>"
|
74
54
|
- !ruby/object:Gem::Version
|
75
|
-
version: '
|
55
|
+
version: '13.0'
|
76
56
|
- !ruby/object:Gem::Dependency
|
77
57
|
name: rspec
|
78
58
|
requirement: !ruby/object:Gem::Requirement
|
@@ -102,6 +82,7 @@ files:
|
|
102
82
|
- lib/simplecov-buildkite.rb
|
103
83
|
- lib/simplecov/buildkite.rb
|
104
84
|
- lib/simplecov/buildkite/annotation_formatter.rb
|
85
|
+
- lib/simplecov/buildkite/profiles.rb
|
105
86
|
- lib/simplecov/buildkite/version.rb
|
106
87
|
homepage: https://github.com/ticky/simplecov-buildkite
|
107
88
|
licenses:
|
@@ -123,8 +104,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
123
104
|
- !ruby/object:Gem::Version
|
124
105
|
version: '0'
|
125
106
|
requirements: []
|
126
|
-
|
127
|
-
rubygems_version: 2.7.7
|
107
|
+
rubygems_version: 3.0.3
|
128
108
|
signing_key:
|
129
109
|
specification_version: 4
|
130
110
|
summary: Generate SimpleCov reports for your parallel Buildkite builds
|
checksums.yaml.gz.sig
DELETED
data.tar.gz.sig
DELETED
Binary file
|
metadata.gz.sig
DELETED