tefoji 3.4.2 → 3.5.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b63db03509300205daa35c04b5329905a3d276a436d747ff884d310b8aac9d53
4
- data.tar.gz: c050a2e8a39285ee728247955c133dab3b87f9526d23549b34e3d91a85d53877
3
+ metadata.gz: fc4b951086f14bcc81ab1aabd55e9598d10178ba5cbfbd61984d89444b2df2b3
4
+ data.tar.gz: a822ad69a634e8e78d763adde8e0606460b290f7b291553216194ddb7c59c23a
5
5
  SHA512:
6
- metadata.gz: 32756204412d4c4b1ab1420fcc9b67b4caaeb1f34ea5c8ea62b5e02466592371d9e7f5e377417ca6dfce6c7c88766350955415a65d5d10a0995297e1d93c99fe
7
- data.tar.gz: 17b5b4a29527381c795e3f220b6b4a446c82c92c9bd6ee0fb70cae8b0d928a42eadc047c7f5c97dd6ab135b7b626bbe0e6f319122a41b8bd5a832f2b10455f18
6
+ metadata.gz: 4720d892040f8f1be05329d2de1845c1a2255441c9e71cb7211df1b189c4d0d342f31c6611ad52f210fb442a289406250f53c0a7705bbc7c244bd8fe3de3d750
7
+ data.tar.gz: b2e7f33d4e8cd0ee744a3e7d55b8d6d29b5a48887441f54ba0bfdb55789f31167913a963c368fcee9d4458572bd48e7571257e2c853935ac5ed9d52d500a2d05
@@ -48,6 +48,7 @@ module UserFunctions
48
48
  MODULES: 'MODULES',
49
49
  MODULES_INTERNAL: 'FM',
50
50
  OPERATIONS: 'OPS',
51
+ P4DEVOPS: 'P4DEVOPS',
51
52
  PDK: 'CONT',
52
53
  PE_INTERNAL: 'PE',
53
54
  POOLER: 'POOLER',
@@ -57,7 +58,6 @@ module UserFunctions
57
58
  PUPPETSERVER: 'SERVER',
58
59
  PUPPET_AGENT: 'PA',
59
60
  QUALITY_ENGINEERING: 'QENG',
60
- RELEASE_ENGINEERING: 'RE',
61
61
  SLV: 'SLV',
62
62
  SUPPORT: 'SUP',
63
63
  VANAGON: 'VANAGON',
@@ -80,8 +80,7 @@ module UserFunctions
80
80
  CODE_MANAGEMENT: 'Dumpling',
81
81
  DUMPLING: 'Dumpling',
82
82
  FACTER: 'Phoenix',
83
- INSTALLER: 'Installer and Management',
84
- NETWORKING: 'Network Automation',
83
+ INSTALLER: 'Installer',
85
84
  OPERATIONS: 'Operations',
86
85
  PE: 'Dumpling',
87
86
  PLATFORM_OS: 'Unicorn',
@@ -73,21 +73,28 @@ module Tefoji
73
73
  # HTTP doesn't like linefeeds in the auth string, hence #strict_encode64
74
74
  @jira_auth = Base64.strict_encode64(decoded_auth.join(':'))
75
75
  @authentication_header = { 'Authorization' => "Basic #{@jira_auth}" }
76
- end
77
76
 
78
- # Do this so we can inform the user quickly that their credentials didn't work
79
- # There may be a better test, but this is the one the original Winston uses
80
- def test_authentication
81
- get_username(@jira_username)
82
- rescue RestClient::Forbidden
83
- fatal 'Forbidden: either the authentication is incorrect or ' \
84
- 'Jira might be requiring a CAPTCHA response from the web interface.'
77
+ # Verify authentication
78
+ return if @jira_mock
79
+ return if get_username(@jira_username)
80
+
81
+ @logger.info "Authentication failed, trying again with username: #{@jira_username}@perforce.com"
82
+ # Reset authentication with @perforce.com added to username
83
+ @jira_username = "#{@jira_username}@perforce.com"
84
+ decoded_auth[0] = @jira_username
85
+ @jira_auth = Base64.strict_encode64(decoded_auth.join(':'))
86
+ @authentication_header = { 'Authorization' => "Basic #{@jira_auth}" }
87
+ # Retry authentication
88
+ fatal 'Authentication failed: Credentials are invalid' unless get_username(@jira_username)
85
89
  end
86
90
 
87
91
  # Get information about user in Jira
88
- def get_username(username, fail_if_not_found = true)
92
+ def get_username(username)
89
93
  search_parameters = "user/search?query=#{username}"
90
- jira_get(search_parameters, fail_if_not_found)
94
+ response = jira_get(search_parameters)
95
+ return false if response.empty?
96
+
97
+ response
91
98
  end
92
99
 
93
100
  # Get information about user in Jira
