danger-jira_sync 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,299 @@
1
+ # frozen_string_literal: true
2
+
3
+ require File.expand_path("spec_helper", __dir__)
4
+
5
+ # In order to regenerate the fixtures in ./fixtures/vcr_cassettes,
6
+ # you must ensure that your Jira Cloud development environment contains
7
+ # projects matching all of the key prefixes in ISSUE_KEYS_IN_PR_TITLE and
8
+ # ISSUE_KEYS_IN_PR_BODY. Similarly, there must be an issue in each project
9
+ # with a matching key. Look at JIRA_ENVIRONMENT for hints on how to
10
+ # configure the development environment for VCR.
11
+ #
12
+ # On the GitHub side, if ./fixtures/vcr_cassettes/pull_request.yml changes, you
13
+ # must ensure the title in the response contains the keys found in
14
+ # ISSUE_KEYS_IN_PR_TITLE, and that the body contains the strings found in
15
+ # ISSUE_KEYS_IN_PR_BODY. These constants reflect assumptions in the test suite.
16
+ #
17
+ ISSUE_KEYS_IN_PR_TITLE = ["DEV-1", "ABC-1"].freeze
18
+ ISSUE_KEYS_IN_PR_BODY = ["XYZ-1"].freeze
19
+ JIRA_ENVIRONMENT = {
20
+ projects: [
21
+ {
22
+ key: "DEV",
23
+ issues: [
24
+ {
25
+ key: "DEV-1",
26
+ components: %w(ComponentA ComponentB)
27
+ }
28
+ ]
29
+ },
30
+ {
31
+ key: "XYZ",
32
+ issues: [
33
+ {
34
+ key: "XYZ-1",
35
+ components: %w(ComponentC)
36
+ }
37
+ ]
38
+ },
39
+ {
40
+ key: "ABC",
41
+ issues: [
42
+ {
43
+ key: "ABC-1",
44
+ components: %w(ComponentB)
45
+ }
46
+ ]
47
+ }
48
+ ]
49
+ }.freeze
50
+
51
+ RSpec.describe Danger::DangerJiraSync do
52
+ it "should be a plugin" do
53
+ expect(described_class.new(nil)).to be_a Danger::Plugin
54
+ end
55
+
56
+ describe "with Dangerfile" do
57
+ let(:dangerfile) { testing_dangerfile }
58
+ let(:plugin) { dangerfile.jira_sync }
59
+ let(:jira_settings) do
60
+ {
61
+ jira_url: testing_env["DANGER_JIRA_URL"],
62
+ jira_username: testing_env["DANGER_JIRA_USERNAME"],
63
+ jira_api_token: testing_env["DANGER_JIRA_API_TOKEN"]
64
+ }
65
+ end
66
+
67
+ def stub_pull_request
68
+ VCR.use_cassette(:pull_request) do
69
+ plugin.env.request_source.fetch_details
70
+ end
71
+ end
72
+
73
+ before do
74
+ stub_pull_request
75
+ end
76
+
77
+ describe "configure" do
78
+ it "should return the JIRA::Client instance" do
79
+ value = plugin.configure(jira_settings)
80
+ expect(value).to be_a(JIRA::Client)
81
+ end
82
+ end
83
+
84
+ describe "autolabel_pull_request" do
85
+ let(:issue_prefixes) { %w(DEV ABC) }
86
+
87
+ it "raises a NotConfiguredError when #configure has not been called" do
88
+ expect { plugin.autolabel_pull_request(issue_prefixes) }.to(
89
+ raise_error(Danger::DangerJiraSync::NotConfiguredError)
90
+ )
91
+ end
92
+
93
+ context "after calling #configure" do
94
+ class GitHubAPIMock
95
+ end
96
+
97
+ let(:github_api_mock) { GitHubAPIMock.new }
98
+
99
+ before do
100
+ plugin.configure(jira_settings)
101
+ end
102
+
103
+ def stub_github_api_labelling(labels: [])
104
+ allow(github_api_mock).to receive(:labels).and_return(labels)
105
+ allow(github_api_mock).to receive(:add_label).and_return(nil)
106
+ allow(github_api_mock).to receive(:add_labels_to_an_issue).and_return(nil)
107
+
108
+ allow(plugin.github).to receive(:api).and_return(github_api_mock)
109
+ end
110
+
111
+ def extract_project_keys(prefixes)
112
+ return prefixes.map { |key| key.gsub(/-\d+/, "") }
113
+ end
114
+
115
+ def pr_title_project_keys
116
+ extract_project_keys(ISSUE_KEYS_IN_PR_TITLE)
117
+ end
118
+
119
+ def pr_body_project_keys
120
+ extract_project_keys(ISSUE_KEYS_IN_PR_BODY)
121
+ end
122
+
123
+ def pr_title_related_component_names
124
+ component_names = []
125
+
126
+ JIRA_ENVIRONMENT[:projects].map do |project|
127
+ next unless pr_title_project_keys.include? project[:key]
128
+ component_names += project[:issues].map { |issue| issue[:components] }
129
+ end
130
+
131
+ component_names.flatten.uniq
132
+ end
133
+
134
+ def pr_title_related_project_keys
135
+ project_keys = []
136
+
137
+ JIRA_ENVIRONMENT[:projects].map do |project|
138
+ project_keys << project[:key] if pr_title_project_keys.include? project[:key]
139
+ end
140
+
141
+ project_keys.compact.uniq
142
+ end
143
+
144
+ def stub_jira_find_issue_response(code:, message:)
145
+ client = plugin.configure(jira_settings)
146
+
147
+ response_mock = Object.new
148
+ allow(response_mock).to receive(:code).and_return(code)
149
+ allow(response_mock).to receive(:message).and_return(message)
150
+
151
+ issue_mock = Object.new
152
+ allow(issue_mock).to receive(:find).and_raise(JIRA::HTTPError.new(response_mock))
153
+
154
+ allow(client).to receive(:Issue).and_return(issue_mock)
155
+ end
156
+
157
+ def stub_jira_find_issue_404
158
+ stub_jira_find_issue_response(code: 404, message: "Not found")
159
+ end
160
+
161
+ def stub_jira_find_issue_unauthorized
162
+ stub_jira_find_issue_response(code: 503, message: "Unauthorized")
163
+ end
164
+
165
+ it "returns a list of labels that contains Jira component names" do
166
+ stub_github_api_labelling
167
+
168
+ labels = []
169
+ VCR.use_cassette(:default_success, record: :new_episodes) do
170
+ labels = plugin.autolabel_pull_request(issue_prefixes)
171
+ end
172
+
173
+ expect(labels).to include(*pr_title_related_component_names)
174
+ end
175
+
176
+ it "returns a list of labels that contains Jira issue project keys" do
177
+ stub_github_api_labelling
178
+
179
+ labels = []
180
+ VCR.use_cassette(:default_success, record: :new_episodes) do
181
+ labels = plugin.autolabel_pull_request(issue_prefixes)
182
+ end
183
+
184
+ expect(labels).to include(*pr_title_related_project_keys)
185
+ end
186
+
187
+ it "creates a warning when a related Jira ticket cannot be fetched" do
188
+ stub_jira_find_issue_404
189
+
190
+ VCR.use_cassette(:default_success, record: :new_episodes) do
191
+ expect(plugin.autolabel_pull_request(issue_prefixes)).to be_nil
192
+ end
193
+
194
+ issue_warning_count = dangerfile.status_report[:warnings].count do |warning|
195
+ warning.start_with?("Error while retrieving JIRA issue")
196
+ end
197
+
198
+ expect(issue_warning_count).to eq(issue_prefixes.length)
199
+ end
200
+
201
+ it "creates only one warning when the Jira credentials are invalid" do
202
+ stub_jira_find_issue_unauthorized
203
+
204
+ VCR.use_cassette(:default_success, record: :new_episodes) do
205
+ expect(plugin.autolabel_pull_request(issue_prefixes)).to be_nil
206
+ end
207
+
208
+ issue_warning_count = dangerfile.status_report[:warnings].count do |warning|
209
+ warning.start_with?("Error while retrieving JIRA issue")
210
+ end
211
+
212
+ expect(issue_warning_count).to eq(1)
213
+ end
214
+
215
+ it "adds a label to the github issue for each related jira issue component name" do
216
+ pr_title_related_component_names.each do |component_name|
217
+ expect(github_api_mock).to receive(:add_label).with(anything, component_name, anything).once.and_return(nil)
218
+ end
219
+ stub_github_api_labelling
220
+
221
+ VCR.use_cassette(:default_success, record: :new_episodes) do
222
+ plugin.autolabel_pull_request(issue_prefixes)
223
+ end
224
+ end
225
+
226
+ it "adds a label to the github issue for each related jira issue project key" do
227
+ pr_title_related_project_keys.each do |project_key|
228
+ expect(github_api_mock).to receive(:add_label).with(anything, project_key, anything).once.and_return(nil)
229
+ end
230
+ stub_github_api_labelling
231
+
232
+ VCR.use_cassette(:default_success, record: :new_episodes) do
233
+ plugin.autolabel_pull_request(issue_prefixes)
234
+ end
235
+ end
236
+
237
+ it "adds missing github labels" do
238
+ labels = pr_title_project_keys + pr_title_related_component_names
239
+ labels.each do |label|
240
+ expect(github_api_mock).to receive(:add_label).with(anything, label, anything)
241
+ end
242
+ stub_github_api_labelling
243
+
244
+ VCR.use_cassette(:default_success, record: :new_episodes) do
245
+ plugin.autolabel_pull_request(issue_prefixes)
246
+ end
247
+ end
248
+
249
+ it "does not attempt to add new github labels when they already exist" do
250
+ existing_labels = %w(ComponentA)
251
+ existing_labels.each do |existing_label|
252
+ expect(github_api_mock).not_to receive(:add_label).with(anything, existing_label, anything)
253
+ end
254
+ stub_github_api_labelling(labels: existing_labels)
255
+
256
+ VCR.use_cassette(:default_success) do
257
+ plugin.autolabel_pull_request(issue_prefixes)
258
+ end
259
+ end
260
+
261
+ it "returns nil if no issue keys are found in the pr name or body" do
262
+ expect(plugin.autolabel_pull_request(["NOPE"])).to be_nil
263
+ end
264
+
265
+ it "falls back to issue keys in the pr body if none are found in the pr title" do
266
+ stub_github_api_labelling
267
+
268
+ VCR.use_cassette(:default_success, record: :new_episodes) do
269
+ plugin.autolabel_pull_request(pr_body_project_keys)
270
+ end
271
+ end
272
+
273
+ it "ignores issue keys in the pr body if any are found in the pr title" do
274
+ stub_github_api_labelling
275
+
276
+ labels = []
277
+ VCR.use_cassette(:default_success, record: :new_episodes) do
278
+ labels = plugin.autolabel_pull_request(pr_body_project_keys + pr_title_project_keys)
279
+ end
280
+
281
+ expect(labels).to include(*pr_title_project_keys)
282
+ expect(labels).not_to include(*pr_body_project_keys)
283
+ end
284
+
285
+ it "raises an ArgumentError if no issue_prefixes are specified" do
286
+ expect { plugin.autolabel_pull_request([]) }.to raise_error(ArgumentError)
287
+ end
288
+
289
+ it "returns nil if no labels can be fetched from Jira" do
290
+ stub_jira_find_issue_404
291
+
292
+ VCR.use_cassette(:default_success, record: :new_episodes) do
293
+ expect(plugin.autolabel_pull_request(issue_prefixes)).to be_nil
294
+ end
295
+ end
296
+ end
297
+ end
298
+ end
299
+ end
@@ -0,0 +1,87 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "pathname"
4
+ ROOT = Pathname.new(File.expand_path("..", __dir__))
5
+ $:.unshift((ROOT + "lib").to_s)
6
+ $:.unshift((ROOT + "spec").to_s)
7
+
8
+ require "bundler/setup"
9
+ require "pry"
10
+
11
+ require "dotenv"
12
+ Dotenv.load
13
+
14
+ # Must be required and started before danger
15
+ require "simplecov"
16
+ SimpleCov.start do
17
+ add_filter "/spec/"
18
+ end
19
+
20
+ require "rspec"
21
+ require "danger"
22
+ require "webmock"
23
+ require "webmock/rspec"
24
+ require "vcr"
25
+
26
+ if `git remote -v` == ""
27
+ puts "You cannot run tests without setting a local git remote on this repo"
28
+ puts "It's a weird side-effect of Danger's internals."
29
+ exit(0)
30
+ end
31
+
32
+ # Use coloured output, it's the best.
33
+ RSpec.configure do |config|
34
+ config.filter_gems_from_backtrace "bundler"
35
+ config.color = true
36
+ config.tty = true
37
+ end
38
+
39
+ VCR.configure do |config|
40
+ config.cassette_library_dir = "#{File.dirname(__FILE__)}/fixtures/vcr_cassettes"
41
+ config.hook_into :webmock
42
+ end
43
+
44
+ require "danger_plugin"
45
+
46
+ # These functions are a subset of https://github.com/danger/danger/blob/master/spec/spec_helper.rb
47
+ # If you are expanding these files, see if it's already been done ^.
48
+
49
+ # A silent version of the user interface,
50
+ # it comes with an extra function `.string` which will
51
+ # strip all ANSI colours from the string.
52
+
53
+ # rubocop:disable Lint/NestedMethodDefinition
54
+ def testing_ui
55
+ @output = StringIO.new
56
+ def @output.winsize
57
+ [20, 9999]
58
+ end
59
+
60
+ cork = Cork::Board.new(out: @output)
61
+ def cork.string
62
+ out.string.gsub(/\e\[([;\d]+)?m/, "")
63
+ end
64
+ cork
65
+ end
66
+ # rubocop:enable Lint/NestedMethodDefinition
67
+
68
+ # Example environment (ENV) that would come from
69
+ # running a PR on TravisCI
70
+ def testing_env
71
+ {
72
+ "HAS_JOSH_K_SEAL_OF_APPROVAL" => "true",
73
+ "TRAVIS_PULL_REQUEST" => "800",
74
+ "TRAVIS_REPO_SLUG" => "artsy/eigen",
75
+ "TRAVIS_COMMIT_RANGE" => "759adcbd0d8f...13c4dc8bb61d",
76
+ "DANGER_GITHUB_API_TOKEN" => ENV["DANGER_GITHUB_API_TOKEN"],
77
+ "DANGER_JIRA_URL" => ENV["DANGER_JIRA_URL"],
78
+ "DANGER_JIRA_USERNAME" => ENV["DANGER_JIRA_USERNAME"],
79
+ "DANGER_JIRA_API_TOKEN" => ENV["DANGER_JIRA_API_TOKEN"]
80
+ }
81
+ end
82
+
83
+ # A stubbed out Dangerfile for use in tests
84
+ def testing_dangerfile
85
+ env = Danger::EnvironmentManager.new(testing_env)
86
+ Danger::Dangerfile.new(env, testing_ui)
87
+ end
metadata ADDED
@@ -0,0 +1,293 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: danger-jira_sync
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Ben Menesini
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2018-06-16 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: danger-plugin-api
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: jira-ruby
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: 1.5.0
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: 1.5.0
41
+ - !ruby/object:Gem::Dependency
42
+ name: bundler
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '1.3'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '1.3'
55
+ - !ruby/object:Gem::Dependency
56
+ name: dotenv
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: rake
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: '10.0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: '10.0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: rspec
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: '3.4'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: '3.4'
97
+ - !ruby/object:Gem::Dependency
98
+ name: simplecov
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
111
+ - !ruby/object:Gem::Dependency
112
+ name: vcr
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - ">="
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - ">="
123
+ - !ruby/object:Gem::Version
124
+ version: '0'
125
+ - !ruby/object:Gem::Dependency
126
+ name: webmock
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - ">="
130
+ - !ruby/object:Gem::Version
131
+ version: '0'
132
+ type: :development
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - ">="
137
+ - !ruby/object:Gem::Version
138
+ version: '0'
139
+ - !ruby/object:Gem::Dependency
140
+ name: rubocop
141
+ requirement: !ruby/object:Gem::Requirement
142
+ requirements:
143
+ - - ">="
144
+ - !ruby/object:Gem::Version
145
+ version: '0'
146
+ type: :development
147
+ prerelease: false
148
+ version_requirements: !ruby/object:Gem::Requirement
149
+ requirements:
150
+ - - ">="
151
+ - !ruby/object:Gem::Version
152
+ version: '0'
153
+ - !ruby/object:Gem::Dependency
154
+ name: yard
155
+ requirement: !ruby/object:Gem::Requirement
156
+ requirements:
157
+ - - ">="
158
+ - !ruby/object:Gem::Version
159
+ version: '0'
160
+ type: :development
161
+ prerelease: false
162
+ version_requirements: !ruby/object:Gem::Requirement
163
+ requirements:
164
+ - - ">="
165
+ - !ruby/object:Gem::Version
166
+ version: '0'
167
+ - !ruby/object:Gem::Dependency
168
+ name: guard
169
+ requirement: !ruby/object:Gem::Requirement
170
+ requirements:
171
+ - - "~>"
172
+ - !ruby/object:Gem::Version
173
+ version: '2.14'
174
+ type: :development
175
+ prerelease: false
176
+ version_requirements: !ruby/object:Gem::Requirement
177
+ requirements:
178
+ - - "~>"
179
+ - !ruby/object:Gem::Version
180
+ version: '2.14'
181
+ - !ruby/object:Gem::Dependency
182
+ name: guard-rspec
183
+ requirement: !ruby/object:Gem::Requirement
184
+ requirements:
185
+ - - "~>"
186
+ - !ruby/object:Gem::Version
187
+ version: '4.7'
188
+ type: :development
189
+ prerelease: false
190
+ version_requirements: !ruby/object:Gem::Requirement
191
+ requirements:
192
+ - - "~>"
193
+ - !ruby/object:Gem::Version
194
+ version: '4.7'
195
+ - !ruby/object:Gem::Dependency
196
+ name: listen
197
+ requirement: !ruby/object:Gem::Requirement
198
+ requirements:
199
+ - - '='
200
+ - !ruby/object:Gem::Version
201
+ version: 3.0.7
202
+ type: :development
203
+ prerelease: false
204
+ version_requirements: !ruby/object:Gem::Requirement
205
+ requirements:
206
+ - - '='
207
+ - !ruby/object:Gem::Version
208
+ version: 3.0.7
209
+ - !ruby/object:Gem::Dependency
210
+ name: awesome_print
211
+ requirement: !ruby/object:Gem::Requirement
212
+ requirements:
213
+ - - ">="
214
+ - !ruby/object:Gem::Version
215
+ version: '0'
216
+ type: :development
217
+ prerelease: false
218
+ version_requirements: !ruby/object:Gem::Requirement
219
+ requirements:
220
+ - - ">="
221
+ - !ruby/object:Gem::Version
222
+ version: '0'
223
+ - !ruby/object:Gem::Dependency
224
+ name: pry
225
+ requirement: !ruby/object:Gem::Requirement
226
+ requirements:
227
+ - - ">="
228
+ - !ruby/object:Gem::Version
229
+ version: '0'
230
+ type: :development
231
+ prerelease: false
232
+ version_requirements: !ruby/object:Gem::Requirement
233
+ requirements:
234
+ - - ">="
235
+ - !ruby/object:Gem::Version
236
+ version: '0'
237
+ description: Synchronizes information between Jira and GitHub
238
+ email:
239
+ - ben.menesini@rover.com
240
+ executables: []
241
+ extensions: []
242
+ extra_rdoc_files: []
243
+ files:
244
+ - ".env.sample"
245
+ - ".gitignore"
246
+ - ".rubocop.yml"
247
+ - ".ruby-gemset"
248
+ - ".ruby-version"
249
+ - ".travis.yml"
250
+ - Gemfile
251
+ - Gemfile.lock
252
+ - Guardfile
253
+ - LICENSE.txt
254
+ - README.md
255
+ - Rakefile
256
+ - danger-jira_sync.gemspec
257
+ - lib/danger_jira_sync.rb
258
+ - lib/danger_plugin.rb
259
+ - lib/jira_sync/gem_version.rb
260
+ - lib/jira_sync/plugin.rb
261
+ - spec/fixtures/vcr_cassettes/default_success.yml
262
+ - spec/fixtures/vcr_cassettes/pull_request.yml
263
+ - spec/jira_sync_spec.rb
264
+ - spec/spec_helper.rb
265
+ homepage: https://github.com/roverdotcom/danger-jira_sync
266
+ licenses:
267
+ - MIT
268
+ metadata: {}
269
+ post_install_message:
270
+ rdoc_options: []
271
+ require_paths:
272
+ - lib
273
+ required_ruby_version: !ruby/object:Gem::Requirement
274
+ requirements:
275
+ - - ">="
276
+ - !ruby/object:Gem::Version
277
+ version: '0'
278
+ required_rubygems_version: !ruby/object:Gem::Requirement
279
+ requirements:
280
+ - - ">="
281
+ - !ruby/object:Gem::Version
282
+ version: '0'
283
+ requirements: []
284
+ rubyforge_project:
285
+ rubygems_version: 2.7.6
286
+ signing_key:
287
+ specification_version: 4
288
+ summary: Synchronizes information betweeh Jira and GitHub
289
+ test_files:
290
+ - spec/fixtures/vcr_cassettes/default_success.yml
291
+ - spec/fixtures/vcr_cassettes/pull_request.yml
292
+ - spec/jira_sync_spec.rb
293
+ - spec/spec_helper.rb