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.
@@ -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,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Mergify
4
+ module RSpec
5
+ VERSION = `git describe --tags --match '*' 2>/dev/null`.then do |v|
6
+ v.empty? ? '0.0.0.dev' : v.tr('-', '.')
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'rspec/version'
4
+
5
+ module Mergify
6
+ module RSpec
7
+ class << self
8
+ attr_accessor :ci_insights
9
+ end
10
+ end
11
+ 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: []