@@ -197,7 +204,7 @@ module Tefoji
197
204
  account_name = user_name_to_account_name(user_email)
198
205
  response = get_username(account_name)
199
206
 
200
- fatal "Jira account ID not found for \"#{account_name}\"" if response.empty?
207
+ fatal "Jira account ID not found for \"#{account_name}\"" unless response
201
208
  account_id = response[0]['accountId']
202
209
 
203
210
  @logger.debug("user account name: \"#{account_name} \" " \
@@ -241,7 +248,7 @@ module Tefoji
241
248
  issue_data.key?('type') && issue_data['type'].casecmp?(ISSUE_EPIC)
242
249
  end
243
250
 
244
- def jira_get(jira_request_path, fail_if_not_found = true)
251
+ def jira_get(jira_request_path)
245
252
  # Jira likes to send complete URLs for responses. Handle
246
253
  # the case where we've received a 'self' query from Jira with
247
254
  # fully formed url
@@ -265,8 +272,7 @@ module Tefoji
265
272
  SocketError,
266
273
  Errno::ECONNREFUSED => e
267
274
  # Return false if not found rather than fail to allow for checking the existence of users.
268
- fatal "Cannot connect to #{@jira_base_rest_url}: #{e.message}" if fail_if_not_found
269
- return false
275
+ fatal "Cannot connect to #{@jira_base_rest_url}: #{e.message}"
270
276
  end
271
277
  return JSON.parse(response.body)
272
278
  end
@@ -433,6 +439,14 @@ module Tefoji
433
439
  jira_fields['customfield_10020'] = issue_data['sprint'].to_i
434
440
  end
435
441
 
442
+ if issue_data['product']
443
+ jira_fields['customfield_10350'] = { FIELD_VALUE => issue_data['product'] }
444
+ end
445
+
446
+ if issue_data['shirt_size']
447
+ jira_fields['customfield_10078'] = { FIELD_VALUE => issue_data['shirt_size'] }
448
+ end
449
+
436
450
  # If a issue has a specified parent issue, prefer that. The parent issue *should* already
437
451
  # be linked to the main epic. Otherwise, we need to set it to have an epic_parent. This can
438
452
  # either be an epic linked to the main epic or the main epic itself.
@@ -1,3 +1,3 @@
1
1
  module Tefoji
2
- VERSION = '3.4.2'
2
+ VERSION = '3.5.0'
3
3
  end
data/lib/tefoji.rb CHANGED
@@ -75,6 +75,8 @@ module Tefoji
75
75
  @declarations[k] = DeclaredValue.new(v)
76
76
  end
77
77
 
78
+ standardize_epics(main_template_data)
79
+
78
80
  resolve_variables(main_template_data['declare'])
79
81
  @logger.debug "Declarations: #{@declarations}"
80
82
 
@@ -85,6 +87,7 @@ module Tefoji
85
87
  main_template.dig(:includes, :before)&.each do |before|
86
88
  default_epic_saved = @default_target_epic
87
89
  @formats = before.dig(:data, 'formats') if before.dig(:data, 'formats')
90
+ standardize_epics(before[:data])
88
91
  process_template(before[:template_name], before[:data], before[:conditional])
89
92
  @default_target_epic = default_epic_saved
90
93
  end
@@ -98,6 +101,7 @@ module Tefoji
98
101
  main_template.dig(:includes, :after)&.each do |after|
99
102
  default_epic_saved = @default_target_epic
100
103
  @formats = after.dig(:data, 'formats') if after.dig(:data, 'formats')
104
+ standardize_epics(after[:data])
101
105
  process_template(after[:template_name], after[:data], after[:conditional])
102
106
  @default_target_epic = default_epic_saved
103
107
  end
@@ -118,9 +122,7 @@ module Tefoji
118
122
  @template_data = template_data
119
123
 
120
124
  if @template_data.key?('epics')
121
- generate_epics_with_issues('epics')
122
- elsif @template_data.key?('epic')
123
- generate_epics_with_issues('epic')
125
+ generate_epics_with_issues
124
126
  elsif @template_data.key?('issues')
125
127
  generate_ordinary_issues
126
128
  else
@@ -272,7 +274,6 @@ module Tefoji
272
274
  @jira_api.logger = @logger
273
275
 
274
276
  @jira_api.authenticate(@jira_url, @jira_user, @jira_auth_string)
275
- @jira_api.test_authentication unless @jira_mock
276
277
  end
277
278
 
278
279
  # Save Jira auth data
@@ -281,8 +282,8 @@ module Tefoji
281
282
  @jira_api.save_authentication(@jira_auth_file)
282
283
  end
283
284
 
284
- def generate_epics_with_issues(epic_key)
285
- epics = generate_epics(epic_key)
285
+ def generate_epics_with_issues
286
+ epics = generate_epics
286
287
  epics.each do |epic|
287
288
  @default_target_epic = epic
288
289
  generate_ordinary_issues
@@ -290,8 +291,8 @@ module Tefoji
290
291
  end
291
292
 
292
293
  # @return [Array] an array of responses from Jira containing a hash of the epic fields.
293
- def generate_epics(epic_key)
294
- epic_to_do_list = [@template_data[epic_key]].flatten
294
+ def generate_epics
295
+ epic_to_do_list = [@template_data['epics']].flatten
295
296
  @logger.debug "Generating data: #{@template_data}"
296
297
 
297
298
  epic_to_do_list.map do |epic|
@@ -848,6 +849,7 @@ module Tefoji
848
849
  def check_assignees(main_template_data)
849
850
  valid_users = []
850
851
  invalid_users_to_epics = {}
852
+
851
853
  main_template_data['epics']&.each do |epic|
852
854
  next unless epic['assignee']
853
855
 
@@ -862,18 +864,6 @@ module Tefoji
862
864
  )
