rspec-mergify 0.0.1
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 +7 -0
- data/LICENSE +674 -0
- data/README.md +66 -0
- data/lib/mergify/rspec/ci_insights.rb +174 -0
- data/lib/mergify/rspec/configuration.rb +82 -0
- data/lib/mergify/rspec/flaky_detection.rb +252 -0
- data/lib/mergify/rspec/formatter.rb +210 -0
- data/lib/mergify/rspec/quarantine.rb +90 -0
- data/lib/mergify/rspec/resources/ci.rb +24 -0
- data/lib/mergify/rspec/resources/git.rb +35 -0
- data/lib/mergify/rspec/resources/github_actions.rb +60 -0
- data/lib/mergify/rspec/resources/jenkins.rb +55 -0
- data/lib/mergify/rspec/resources/mergify.rb +24 -0
- data/lib/mergify/rspec/resources/rspec.rb +22 -0
- data/lib/mergify/rspec/synchronous_batch_span_processor.rb +34 -0
- data/lib/mergify/rspec/utils.rb +140 -0
- data/lib/mergify/rspec/version.rb +9 -0
- data/lib/mergify/rspec.rb +11 -0
- data/lib/rspec_mergify.rb +12 -0
- metadata +104 -0
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'open3'
|
|
4
|
+
|
|
5
|
+
module Mergify
|
|
6
|
+
module RSpec
|
|
7
|
+
# Utility methods shared across the rspec-mergify gem.
|
|
8
|
+
module Utils
|
|
9
|
+
module_function
|
|
10
|
+
|
|
11
|
+
# Raised when a repository full name (owner/repo) is malformed.
|
|
12
|
+
class InvalidRepositoryFullNameError < StandardError; end
|
|
13
|
+
|
|
14
|
+
SUPPORTED_CIS = {
|
|
15
|
+
'GITHUB_ACTIONS' => :github_actions,
|
|
16
|
+
'CIRCLECI' => :circleci,
|
|
17
|
+
'JENKINS_URL' => :jenkins,
|
|
18
|
+
'_RSPEC_MERGIFY_TEST' => :rspec_mergify_suite
|
|
19
|
+
}.freeze
|
|
20
|
+
|
|
21
|
+
TRUTHY_STRINGS = %w[y yes t true on 1].freeze
|
|
22
|
+
FALSY_STRINGS = %w[n no f false off 0].freeze
|
|
23
|
+
|
|
24
|
+
# Convert a string to a boolean.
|
|
25
|
+
# Truthy: y yes t true on 1
|
|
26
|
+
# Falsy: n no f false off 0
|
|
27
|
+
# Raises ArgumentError for anything else.
|
|
28
|
+
def strtobool(string)
|
|
29
|
+
return true if TRUTHY_STRINGS.include?(string.downcase)
|
|
30
|
+
return false if FALSY_STRINGS.include?(string.downcase)
|
|
31
|
+
|
|
32
|
+
raise ArgumentError, "Could not convert '#{string}' to boolean"
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
# Returns true when the named environment variable holds a truthy value.
|
|
36
|
+
def env_truthy?(key)
|
|
37
|
+
TRUTHY_STRINGS.include?(ENV.fetch(key, '').downcase)
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
# Returns true when the suite is running inside CI or when
|
|
41
|
+
# RSPEC_MERGIFY_ENABLE is set to a truthy value.
|
|
42
|
+
def in_ci?
|
|
43
|
+
env_truthy?('CI') || env_truthy?('RSPEC_MERGIFY_ENABLE')
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
# Evaluates whether a CI environment variable should be considered enabled.
|
|
47
|
+
# rubocop:disable Metrics/MethodLength
|
|
48
|
+
def ci_provider
|
|
49
|
+
SUPPORTED_CIS.each do |envvar, name|
|
|
50
|
+
next unless ENV.key?(envvar)
|
|
51
|
+
|
|
52
|
+
enabled =
|
|
53
|
+
begin
|
|
54
|
+
strtobool(ENV.fetch(envvar, ''))
|
|
55
|
+
rescue ArgumentError
|
|
56
|
+
!ENV.fetch(envvar, '').strip.empty?
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
return name if enabled
|
|
60
|
+
end
|
|
61
|
+
nil
|
|
62
|
+
end
|
|
63
|
+
# rubocop:enable Metrics/MethodLength
|
|
64
|
+
|
|
65
|
+
# Parse a git remote URL (SSH or HTTPS) into "owner/repo" form.
|
|
66
|
+
# Returns nil when the URL cannot be recognised.
|
|
67
|
+
def repository_name_from_url(url)
|
|
68
|
+
# SSH: git@github.com:owner/repo.git
|
|
69
|
+
if (m = url.match(%r{\Agit@[\w.-]+:(?<full_name>[\w.-]+/[\w.-]+?)(?:\.git)?/?$}))
|
|
70
|
+
return m[:full_name]
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
# HTTPS/HTTP with optional host (and optional port)
|
|
74
|
+
if (m = url.match(%r{\A(?:https?://[\w.-]+(?::\d+)?/)?(?<full_name>[\w.-]+/[\w.-]+)/?\z}))
|
|
75
|
+
return m[:full_name]
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
nil
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
# Split "owner/repo" into [owner, repo].
|
|
82
|
+
# Raises InvalidRepositoryFullNameError when the format is wrong.
|
|
83
|
+
def split_full_repo_name(full_repo_name)
|
|
84
|
+
parts = full_repo_name.split('/')
|
|
85
|
+
return parts if parts.size == 2
|
|
86
|
+
|
|
87
|
+
raise InvalidRepositoryFullNameError, "Invalid repository name: #{full_repo_name}"
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
# Run a git subcommand via Open3.
|
|
91
|
+
# Returns stripped stdout on success, nil on failure.
|
|
92
|
+
def git(*args)
|
|
93
|
+
stdout, status = Open3.capture2('git', *args, err: File::NULL)
|
|
94
|
+
status.success? ? stdout.strip : nil
|
|
95
|
+
rescue StandardError
|
|
96
|
+
nil
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
# Build an attribute hash from a mapping of
|
|
100
|
+
# { attr_name => [cast_method_symbol, env_var_name_or_callable] }.
|
|
101
|
+
# Attributes whose env var is unset or whose callable returns nil are omitted.
|
|
102
|
+
def get_attributes(mapping)
|
|
103
|
+
mapping.each_with_object({}) do |(attr, (cast, env_or_callable)), result|
|
|
104
|
+
value =
|
|
105
|
+
if env_or_callable.respond_to?(:call)
|
|
106
|
+
env_or_callable.call
|
|
107
|
+
else
|
|
108
|
+
ENV.fetch(env_or_callable, nil)
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
result[attr] = value.public_send(cast) unless value.nil?
|
|
112
|
+
end
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
# Detect the repository name using CI environment variables or a git
|
|
116
|
+
# remote fallback.
|
|
117
|
+
# rubocop:disable Metrics/MethodLength,Metrics/CyclomaticComplexity
|
|
118
|
+
def repository_name
|
|
119
|
+
provider = ci_provider
|
|
120
|
+
|
|
121
|
+
case provider
|
|
122
|
+
when :jenkins
|
|
123
|
+
url = ENV.fetch('GIT_URL', nil)
|
|
124
|
+
return repository_name_from_url(url) if url
|
|
125
|
+
when :github_actions
|
|
126
|
+
return ENV.fetch('GITHUB_REPOSITORY', nil)
|
|
127
|
+
when :circleci
|
|
128
|
+
url = ENV.fetch('CIRCLE_REPOSITORY_URL', nil)
|
|
129
|
+
return repository_name_from_url(url) if url
|
|
130
|
+
when :rspec_mergify_suite
|
|
131
|
+
return 'Mergifyio/rspec-mergify'
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
url = git('config', '--get', 'remote.origin.url')
|
|
135
|
+
repository_name_from_url(url) if url
|
|
136
|
+
end
|
|
137
|
+
# rubocop:enable Metrics/MethodLength,Metrics/CyclomaticComplexity
|
|
138
|
+
end
|
|
139
|
+
end
|
|
140
|
+
end
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative 'mergify/rspec'
|
|
4
|
+
require_relative 'mergify/rspec/ci_insights'
|
|
5
|
+
require_relative 'mergify/rspec/formatter'
|
|
6
|
+
require_relative 'mergify/rspec/configuration'
|
|
7
|
+
|
|
8
|
+
# Initialize singleton (only does real work when in CI)
|
|
9
|
+
Mergify::RSpec.ci_insights = Mergify::RSpec::CIInsights.new
|
|
10
|
+
|
|
11
|
+
# Register hooks and formatter
|
|
12
|
+
Mergify::RSpec::Configuration.setup!
|
metadata
ADDED
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: rspec-mergify
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 0.0.1
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- Mergify
|
|
8
|
+
bindir: bin
|
|
9
|
+
cert_chain: []
|
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
|
11
|
+
dependencies:
|
|
12
|
+
- !ruby/object:Gem::Dependency
|
|
13
|
+
name: opentelemetry-exporter-otlp
|
|
14
|
+
requirement: !ruby/object:Gem::Requirement
|
|
15
|
+
requirements:
|
|
16
|
+
- - "~>"
|
|
17
|
+
- !ruby/object:Gem::Version
|
|
18
|
+
version: '0.29'
|
|
19
|
+
type: :runtime
|
|
20
|
+
prerelease: false
|
|
21
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
22
|
+
requirements:
|
|
23
|
+
- - "~>"
|
|
24
|
+
- !ruby/object:Gem::Version
|
|
25
|
+
version: '0.29'
|
|
26
|
+
- !ruby/object:Gem::Dependency
|
|
27
|
+
name: opentelemetry-sdk
|
|
28
|
+
requirement: !ruby/object:Gem::Requirement
|
|
29
|
+
requirements:
|
|
30
|
+
- - "~>"
|
|
31
|
+
- !ruby/object:Gem::Version
|
|
32
|
+
version: '1.4'
|
|
33
|
+
type: :runtime
|
|
34
|
+
prerelease: false
|
|
35
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
36
|
+
requirements:
|
|
37
|
+
- - "~>"
|
|
38
|
+
- !ruby/object:Gem::Version
|
|
39
|
+
version: '1.4'
|
|
40
|
+
- !ruby/object:Gem::Dependency
|
|
41
|
+
name: rspec-core
|
|
42
|
+
requirement: !ruby/object:Gem::Requirement
|
|
43
|
+
requirements:
|
|
44
|
+
- - "~>"
|
|
45
|
+
- !ruby/object:Gem::Version
|
|
46
|
+
version: '3.12'
|
|
47
|
+
type: :runtime
|
|
48
|
+
prerelease: false
|
|
49
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
50
|
+
requirements:
|
|
51
|
+
- - "~>"
|
|
52
|
+
- !ruby/object:Gem::Version
|
|
53
|
+
version: '3.12'
|
|
54
|
+
description: 'RSpec integration for Mergify CI Insights: OpenTelemetry tracing, flaky
|
|
55
|
+
test detection, and test quarantine.'
|
|
56
|
+
email:
|
|
57
|
+
- support@mergify.com
|
|
58
|
+
executables: []
|
|
59
|
+
extensions: []
|
|
60
|
+
extra_rdoc_files: []
|
|
61
|
+
files:
|
|
62
|
+
- LICENSE
|
|
63
|
+
- README.md
|
|
64
|
+
- lib/mergify/rspec.rb
|
|
65
|
+
- lib/mergify/rspec/ci_insights.rb
|
|
66
|
+
- lib/mergify/rspec/configuration.rb
|
|
67
|
+
- lib/mergify/rspec/flaky_detection.rb
|
|
68
|
+
- lib/mergify/rspec/formatter.rb
|
|
69
|
+
- lib/mergify/rspec/quarantine.rb
|
|
70
|
+
- lib/mergify/rspec/resources/ci.rb
|
|
71
|
+
- lib/mergify/rspec/resources/git.rb
|
|
72
|
+
- lib/mergify/rspec/resources/github_actions.rb
|
|
73
|
+
- lib/mergify/rspec/resources/jenkins.rb
|
|
74
|
+
- lib/mergify/rspec/resources/mergify.rb
|
|
75
|
+
- lib/mergify/rspec/resources/rspec.rb
|
|
76
|
+
- lib/mergify/rspec/synchronous_batch_span_processor.rb
|
|
77
|
+
- lib/mergify/rspec/utils.rb
|
|
78
|
+
- lib/mergify/rspec/version.rb
|
|
79
|
+
- lib/rspec_mergify.rb
|
|
80
|
+
homepage: https://github.com/Mergifyio/rspec-mergify
|
|
81
|
+
licenses:
|
|
82
|
+
- GPL-3.0-only
|
|
83
|
+
metadata:
|
|
84
|
+
homepage_uri: https://github.com/Mergifyio/rspec-mergify
|
|
85
|
+
source_code_uri: https://github.com/Mergifyio/rspec-mergify
|
|
86
|
+
rubygems_mfa_required: 'true'
|
|
87
|
+
rdoc_options: []
|
|
88
|
+
require_paths:
|
|
89
|
+
- lib
|
|
90
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
91
|
+
requirements:
|
|
92
|
+
- - ">="
|
|
93
|
+
- !ruby/object:Gem::Version
|
|
94
|
+
version: '3.1'
|
|
95
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
96
|
+
requirements:
|
|
97
|
+
- - ">="
|
|
98
|
+
- !ruby/object:Gem::Version
|
|
99
|
+
version: '0'
|
|
100
|
+
requirements: []
|
|
101
|
+
rubygems_version: 3.6.9
|
|
102
|
+
specification_version: 4
|
|
103
|
+
summary: RSpec plugin for Mergify CI Insights
|
|
104
|
+
test_files: []
|