tefoji 1.0.9 → 1.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/mixins/user_functions.rb +1 -3
- data/lib/tefoji/cli.rb +17 -9
- data/lib/tefoji/jira_api.rb +153 -56
- data/lib/tefoji.rb +10 -8
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b048f1a4325a22d2fa736626f148827792639424d448ccc0d5a09250e250bdfa
|
4
|
+
data.tar.gz: 8350c3e8d0fdf3ad2ecfdf922ef654b37ddd86f9e44b4358cc713bf54cb462b8
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: fd6187add4fe25d2ea7ebcc3aadc8346cfbfeae133e1fc4c366dad99395cfcbddd0aa6c024caa9f86676651037dcacdf0f1092a98ab0a2d1cc74a9033ab7dd7c
|
7
|
+
data.tar.gz: 2d5fe6518a6a174aeb033e006fa92b168f5115bb4526cb7dbbce2b177ac185bb79b795fcf7e43e86e63f063150bb5e5e6ad2fee28f17251010bbe2d319efd4c7
|
@@ -34,7 +34,6 @@ module UserFunctions
|
|
34
34
|
# Maps of Winston-style Jira names (projects, sprints, to the actual assets
|
35
35
|
def jira_projects
|
36
36
|
{
|
37
|
-
BOLT: 'BOLT',
|
38
37
|
BUILD_TOOLS: 'BUILD',
|
39
38
|
CLIENT_TOOLS: 'CT',
|
40
39
|
CODE_MANAGEMENT: 'CODEMGMT',
|
@@ -50,14 +49,13 @@ module UserFunctions
|
|
50
49
|
OPERATIONS: 'OPS',
|
51
50
|
PDK: 'CONT',
|
52
51
|
PE_INTERNAL: 'PE',
|
52
|
+
POOLER: 'POOLER',
|
53
53
|
PROJECT_CENTRAL: 'PC',
|
54
54
|
PUPPETDB: 'PDB',
|
55
55
|
PUPPETSERVER: 'SERVER',
|
56
56
|
PUPPET_AGENT: 'PA',
|
57
57
|
PUPPET: 'PUP',
|
58
58
|
QUALITY_ENGINEERING: 'QENG',
|
59
|
-
DIO: 'DIO',
|
60
|
-
RAZOR: 'RAZOR',
|
61
59
|
RELEASE_ENGINEERING: 'RE',
|
62
60
|
SLV: 'SLV',
|
63
61
|
SUPPORT: 'SUP',
|
data/lib/tefoji/cli.rb
CHANGED
@@ -6,8 +6,11 @@ require 'yaml'
|
|
6
6
|
module Tefoji
|
7
7
|
class CLI
|
8
8
|
DEFAULT_JIRA_URL = 'https://tickets.puppetlabs.com'
|
9
|
-
JIRA_TEST_URL = 'https://jira-app-
|
9
|
+
JIRA_TEST_URL = 'https://jira-app-test-1.ops.puppetlabs.net/'
|
10
10
|
DEFAULT_JIRA_AUTH_FILE = "#{ENV['HOME']}/.tefoji-auth.yaml"
|
11
|
+
JIRA_CLOUD_URLS = [
|
12
|
+
'https://puppet.atlassian.net'
|
13
|
+
]
|
11
14
|
|
12
15
|
DOCUMENTATION = <<~DOCOPT
|
13
16
|
Generate Jira issues from YAML files.
|
@@ -47,19 +50,24 @@ module Tefoji
|
|
47
50
|
exit 0
|
48
51
|
end
|
49
52
|
|
53
|
+
@user_options['--jira'] = JIRA_TEST_URL if @user_options['--jira-test']
|
54
|
+
@user_options['--jira'] = DEFAULT_JIRA_URL if @user_options['--jira'].nil?
|
55
|
+
|
50
56
|
@user_options['jira-auth-string'] = nil
|
51
57
|
@user_options['jira-auth-file'] = @user_options['--jira-auth'] || DEFAULT_JIRA_AUTH_FILE
|
52
58
|
|
59
|
+
@user_options['jira-cloud'] = false
|
60
|
+
@user_options['jira-cloud'] = true if JIRA_CLOUD_URLS.include?(@user_options['--jira'])
|
61
|
+
|
53
62
|
jira_auth_file = @user_options['jira-auth-file']
|
54
|
-
|
55
|
-
authentication = YAML.load_file(jira_auth_file)
|
56
|
-
if authentication.key?('jira-auth')
|
57
|
-
@user_options['jira-auth-string'] = authentication['jira-auth']
|
58
|
-
end
|
59
|
-
end
|
63
|
+
return unless File.file?(jira_auth_file)
|
60
64
|
|
61
|
-
|
62
|
-
@user_options['
|
65
|
+
authentication = YAML.load_file(jira_auth_file)
|
66
|
+
if @user_options['jira-cloud'] && authentication.key?('jira-cloud-auth')
|
67
|
+
@user_options['jira-auth-string'] = authentication['jira-cloud-auth']
|
68
|
+
elsif authentication.key?('jira-auth')
|
69
|
+
@user_options['jira-auth-string'] = authentication['jira-auth']
|
70
|
+
end
|
63
71
|
end
|
64
72
|
|
65
73
|
# Iterate through issue templates, validating each. If that goes well, generate
|
data/lib/tefoji/jira_api.rb
CHANGED
@@ -2,6 +2,7 @@ require 'base64'
|
|
2
2
|
require 'io/console'
|
3
3
|
require 'json'
|
4
4
|
require 'rest-client'
|
5
|
+
RestClient.log = 'stdout'
|
5
6
|
|
6
7
|
module Tefoji
|
7
8
|
## An interface to send API request to Jira using the rest-client gem.
|
@@ -14,6 +15,7 @@ module Tefoji
|
|
14
15
|
include Logging
|
15
16
|
|
16
17
|
## Jira field keys
|
18
|
+
FIELD_ACCOUNT_ID = 'accountId'
|
17
19
|
FIELD_ID = 'id'
|
18
20
|
FIELD_KEY = 'key'
|
19
21
|
FIELD_NAME = 'name'
|
@@ -21,7 +23,6 @@ module Tefoji
|
|
21
23
|
|
22
24
|
## Issue type constants
|
23
25
|
ISSUE_EPIC = 'Epic'
|
24
|
-
ISSUE_FEATURE = 'Feature'
|
25
26
|
ISSUE_NEW_FEATURE = 'New Feature'
|
26
27
|
ISSUE_SUB_TASK = 'Sub-task'
|
27
28
|
ISSUE_TASK = 'Task'
|
@@ -74,20 +75,26 @@ module Tefoji
|
|
74
75
|
|
75
76
|
# Do this so we can inform the user quickly that their credentials didn't work
|
76
77
|
# There may be a better test, but this is the one the original Winston uses
|
77
|
-
def test_authentication
|
78
|
-
get_username(@jira_username)
|
78
|
+
def test_authentication(jira_cloud)
|
79
|
+
get_username(@jira_username, jira_cloud)
|
79
80
|
rescue RestClient::Forbidden
|
80
81
|
fatal 'Forbidden: either the authentication is incorrect or ' \
|
81
82
|
'Jira might be requiring a CAPTCHA response from the web interface.'
|
82
83
|
end
|
83
84
|
|
84
85
|
# Get information about user in Jira
|
85
|
-
def get_username(username, fail_if_not_found = true)
|
86
|
-
|
86
|
+
def get_username(username, jira_cloud, fail_if_not_found = true)
|
87
|
+
search_parameters = if jira_cloud
|
88
|
+
"user/search?query=#{username}"
|
89
|
+
else
|
90
|
+
"user?username=#{username}"
|
91
|
+
end
|
92
|
+
|
93
|
+
jira_get(search_parameters, fail_if_not_found)
|
87
94
|
end
|
88
95
|
|
89
96
|
# Save authentication YAML to the a file for reuse.
|
90
|
-
def save_authentication(save_file_name)
|
97
|
+
def save_authentication(save_file_name, jira_cloud)
|
91
98
|
backup_file_name = "#{save_file_name}.bak"
|
92
99
|
|
93
100
|
if File.readable?(save_file_name)
|
@@ -95,18 +102,22 @@ module Tefoji
|
|
95
102
|
@logger.info "Saved #{save_file_name} to #{backup_file_name}"
|
96
103
|
end
|
97
104
|
|
98
|
-
|
99
|
-
|
100
|
-
|
105
|
+
jira_auth_string = if jira_cloud
|
106
|
+
"jira-auth: #{@jira_auth_string}\n"
|
107
|
+
else
|
108
|
+
"jira-cloud-auth: #{@jira_auth_string}\n"
|
109
|
+
end
|
110
|
+
File.write(save_file_name, jira_auth_string)
|
111
|
+
|
101
112
|
File.chmod(0o600, save_file_name)
|
102
113
|
|
103
114
|
@logger.info "Saved Jira authentication to #{save_file_name}"
|
104
115
|
end
|
105
116
|
|
106
117
|
# Create a Jira issue
|
107
|
-
def create_issue(issue_data)
|
118
|
+
def create_issue(issue_data, jira_cloud)
|
108
119
|
request_path = 'issue'
|
109
|
-
jira_fields = issue_data_to_jira_fields(issue_data)
|
120
|
+
jira_fields = issue_data_to_jira_fields(issue_data, jira_cloud)
|
110
121
|
jira_post(request_path, jira_fields)
|
111
122
|
rescue RestClient::Forbidden
|
112
123
|
fatal "Forbidden: could not send #{request_path} request to Jira. "\
|
@@ -160,12 +171,25 @@ module Tefoji
|
|
160
171
|
end
|
161
172
|
|
162
173
|
# https://www.youtube.com/watch?v=JsntlJZ9h1U
|
163
|
-
def add_watcher(issue_key, watcher)
|
174
|
+
def add_watcher(issue_key, watcher, jira_cloud)
|
164
175
|
request_path = "issue/#{issue_key}/watchers"
|
176
|
+
watcher = useremail_to_id(watcher) if jira_cloud
|
165
177
|
request_data = watcher
|
166
178
|
jira_post(request_path, request_data)
|
167
179
|
end
|
168
180
|
|
181
|
+
# jira cloud api calls now require an accountId rather than a username. This method will convert
|
182
|
+
# emails or display names to accountIds.
|
183
|
+
def useremail_to_id(email)
|
184
|
+
response = get_username(email, true, true)[0]
|
185
|
+
id = response['accountId']
|
186
|
+
if id.nil? || id.empty?
|
187
|
+
@logger.error "accountId not found for #{email}."
|
188
|
+
exit 1
|
189
|
+
end
|
190
|
+
return id
|
191
|
+
end
|
192
|
+
|
169
193
|
private
|
170
194
|
|
171
195
|
def jira_get(jira_request_path, fail_if_not_found = true)
|
@@ -177,7 +201,6 @@ module Tefoji
|
|
177
201
|
url = "#{@jira_base_rest_url}/#{jira_request_path}"
|
178
202
|
end
|
179
203
|
headers = @authentication_header
|
180
|
-
|
181
204
|
begin
|
182
205
|
response = RestClient.get(url, headers)
|
183
206
|
rescue RestClient::MovedPermanently,
|
@@ -244,7 +267,7 @@ module Tefoji
|
|
244
267
|
# Provide the needed translation of user-created data to required format
|
245
268
|
# of Jira requests. This is mostly a list of fussing with the Jira field
|
246
269
|
# names.
|
247
|
-
def issue_data_to_jira_fields(issue_data)
|
270
|
+
def issue_data_to_jira_fields(issue_data, jira_cloud)
|
248
271
|
# Check to ensure we have what we need to create a issue
|
249
272
|
|
250
273
|
unless issue_data['summary']
|
@@ -257,64 +280,130 @@ module Tefoji
|
|
257
280
|
end
|
258
281
|
|
259
282
|
# build the jira_fields hash describing the issue
|
260
|
-
|
261
283
|
# These are required for all issues
|
262
284
|
jira_fields = {
|
263
285
|
'summary' => issue_data['summary'],
|
264
286
|
'project' => { 'key' => issue_data['project'] }
|
265
287
|
}
|
266
288
|
|
289
|
+
set_common_jira_fields(issue_data, jira_fields)
|
290
|
+
|
291
|
+
if jira_cloud
|
292
|
+
set_cloud_jira_fields(issue_data, jira_fields)
|
293
|
+
else
|
294
|
+
set_onprem_jira_fields(issue_data, jira_fields)
|
295
|
+
end
|
296
|
+
|
297
|
+
return { 'fields' => jira_fields }
|
298
|
+
end
|
299
|
+
|
300
|
+
def set_common_jira_fields(issue_data, jira_fields)
|
267
301
|
# The following are optional
|
268
302
|
if issue_data['description']
|
269
303
|
jira_fields['description'] = issue_data['description']
|
270
304
|
end
|
305
|
+
|
306
|
+
if issue_data['labels']
|
307
|
+
labels = issue_data['labels'].to_a.flatten.reject { |t| t =~ /^\s*$/ }
|
308
|
+
jira_fields['labels'] = labels unless labels.empty?
|
309
|
+
end
|
310
|
+
if issue_data['duedate']
|
311
|
+
jira_fields['duedate'] = issue_data['duedate']
|
312
|
+
end
|
313
|
+
if issue_data['fix_version']
|
314
|
+
jira_fields['fixVersions'] = [issue_data['fix_version']]
|
315
|
+
end
|
316
|
+
|
317
|
+
if issue_data['components']
|
318
|
+
components = issue_data[:components].to_a.flatten.reject { |t| t =~ /^\s*$/ }
|
319
|
+
unless components.empty?
|
320
|
+
jira_fields['components'] = components.map { |component| { FIELD_NAME => component } }
|
321
|
+
end
|
322
|
+
end
|
323
|
+
|
324
|
+
# Default issue type to ISSUE_TASK if it isn't already set
|
325
|
+
jira_fields['issuetype'] = { FIELD_NAME => ISSUE_TASK }
|
326
|
+
|
327
|
+
security = ENV['SECURITY'] || issue_data['security']
|
328
|
+
return unless security
|
329
|
+
|
330
|
+
case security.downcase
|
331
|
+
when 'confidential'
|
332
|
+
jira_fields['security'] = { FIELD_ID => '10002' }
|
333
|
+
when 'internal'
|
334
|
+
jira_fields['security'] = { FIELD_ID => '10001' }
|
335
|
+
when 'public'
|
336
|
+
# Nothing to do here - public is default
|
337
|
+
else
|
338
|
+
@logger.fatal "Unknown security type: #{security}"
|
339
|
+
exit 1
|
340
|
+
end
|
341
|
+
end
|
342
|
+
|
343
|
+
def set_cloud_jira_fields(issue_data, jira_fields)
|
271
344
|
if issue_data['assignee']
|
272
|
-
|
345
|
+
assignee = issue_data['assignee']
|
346
|
+
assignee = useremail_to_id(assignee)
|
347
|
+
jira_fields['assignee'] = { FIELD_ACCOUNT_ID => assignee }
|
273
348
|
end
|
349
|
+
|
350
|
+
if issue_data['type']
|
351
|
+
jira_fields['issuetype'] = { FIELD_NAME => issue_data['type'] }
|
352
|
+
# If this is an epic, we need to add an epic name
|
353
|
+
if issue_data['type'].casecmp?(ISSUE_EPIC)
|
354
|
+
jira_fields['customfield_10011'] = issue_data['epic_name'] || issue_data['summary']
|
355
|
+
end
|
356
|
+
end
|
357
|
+
|
274
358
|
if issue_data['story_points']
|
275
|
-
jira_fields['
|
359
|
+
jira_fields['customfield_10038'] = issue_data['story_points'].to_i
|
276
360
|
end
|
277
361
|
if issue_data['team']
|
278
|
-
jira_fields['
|
362
|
+
jira_fields['customfield_10052'] = { FIELD_VALUE => issue_data['team'] }
|
279
363
|
end
|
280
364
|
if issue_data['teams']
|
281
365
|
teams = issue_data['teams'].to_a.flatten.reject { |t| t =~ /^\s*$/ }
|
282
366
|
unless teams.empty?
|
283
|
-
jira_fields['
|
367
|
+
jira_fields['customfield_10066'] = teams.map { |team| { FIELD_VALUE => team } }
|
284
368
|
end
|
285
369
|
end
|
286
370
|
if issue_data['subteam']
|
287
|
-
jira_fields['
|
371
|
+
jira_fields['customfield_10045'] = [issue_data['subteam']]
|
288
372
|
end
|
289
373
|
if issue_data['sprint']
|
290
|
-
jira_fields['
|
374
|
+
jira_fields['customfield_10020'] = issue_data['sprint'].to_i
|
291
375
|
end
|
292
376
|
if issue_data['acceptance']
|
293
|
-
jira_fields['
|
294
|
-
end
|
295
|
-
if issue_data['labels']
|
296
|
-
labels = issue_data['labels'].to_a.flatten.reject { |t| t =~ /^\s*$/ }
|
297
|
-
jira_fields['labels'] = labels unless labels.empty?
|
298
|
-
end
|
299
|
-
if issue_data['duedate']
|
300
|
-
jira_fields['duedate'] = issue_data['duedate']
|
301
|
-
end
|
302
|
-
if issue_data['fix_version']
|
303
|
-
jira_fields['fixVersions'] = [issue_data['fix_version']]
|
377
|
+
jira_fields['customfield_10062'] = issue_data['acceptance']
|
304
378
|
end
|
305
379
|
if issue_data['release_notes']
|
306
|
-
jira_fields['
|
380
|
+
jira_fields['customfield_10043'] = { FIELD_VALUE => issue_data['release_notes'] }
|
307
381
|
end
|
308
382
|
|
309
|
-
|
310
|
-
|
311
|
-
|
312
|
-
|
383
|
+
# If a issue has a specified parent issue, prefer that. The parent issue *should* already
|
384
|
+
# be linked to the main epic. Otherwise, we need to set it to have an epic_parent. This can
|
385
|
+
# either be an epic linked to the main epic or the main epic itself.
|
386
|
+
|
387
|
+
if issue_data['parent']
|
388
|
+
unless issue_data['type'].casecmp?(ISSUE_SUB_TASK) || !issue_data['type']
|
389
|
+
@logger.fatal "A issue with a parent must be classified as a Sub-issue\n\n#{issue_data}"
|
390
|
+
exit 1
|
391
|
+
end
|
392
|
+
jira_fields['issuetype'] = { FIELD_NAME => ISSUE_SUB_TASK }
|
393
|
+
jira_fields['parent'] = { FIELD_KEY => issue_data['parent'] }
|
394
|
+
elsif issue_data['epic_parent']
|
395
|
+
if issue_data['type'].casecmp?(ISSUE_SUB_TASK)
|
396
|
+
@logger.fatal "This issue cannot be a subtask of an epic\n\n#{issue_data}"
|
397
|
+
exit 1
|
313
398
|
end
|
399
|
+
jira_fields['customfield_10018'] = issue_data['epic_parent']
|
314
400
|
end
|
401
|
+
end
|
315
402
|
|
316
|
-
|
317
|
-
|
403
|
+
def set_onprem_jira_fields(issue_data, jira_fields)
|
404
|
+
if issue_data['assignee']
|
405
|
+
jira_fields['assignee'] = { FIELD_NAME => issue_data['assignee'] }
|
406
|
+
end
|
318
407
|
|
319
408
|
if issue_data['type']
|
320
409
|
jira_fields['issuetype'] = { FIELD_NAME => issue_data['type'] }
|
@@ -324,6 +413,31 @@ module Tefoji
|
|
324
413
|
end
|
325
414
|
end
|
326
415
|
|
416
|
+
if issue_data['story_points']
|
417
|
+
jira_fields['customfield_10002'] = issue_data['story_points'].to_i
|
418
|
+
end
|
419
|
+
if issue_data['team']
|
420
|
+
jira_fields['customfield_14200'] = { FIELD_VALUE => issue_data['team'] }
|
421
|
+
end
|
422
|
+
if issue_data['teams']
|
423
|
+
teams = issue_data['teams'].to_a.flatten.reject { |t| t =~ /^\s*$/ }
|
424
|
+
unless teams.empty?
|
425
|
+
jira_fields['customfield_14201'] = teams.map { |team| { FIELD_VALUE => team } }
|
426
|
+
end
|
427
|
+
end
|
428
|
+
if issue_data['subteam']
|
429
|
+
jira_fields['customfield_11700'] = [issue_data['subteam']]
|
430
|
+
end
|
431
|
+
if issue_data['sprint']
|
432
|
+
jira_fields['customfield_10005'] = issue_data['sprint'].to_i
|
433
|
+
end
|
434
|
+
if issue_data['acceptance']
|
435
|
+
jira_fields['customfield_11501'] = issue_data['acceptance']
|
436
|
+
end
|
437
|
+
if issue_data['release_notes']
|
438
|
+
jira_fields['customfield_11100'] = { FIELD_VALUE => issue_data['release_notes'] }
|
439
|
+
end
|
440
|
+
|
327
441
|
# If a issue has a specified parent issue, prefer that. The parent issue *should* already
|
328
442
|
# be linked to the main epic. Otherwise, we need to set it to have an epic_parent. This can
|
329
443
|
# either be an epic linked to the main epic or the main epic itself.
|
@@ -342,23 +456,6 @@ module Tefoji
|
|
342
456
|
end
|
343
457
|
jira_fields['customfield_10006'] = issue_data['epic_parent']
|
344
458
|
end
|
345
|
-
|
346
|
-
security = ENV['SECURITY'] || issue_data['security']
|
347
|
-
if security
|
348
|
-
case security.downcase
|
349
|
-
when 'confidential'
|
350
|
-
jira_fields['security'] = { FIELD_ID => '10002' }
|
351
|
-
when 'internal'
|
352
|
-
jira_fields['security'] = { FIELD_ID => '10001' }
|
353
|
-
when 'public'
|
354
|
-
# Nothing to do here - public is default
|
355
|
-
else
|
356
|
-
@logger.fatal "Unknown security type: #{security}"
|
357
|
-
exit 1
|
358
|
-
end
|
359
|
-
end
|
360
|
-
|
361
|
-
return { 'fields' => jira_fields }
|
362
459
|
end
|
363
460
|
end
|
364
461
|
|
data/lib/tefoji.rb
CHANGED
@@ -28,6 +28,7 @@ module Tefoji
|
|
28
28
|
@jira_auth_string = user_options['jira-auth-string']
|
29
29
|
@jira_auth_file = user_options['jira-auth-file']
|
30
30
|
@jira_mock = user_options['--jira-mock']
|
31
|
+
@jira_cloud = user_options['jira-cloud']
|
31
32
|
|
32
33
|
@no_notes = user_options['--no-notes']
|
33
34
|
@template_data = {}
|
@@ -272,13 +273,13 @@ module Tefoji
|
|
272
273
|
@jira_api.logger = @logger
|
273
274
|
|
274
275
|
@jira_api.authenticate(@jira_url, @jira_user, @jira_auth_string)
|
275
|
-
@jira_api.test_authentication unless @jira_mock
|
276
|
+
@jira_api.test_authentication(@jira_cloud) unless @jira_mock
|
276
277
|
end
|
277
278
|
|
278
279
|
# Save Jira auth data
|
279
280
|
def save_authentication
|
280
281
|
authenticate unless @jira_api
|
281
|
-
@jira_api.save_authentication(@jira_auth_file)
|
282
|
+
@jira_api.save_authentication(@jira_auth_file, @jira_cloud)
|
282
283
|
end
|
283
284
|
|
284
285
|
private
|
@@ -297,8 +298,9 @@ module Tefoji
|
|
297
298
|
feature_to_do = @template_data['feature']
|
298
299
|
|
299
300
|
feature = variable_substitute(feature_to_do)
|
300
|
-
feature['type'] = JiraApi::
|
301
|
-
|
301
|
+
feature['type'] = JiraApi::ISSUE_NEW_FEATURE
|
302
|
+
|
303
|
+
@feature_issue = @jira_api.create_issue(feature, @jira_cloud)
|
302
304
|
@logger.info "Feature issue: #{@feature_issue['key']}"
|
303
305
|
@feature_issue
|
304
306
|
end
|
@@ -360,7 +362,7 @@ module Tefoji
|
|
360
362
|
epic['security'] = 'internal'
|
361
363
|
end
|
362
364
|
|
363
|
-
epic_issue = @jira_api.create_issue(epic)
|
365
|
+
epic_issue = @jira_api.create_issue(epic, @jira_cloud)
|
364
366
|
epic_issue['short_name'] = short_name
|
365
367
|
@logger.info 'Epic: %16s [%s]' % [epic_issue['key'], short_name]
|
366
368
|
@jira_api.link_issues(@feature_issue['key'], epic_issue['key']) if @feature_issue
|
@@ -400,7 +402,7 @@ module Tefoji
|
|
400
402
|
jira_ready_data, raw_issue_data = prepare_jira_ready_data(issue, issue_defaults)
|
401
403
|
next if jira_ready_data.nil? || raw_issue_data.nil?
|
402
404
|
|
403
|
-
response_data = @jira_api.create_issue(jira_ready_data)
|
405
|
+
response_data = @jira_api.create_issue(jira_ready_data, @jira_cloud)
|
404
406
|
jira_issue = @jira_api.retrieve_issue(response_data['self'])
|
405
407
|
jira_issue['short_name'] = raw_issue_data['short_name']
|
406
408
|
|
@@ -610,7 +612,7 @@ module Tefoji
|
|
610
612
|
issue_key = jira_issue_data['key']
|
611
613
|
watchers = raw_issue_data[deferred_tag].value
|
612
614
|
watchers.each do |watcher|
|
613
|
-
@jira_api.add_watcher(issue_key, watcher)
|
615
|
+
@jira_api.add_watcher(issue_key, watcher, @jira_cloud)
|
614
616
|
@logger.info '%14s: watched by %s' % [issue_key, watcher]
|
615
617
|
end
|
616
618
|
end
|
@@ -932,7 +934,7 @@ module Tefoji
|
|
932
934
|
def update_user_validity(username, issue_name, valid_users, invalid_users)
|
933
935
|
if invalid_users.key?(username)
|
934
936
|
invalid_users[username] += [issue_name]
|
935
|
-
elsif @jira_api.get_username(username, false)
|
937
|
+
elsif @jira_api.get_username(username, @jira_cloud, false)
|
936
938
|
valid_users << username
|
937
939
|
else
|
938
940
|
invalid_users[username] = invalid_users.fetch(username, []) + [issue_name]
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: tefoji
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0
|
4
|
+
version: 1.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Puppet Labs
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-
|
11
|
+
date: 2023-05-17 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: pry-byebug
|