863
865
  end
864
866
 
865
- if main_template_data.dig('epic', 'assignee')
866
- assignee_username = get_username_from_assignee(main_template_data['epic']['assignee'])
867
- unless valid_users.include?(assignee_username)
868
- update_user_validity(
869
- assignee_username,
870
- main_template_data['epic']['summary'],
871
- valid_users,
872
- invalid_users_to_epics
873
- )
874
- end
875
- end
876
-
877
867
  invalid_users_to_issue_defaults = {}
878
868
  if main_template_data.dig('issue_defaults', 'assignee')
879
869
  assignee_username = get_username_from_assignee(
@@ -943,7 +933,7 @@ module Tefoji
943
933
  def update_user_validity(username, issue_name, valid_users, invalid_users)
944
934
  if invalid_users.key?(username)
945
935
  invalid_users[username] += [issue_name]
946
- elsif @jira_api.get_username(username, false)
936
+ elsif @jira_api.get_username(username)
947
937
  valid_users << username
948
938
  else
949
939
  invalid_users[username] = invalid_users.fetch(username, []) + [issue_name]
@@ -954,6 +944,7 @@ module Tefoji
954
944
  # in the associated project.
955
945
  def check_components(main_template_data)
956
946
  invalid_components = Set.new
947
+
957
948
  main_template_data['epics']&.each do |epic|
958
949
  next unless epic['components']
959
950
 
@@ -964,14 +955,6 @@ module Tefoji
964
955
  end
965
956
  end
966
957
 
967
- if main_template_data.dig('epic', 'components')
968
- project = expand_right_value(main_template_data['epic']['project']).value
969
- update_valid_components(project)
970
- main_template_data['epic']['components'].each do |component|
971
- invalid_components.add([project, component]) unless @valid_components[project].include?(component)
972
- end
973
- end
974
-
975
958
  main_template_data['issues'].each do |issue|
976
959
  next unless issue['components']
977
960
 
@@ -1013,5 +996,25 @@ module Tefoji
1013
996
 
1014
997
  logger
1015
998
  end
999
+
1000
+ # Takes template data as input and ensures the format for the epics
1001
+ # field is the 'epics' key with an array as the value.
1002
+ def standardize_epics(template_data)
1003
+ # Determine if epic or epics key exists
1004
+ if template_data['epic']
1005
+ epic_value = 'epic'
1006
+ elsif template_data['epics']
1007
+ epic_value = 'epics'
1008
+ else
1009
+ @logger.debug('No epics found in template, skipping standardize_epics')
1010
+ return
1011
+ end
1012
+ # Convert epic data to array if not currently an array
1013
+ epics_data = template_data[epic_value]
1014
+ epics_data = [template_data[epic_value]] unless epics_data.is_a?(Array)
1015
+ # Set epics data and delete epic data if it exists
1016
+ template_data['epics'] = epics_data
1017
+ template_data.delete('epic') if epic_value == 'epic'
1018
+ end
1016
1019
  end
1017
1020
  end
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: 3.4.2
4
+ version: 3.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Puppet By Perforce
8
- autorequire:
8
+ autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2024-03-21 00:00:00.000000000 Z
11
+ date: 2025-10-27 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: debug
@@ -175,7 +175,7 @@ metadata:
175
175
  homepage_uri: https://github.com/puppetlabs/tefoji
176
176
  source_code_uri: https://github.com/puppetlabs/tefoji
177
177
  changelog_uri: https://github.com/puppetlabs/tefoji/blob/main/CHANGELOG.md
178
- post_install_message:
178
+ post_install_message:
179
179
  rdoc_options: []
180
180
  require_paths:
181
181
  - lib
@@ -191,7 +191,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
191
191
  version: '0'
192
192
  requirements: []
193
193
  rubygems_version: 3.2.33
194
- signing_key:
194
+ signing_key:
195
195
  specification_version: 4
196
196
  summary: Generate Jira issues from a YAML specification.
197
197
  test_files: []