pdksync 0.5.0 → 0.8.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.
data/lib/pdksync.rb CHANGED
@@ -4,59 +4,44 @@ require 'open3'
4
4
  require 'fileutils'
5
5
  require 'rake'
6
6
  require 'pdk'
7
- require 'pdksync/constants'
7
+ require 'pdksync/configuration'
8
8
  require 'pdksync/gitplatformclient'
9
+
9
10
  require 'json'
10
11
  require 'yaml'
11
- require 'colorize'
12
12
  require 'bundler'
13
13
  require 'octokit'
14
+ require 'pdk/util/template_uri'
15
+ require 'pdksync/logger'
16
+ require 'pdksync/utils'
17
+ require 'terminal-table'
14
18
 
15
19
  # @summary
16
20
  # This module set's out and controls the pdksync process
17
- # @param [String] @namspace
18
- # The namespace of the repositories we are updating.
19
- # @param [String] @pdksync_dir
20
- # The local directory the repositories are to be copied to.
21
- # @param [String] @push_file_destination
22
- # The remote that the pull requests are to be made against.
23
- # @param [String] @create_pr_against
24
- # The branch the the pull requests are to be made against.
25
- # @param [String] @managed_modules
26
- # The file that the array of managed modules is to be retrieved from.
27
- # @param [Symbol] @git_platform
28
- # The Git hosting platform to use for pull requests
29
- # @param [String] @git_base_uri
30
- # The base URI for Git repository access, for example 'https://github.com' or
31
- # 'ssh://git@repo.example.com:2222'
32
- # @param [Hash] @git_platform_access_settings
33
- # Hash of access settings required to access the configured Git hosting
34
- # platform API. Must always contain the key :access_token set to the exported
35
- # GITHUB_TOKEN or GITLAB_TOKEN. In case of Gitlab it also must contain the
36
- # key :gitlab_api_endpoint with an appropriate value.
37
21
  module PdkSync
38
- include Constants
39
- @namespace = Constants::NAMESPACE
40
- @pdksync_dir = Constants::PDKSYNC_DIR
41
- @push_file_destination = Constants::PUSH_FILE_DESTINATION
42
- @create_pr_against = Constants::CREATE_PR_AGAINST
43
- @managed_modules = Constants::MANAGED_MODULES
44
- @default_pdksync_label = Constants::PDKSYNC_LABEL
45
- @git_platform = Constants::GIT_PLATFORM
46
- @git_base_uri = Constants::GIT_BASE_URI
47
- @git_platform_access_settings = {
48
- access_token: Constants::ACCESS_TOKEN,
49
- gitlab_api_endpoint: Constants::GITLAB_API_ENDPOINT
50
- }
22
+ def self.configuration
23
+ @configuration ||= PdkSync::Configuration.new
24
+ end
25
+
26
+ @main_path = Dir.pwd
27
+
28
+ def self.client
29
+ @client ||= Utils.setup_client
30
+ end
51
31
 
52
32
  def self.main(steps: [:clone], args: nil)
53
- check_pdk_version
54
- create_filespace
55
- client = setup_client
56
- module_names = return_modules
57
- raise "No modules found in '#{@managed_modules}'" if module_names.nil?
58
- validate_modules_exist(client, module_names)
33
+ Utils.check_pdk_version if ENV['PDKSYNC_VERSION_CHECK'].eql?('true')
34
+ Utils.create_filespace
35
+ Utils.create_filespace_gem
36
+ module_names = Utils.return_modules
37
+
38
+ unless steps.include?(:clone_gem) || steps.include?(:multi_gem_testing)
39
+ raise "No modules found in '#{Utils.configuration.managed_modules}'" if module_names.nil?
40
+ end
41
+
59
42
  pr_list = []
43
+ report_rows = []
44
+ table = Terminal::Table.new
60
45
 
61
46
  # The current directory is saved for cleanup purposes
62
47
  main_path = Dir.pwd
@@ -64,455 +49,330 @@ module PdkSync
64
49
  # validation run_a_command
65
50
  if steps.include?(:run_a_command)
66
51
  raise '"run_a_command" requires an argument to run.' if args.nil?
67
- puts "Command '#{args}'"
52
+ PdkSync::Logger.info "Command '#{args}'"
68
53
  end
69
54
  # validation create_commit
70
55
  if steps.include?(:create_commit)
71
56
  raise 'Needs a branch_name and commit_message' if args.nil? || args[:commit_message].nil? || args[:branch_name].nil?
72
- puts "Commit branch_name=#{args[:branch_name]} commit_message=#{args[:commit_message]}"
57
+ PdkSync::Logger.info "Commit branch_name=#{args[:branch_name]} commit_message=#{args[:commit_message]}"
73
58
  end
74
59
  # validation create_pr
75
60
  if steps.include?(:create_pr)
76
61
  raise 'Needs a pr_title' if args.nil? || args[:pr_title].nil?
77
- puts "PR title =#{args[:additional_title]} #{args[:pr_title]}"
62
+ PdkSync::Logger.info "PR title =#{args[:additional_title]} #{args[:pr_title]}"
78
63
  end
79
64
  # validation clean_branches
80
65
  if steps.include?(:clean_branches)
81
66
  raise 'Needs a branch_name, and the branch name contains the string pdksync' if args.nil? || args[:branch_name].nil? || !args[:branch_name].include?('pdksync')
82
- puts "Removing branch_name =#{args[:branch_name]}"
67
+ PdkSync::Logger.info "Removing branch_name =#{args[:branch_name]}"
68
+ end
69
+ # validation clone_gem
70
+ if steps.include?(:clone_gem)
71
+ raise 'Needs a gem_name' if args.nil? || args[:gem_name].nil?
72
+ PdkSync::Logger.info "Command '#{args}'"
73
+ end
74
+ # validation multi_gem_testing
75
+ if steps.include?(:multi_gem_testing)
76
+ raise '"multi_gem_testing" requires arguments to run version_file and build_gem.' if args.nil? || args[:version_file].nil? || args[:build_gem].nil?
77
+ puts "Command '#{args}'"
78
+ end
79
+ # validation multi_gem_file_update
80
+ if steps.include?(:multigem_file_update)
81
+ raise 'multigem_file_update requires arguments gem_to_test, gemfury_username to run.' if args[:gem_name].nil? || args[:gemfury_username].nil?
82
+ puts "Command '#{args}'"
83
+ end
84
+ # validation gem_file_update
85
+ if steps.include?(:gem_file_update)
86
+ raise '"gem_file_update" requires arguments (gem_to_test) to run.' if args[:gem_to_test].nil?
87
+ puts "Command '#{args}'"
88
+ end
89
+ # validation run_tests_locally
90
+ if steps.include?(:run_tests_locally)
91
+ puts "Command '#{args}'"
92
+ end
93
+ # validation fetch_test_results_locally
94
+ if steps.include?(:fetch_test_results_locally)
95
+ puts "Command '#{args}'"
96
+ end
97
+ # validation run_tests_jenkins
98
+ if steps.include?(:run_tests_jenkins)
99
+ raise 'run_tests_jenkins requires arguments (jenkins_server_url, github_branch) to run.' if args[:github_branch].nil? || args[:jenkins_server_url].nil?
100
+ puts "Command '#{args}'"
101
+ end
102
+ # validation test_results_jenkins
103
+ if steps.include?(:test_results_jenkins)
104
+ raise 'test_results_jenkins requires argument jenkins_server_url to run.' if args[:jenkins_server_url].nil?
105
+ puts "Command '#{args}'"
83
106
  end
84
107
 
85
- abort "No modules listed in #{@managed_modules}" if module_names.nil?
86
- module_names.each do |module_name|
87
- module_args = args.clone
108
+ unless steps.include?(:clone_gem) || steps.include?(:multi_gem_testing)
109
+ abort "No modules listed in #{Utils.configuration.managed_modules}" if module_names.nil?
110
+ end
111
+
112
+ if steps.include?(:clone_gem) || steps.include?(:multi_gem_testing)
113
+ gem_args = args.clone
88
114
  Dir.chdir(main_path) unless Dir.pwd == main_path
89
- print "#{module_name}, "
90
- repo_name = "#{@namespace}/#{module_name}"
91
- output_path = "#{@pdksync_dir}/#{module_name}"
92
- if steps.include?(:clone)
93
- clean_env(output_path) if Dir.exist?(output_path)
94
- print 'delete module directory, '
95
- @git_repo = clone_directory(@namespace, module_name, output_path)
96
- print 'cloned, '
97
- puts "(WARNING) Unable to clone repo for #{module_name}".red if @git_repo.nil?
115
+ PdkSync::Logger.info "#{gem_args[:gem_name]}, "
116
+ output_path = File.join(Utils.configuration.pdksync_gem_dir, gem_args[:gem_name])
117
+ if steps.include?(:clone_gem)
118
+ Utils.clean_env(output_path) if Dir.exist?(output_path)
119
+ PdkSync::Logger.info 'delete gem directory, '
120
+ @git_repo = Utils.clone_directory(Utils.configuration.namespace, gem_args[:gem_name], output_path)
121
+ PdkSync::Logger.info 'cloned'
122
+ PdkSync::Logger.error "Unable to clone repo for #{gem_args[:gem_name]}".red if @git_repo.nil?
98
123
  Dir.chdir(main_path) unless Dir.pwd == main_path
99
- next if @git_repo.nil?
100
124
  end
101
- puts '(WARNING) @output_path does not exist, skipping module'.red unless File.directory?(output_path)
102
- next unless File.directory?(output_path)
103
- if steps.include?(:pdk_convert)
104
- exit_status = run_command(output_path, "#{return_pdk_path} convert --force --template-url https://github.com/puppetlabs/pdk-templates")
105
- print 'converted, '
106
- next unless exit_status.zero?
107
- end
108
- if steps.include?(:pdk_validate)
125
+ puts '(WARNING) @output_path does not exist, gem'.red unless File.directory?(output_path)
126
+ if steps.include?(:multi_gem_testing)
109
127
  Dir.chdir(main_path) unless Dir.pwd == main_path
110
- exit_status = run_command(output_path, "#{return_pdk_path} validate -a")
111
- print 'validated, '
112
- next unless exit_status.zero?
113
- end
114
- if steps.include?(:run_a_command)
128
+ PdkSync::Logger.info 'Multi Gem Testing, '
129
+ current_gem_version = Utils.check_gem_latest_version(gem_args[:gem_name])
130
+ PdkSync::Logger.info current_gem_version
131
+ new_gem_version = Utils.update_gem_latest_version_by_one(current_gem_version)
132
+ PdkSync::Logger.info new_gem_version
115
133
  Dir.chdir(main_path) unless Dir.pwd == main_path
116
- print 'run command, '
117
- exit_status = run_command(output_path, module_args)
118
- next unless exit_status.zero?
119
- end
120
- if steps.include?(:pdk_update)
134
+ exit_status = Utils.run_command(output_path, "sed s/#{current_gem_version}/#{new_gem_version}/g #{gem_args[:version_file]} >> test.yml", nil)
135
+ PdkSync::Logger.info 'Updated the version'
121
136
  Dir.chdir(main_path) unless Dir.pwd == main_path
122
- next unless pdk_update(output_path).zero?
123
- if steps.include?(:use_pdk_ref)
124
- ref = return_template_ref
125
- pr_title = module_args[:additional_title] ? "#{module_args[:additional_title]} - pdksync_#{ref}" : "pdksync_#{ref}"
126
- module_args = module_args.merge(branch_name: "pdksync_#{ref}",
127
- commit_message: pr_title,
128
- pr_title: pr_title,
129
- pdksync_label: @default_pdksync_label)
130
- end
131
- print 'pdk update, '
132
- end
133
- if steps.include?(:create_commit)
137
+ exit_status = Utils.run_command(output_path, "cp test.yml #{gem_args[:version_file]}", nil)
134
138
  Dir.chdir(main_path) unless Dir.pwd == main_path
135
- git_instance = Git.open(output_path)
136
- create_commit(git_instance, module_args[:branch_name], module_args[:commit_message])
137
- print 'commit created, '
138
- end
139
- if steps.include?(:push)
139
+ exit_status = Utils.run_command(output_path, 'rm -rf test.yml', nil)
140
+ PdkSync::Logger.info 'bundle install'
141
+ Dir.chdir(main_path) unless Dir.pwd == main_path
142
+ exit_status = Utils.run_command(output_path, 'bundle install', nil)
143
+ PdkSync::Logger.info 'building gem'
144
+ Dir.chdir(main_path) unless Dir.pwd == main_path
145
+ exit_status = Utils.run_command(output_path, "bundle exec #{gem_args[:build_gem]}", nil)
146
+ PdkSync::Logger.info 'uploading packages'
140
147
  Dir.chdir(main_path) unless Dir.pwd == main_path
141
- git_instance = Git.open(output_path)
142
- if git_instance.diff(git_instance.current_branch, "#{@push_file_destination}/#{@create_pr_against}").size != 0 # Git::Diff doesn't have empty? # rubocop:disable Style/ZeroLengthPredicate
143
- push_staged_files(git_instance, git_instance.current_branch, repo_name)
144
- print 'push, '
145
- else
146
- print 'skipped push, '
148
+ Dir.chdir("#{output_path}/#{gem_args[:gem_path]}") unless Dir.pwd == output_path
149
+ gemfury_token = Utils.configuration.gemfury_access_settings
150
+ Dir.glob('*.gem') do |filename|
151
+ PdkSync::Logger.info filename
152
+ Dir.chdir(main_path) unless Dir.pwd == main_path
153
+ exit_status = Utils.run_command("#{output_path}/#{gem_args[:gem_path]}", "curl -F package=@#{filename} https://" + gemfury_token + "@push.fury.io/#{gem_args[:gemfury_username]}/", nil)
147
154
  end
148
155
  end
149
- if steps.include?(:create_pr)
156
+ else
157
+ module_names.each do |module_name|
158
+ module_args = args.clone
150
159
  Dir.chdir(main_path) unless Dir.pwd == main_path
151
- git_instance = Git.open(output_path)
152
- if git_instance.diff(git_instance.current_branch, "#{@push_file_destination}/#{@create_pr_against}").size != 0 # Git::Diff doesn't have empty? # rubocop:disable Style/ZeroLengthPredicate
153
- pdk_version = return_pdk_version("#{output_path}/metadata.json")
154
-
155
- # If a label is supplied, verify that it is available in the repo
156
- label = module_args[:pdksync_label] ? module_args[:pdksync_label] : module_args[:label]
157
- label_valid = (label.is_a?(String) && !label.to_str.empty?) ? check_for_label(client, repo_name, label) : nil
158
-
159
- # Exit current iteration if an error occured retrieving a label
160
- if label_valid == false
161
- raise 'Ensure label is valid'
160
+ PdkSync::Logger.info "#{module_name}, "
161
+ repo_name = File.join(Utils.configuration.namespace, module_name)
162
+ output_path = File.join(Utils.configuration.pdksync_dir, module_name)
163
+ if steps.include?(:clone)
164
+ Utils.validate_modules_exist(client, [module_name])
165
+ Utils.clean_env(output_path) if Dir.exist?(output_path)
166
+ PdkSync::Logger.info 'delete module directory'
167
+ @git_repo = Utils.clone_directory(Utils.configuration.namespace, module_name, output_path)
168
+ PdkSync::Logger.info 'cloned'
169
+ PdkSync::Logger.error "Unable to clone repo for #{module_name}" if @git_repo.nil?
170
+ Dir.chdir(main_path) unless Dir.pwd == main_path
171
+ next if @git_repo.nil?
172
+ end
173
+ PdkSync::Logger.warn "#{output_path} does not exist, skipping module" unless File.directory?(output_path)
174
+ next unless File.directory?(output_path)
175
+ if steps.include?(:pdk_convert)
176
+ exit_status = Utils.run_command(output_path, "#{Utils.return_pdk_path} convert --force #{configuration.templates}", nil)
177
+ PdkSync::Logger.info 'converted'
178
+ next unless exit_status.zero?
179
+ end
180
+ if steps.include?(:pdk_validate)
181
+ Dir.chdir(main_path) unless Dir.pwd == main_path
182
+ exit_status = Utils.run_command(output_path, "#{Utils.return_pdk_path} validate -a", nil)
183
+ PdkSync::Logger.info 'validated' if exit_status.zero?
184
+ next unless exit_status.zero?
185
+ end
186
+ if steps.include?(:run_a_command)
187
+ Dir.chdir(main_path) unless Dir.pwd == main_path
188
+ PdkSync::Logger.info 'run command'
189
+ if module_args[:option].nil?
190
+ pid = Utils.run_command(output_path, module_args[:command], module_args[:option])
191
+ next unless pid != 0 # rubocop:disable Metrics/BlockNesting
192
+ else
193
+ exit_status = Utils.run_command(output_path, module_args[:command], nil)
194
+ next unless exit_status.zero? # rubocop:disable Metrics/BlockNesting
162
195
  end
163
-
164
- # Create the PR and add link to pr list
165
- pr = create_pr(client, repo_name, git_instance.current_branch, pdk_version, module_args[:pr_title])
166
- if pr.nil?
167
- break
196
+ end
197
+ if steps.include?(:gem_file_update)
198
+ Dir.chdir(main_path) unless Dir.pwd == main_path
199
+ print 'gem file update, '
200
+ Utils.gem_file_update(output_path, module_args[:gem_to_test], module_args[:gem_line], module_args[:gem_sha_finder], module_args[:gem_sha_replacer], module_args[:gem_version_finder], module_args[:gem_version_replacer], module_args[:gem_branch_finder], module_args[:gem_branch_replacer], main_path) # rubocop:disable Metrics/LineLength
201
+ print 'gem file updated, '
202
+ end
203
+ if steps.include?(:run_tests_locally)
204
+ Dir.chdir(main_path) unless Dir.pwd == main_path
205
+ PdkSync::Logger.info 'Run tests '
206
+ module_type = Utils.module_type(output_path, module_name)
207
+ Utils.run_tests_locally(output_path, module_type, module_args[:provision_type], module_name, module_args[:puppet_collection])
208
+ end
209
+ if steps.include?(:fetch_test_results_locally)
210
+ Dir.chdir(main_path) unless Dir.pwd == main_path
211
+ PdkSync::Logger.info 'Fetch test results for local run '
212
+ module_type = Utils.module_type(output_path, module_name)
213
+ table = Utils.fetch_test_results_locally(output_path, module_type, module_name, report_rows)
214
+ end
215
+ if steps.include?(:pdk_update)
216
+ Dir.chdir(main_path) unless Dir.pwd == main_path
217
+ next unless Utils.pdk_update(output_path).zero?
218
+ if steps.include?(:use_pdk_ref)
219
+ ref = Utils.return_template_ref(File.join(output_path, 'metadata.json'))
220
+ pr_title = module_args[:additional_title] ? "#{module_args[:additional_title]} - pdksync_#{ref}" : "pdksync_#{ref}" # rubocop:disable Metrics/BlockNesting
221
+ module_args = module_args.merge(branch_name: "pdksync_#{ref}",
222
+ commit_message: pr_title,
223
+ pr_title: pr_title,
224
+ pdksync_label: Utils.configuration.default_pdksync_label)
168
225
  end
169
-
170
- pr_list.push(pr.html_url)
171
- print 'created pr, '
172
-
173
- # If a valid label is supplied, add this to the PR
174
- if label_valid == true
175
- add_label(client, repo_name, pr.number, label)
176
- print "added label '#{label}' "
226
+ PdkSync::Logger.info 'pdk update'
227
+ end
228
+ if steps.include?(:use_gem_ref)
229
+ pr_title = module_args[:additional_title] ? "#{module_args[:additional_title]} - pdksync_gem_testing" : 'pdksync_gem_testing'
230
+ module_args = module_args.merge(branch_name: "gem_testing_#{module_args[:gem_to_test]}",
231
+ commit_message: pr_title,
232
+ pr_title: pr_title,
233
+ pdksync_label: Utils.configuration.default_pdksync_label)
234
+ end
235
+ if steps.include?(:create_commit)
236
+ Dir.chdir(main_path) unless Dir.pwd == main_path
237
+ git_instance = Git.open(output_path)
238
+ Utils.create_commit(git_instance, module_args[:branch_name], module_args[:commit_message])
239
+ PdkSync::Logger.info 'commit created'
240
+ end
241
+ if steps.include?(:push)
242
+ Dir.chdir(main_path) unless Dir.pwd == main_path
243
+ git_instance = Git.open(output_path)
244
+ if git_instance.diff(git_instance.current_branch, "#{Utils.configuration.push_file_destination}/#{Utils.configuration.create_pr_against}").size != 0 # Git::Diff doesn't have empty? # rubocop:disable Style/ZeroLengthPredicate
245
+ PdkSync::Logger.info 'push'
246
+ Utils.push_staged_files(git_instance, git_instance.current_branch, repo_name)
247
+ else
248
+ PdkSync::Logger.info 'skipped push'
177
249
  end
178
- else
179
- print 'skipped pr, '
180
250
  end
181
- end
182
- if steps.include?(:clean_branches)
183
- Dir.chdir(main_path) unless Dir.pwd == main_path
184
- delete_branch(client, repo_name, module_args[:branch_name])
185
- print 'branch deleted, '
186
- end
187
- puts 'done.'.green
188
- end
189
- return if pr_list.size.zero?
190
- puts "\nPRs created:\n".blue
191
- pr_list.each do |pr|
192
- puts pr
193
- end
194
- end
195
-
196
- # @summary
197
- # Check the local pdk version against the most recent tagged release on GitHub
198
- def self.check_pdk_version
199
- stdout, _stderr, status = Open3.capture3("#{return_pdk_path} --version")
200
- raise "(FAILURE) Unable to find pdk at '#{return_pdk_path}'.".red unless status.exitstatus
201
-
202
- local_version = stdout.strip
203
- remote_version = Octokit.tags('puppetlabs/pdk').first[:name][1..-1]
204
-
205
- unless Gem::Version.new(remote_version) <= Gem::Version.new(local_version)
206
- puts "(WARNING) The current version of pdk is #{remote_version} however you are using #{local_version}".red
207
- end
208
- rescue StandardError => error
209
- puts "(WARNING) Unable to check latest pdk version. #{error}".red
210
- end
211
-
212
- # @summary
213
- # This method when called will create a directory identified by the set global variable '@pdksync_dir', on the condition that it does not already exist.
214
- def self.create_filespace
215
- FileUtils.mkdir @pdksync_dir unless Dir.exist?(@pdksync_dir)
216
- end
217
-
218
- # @summary
219
- # This method when called will create and return an octokit client with access to the upstream git repositories.
220
- # @return [PdkSync::GitPlatformClient] client
221
- # The Git platform client that has been created.
222
- def self.setup_client
223
- PdkSync::GitPlatformClient.new(@git_platform, @git_platform_access_settings)
224
- rescue StandardError => error
225
- raise "Git platform access not set up correctly: #{error}"
226
- end
227
-
228
- # @summary
229
- # This method when called will access a file set by the global variable '@managed_modules' and retrieve the information within as an array.
230
- # @return [Array]
231
- # An array of different module names.
232
- def self.return_modules
233
- raise "File '#{@managed_modules}' is empty/does not exist" if File.size?(@managed_modules).nil?
234
- YAML.safe_load(File.open(@managed_modules))
235
- end
236
-
237
- # @summary
238
- # This method when called will parse an array of module names and verify
239
- # whether they are valid repo or project names on the configured Git
240
- # hosting platform.
241
- # @param [PdkSync::GitPlatformClient] client
242
- # The Git platform client used to get a repository.
243
- # @param [Array] module_names
244
- # String array of the names of Git platform repos
245
- def self.validate_modules_exist(client, module_names)
246
- invalid_names = []
247
- raise "Error reading in modules. Check syntax of '#{@managed_modules}'." unless !module_names.nil? && module_names.is_a?(Array)
248
- module_names.each do |module_name|
249
- # If module name is invalid, push it to invalid names array
250
- unless client.repository?("#{@namespace}/#{module_name}")
251
- invalid_names.push(module_name)
252
- next
253
- end
254
- end
255
- # Raise error if any invalid matches were found
256
- raise "Could not find the following repositories: #{invalid_names}" unless invalid_names.empty?
257
- end
258
-
259
- # @summary
260
- # Try to use a fully installed pdk, otherwise fall back to the bundled pdk gem.
261
- # @return String
262
- # Path to the pdk executable
263
- def self.return_pdk_path
264
- full_path = '/opt/puppetlabs/pdk/bin/pdk'
265
- path = if File.executable?(full_path)
266
- full_path
267
- else
268
- puts "(WARNING) Using pdk on PATH not '#{full_path}'".red
269
- 'pdk'
270
- end
271
- path
272
- end
273
-
274
- def self.create_commit(git_repo, branch_name, commit_message)
275
- checkout_branch(git_repo, branch_name)
276
- if add_staged_files(git_repo) # ignore rubocop for clarity on side effect ordering # rubocop:disable Style/GuardClause
277
- commit_staged_files(git_repo, branch_name, commit_message)
278
- end
279
- end
280
-
281
- # @summary
282
- # This method when called will call the delete function against the given repository if it exists.
283
- # @param [String] output_path
284
- # The repository that is to be deleted.
285
- def self.clean_env(output_path)
286
- # If a local copy already exists it is removed
287
- FileUtils.rm_rf(output_path)
288
- end
289
-
290
- # @summary
291
- # This method when called will clone a given repository into a local location that has also been set.
292
- # @param [String] namespace
293
- # The namespace the repository is located in.
294
- # @param [String] module_name
295
- # The name of the repository.
296
- # @param [String] output_path
297
- # The location the repository is to be cloned to.
298
- # @return [Git::Base]
299
- # A git object representing the local repository.
300
- def self.clone_directory(namespace, module_name, output_path)
301
- Git.clone("#{@git_base_uri}/#{namespace}/#{module_name}.git", output_path.to_s) # is returned
302
- rescue Git::GitExecuteError => error
303
- puts "(FAILURE) Cloning #{module_name} has failed. #{error}".red
304
- end
305
-
306
- # @summary
307
- # This method when called will run a command command at the given location, with an error message being thrown if it is not successful.
308
- # @param [String] output_path
309
- # The location that the command is to be run from.
310
- # @param [String] command
311
- # The command to be run.
312
- # @return [Integer]
313
- # The status code of the command run.
314
- def self.run_command(output_path, command)
315
- stdout = ''
316
- stderr = ''
317
- status = Process::Status
318
-
319
- Dir.chdir(output_path) unless Dir.pwd == output_path
320
-
321
- # Environment cleanup required due to Ruby subshells using current Bundler environment
322
- if command =~ %r{^bundle}
323
- Bundler.with_clean_env do
324
- stdout, stderr, status = Open3.capture3(command)
325
- end
326
- else
327
- stdout, stderr, status = Open3.capture3(command)
328
- end
329
-
330
- puts "\n#{stdout}\n".yellow
331
- puts "(FAILURE) Unable to run command '#{command}': #{stderr}".red unless status.exitstatus.zero?
332
- status.exitstatus
333
- end
251
+ if steps.include?(:create_pr)
252
+ Dir.chdir(main_path) unless Dir.pwd == main_path
253
+ git_instance = Git.open(output_path)
254
+ if git_instance.diff(git_instance.current_branch, "#{Utils.configuration.push_file_destination}/#{Utils.configuration.create_pr_against}").size != 0 # Git::Diff doesn't have empty? # rubocop:disable Style/ZeroLengthPredicate
255
+ pdk_version = Utils.return_pdk_version("#{output_path}/metadata.json")
256
+
257
+ # If a label is supplied, verify that it is available in the repo
258
+ label = module_args[:pdksync_label] ? module_args[:pdksync_label] : module_args[:label] # rubocop:disable Metrics/BlockNesting
259
+ label_valid = (label.is_a?(String) && !label.to_str.empty?) ? Utils.check_for_label(client, repo_name, label) : nil # rubocop:disable Metrics/BlockNesting
260
+
261
+ # Exit current iteration if an error occured retrieving a label
262
+ if label_valid == false # rubocop:disable Metrics/BlockNesting
263
+ raise 'Ensure label is valid'
264
+ end
265
+
266
+ # Create the PR and add link to pr list
267
+ pr = Utils.create_pr(client, repo_name, git_instance.current_branch, pdk_version, module_args[:pr_title])
268
+ break if pr.nil? # rubocop:disable Metrics/BlockNesting
269
+
270
+ pr_list.push(pr.html_url)
271
+ PdkSync::Logger.info 'created pr'
272
+
273
+ # If a valid label is supplied, add this to the PR
274
+ if label_valid == true # rubocop:disable Metrics/BlockNesting
275
+ Utils.add_label(client, repo_name, pr.number, label)
276
+ PdkSync::Logger.info "added label '#{label}' "
277
+ end
278
+ else
279
+ PdkSync::Logger.info 'skipped pr'
280
+ end
281
+ end
282
+ if steps.include?(:clean_branches)
283
+ Dir.chdir(main_path) unless Dir.pwd == main_path
284
+ Utils.delete_branch(client, repo_name, module_args[:branch_name])
285
+ PdkSync::Logger.info 'branch deleted'
286
+ end
287
+ if steps.include?(:run_tests_jenkins)
288
+ jenkins_client = Utils.setup_jenkins_client(module_args[:jenkins_server_url])
289
+ Dir.chdir(main_path) unless Dir.pwd == main_path
290
+ PdkSync::Logger.info 'Run tests in jenkins '
291
+ module_type = Utils.module_type(output_path, module_name)
292
+ if module_type == 'traditional'
293
+ github_user = 'puppetlabs' if module_args[:test_framework].nil? # rubocop:disable Metrics/BlockNesting
294
+ github_user = module_args[:github_user] unless module_args[:github_user].nil? # rubocop:disable Metrics/BlockNesting
295
+ if module_args[:test_framework] == 'jenkins' || module_args[:test_framework].nil? # rubocop:disable Metrics/BlockNesting
296
+ module_name = "puppetlabs-#{module_name}" if %w[cisco_ios device_manager].include?(module_name) # rubocop:disable Metrics/BlockNesting
297
+ job_name = "forge-module_#{module_name}_init-manual-parameters_adhoc"
298
+ job_name = "forge-windows_#{module_name}_init-manual-parameters_adhoc" if ['puppetlabs-reboot', 'puppetlabs-iis', 'puppetlabs-powershell', 'sqlserver'].include?(module_name) # rubocop:disable Metrics/BlockNesting, Metrics/LineLength
299
+ build_id = Utils.run_tests_jenkins(jenkins_client, module_name, module_args[:github_branch], github_user, job_name)
300
+ next if build_id.nil? # rubocop:disable Metrics/BlockNesting
301
+ PdkSync::Logger.info "New adhoc TEST EXECUTION has started. \nYou can check progress here: #{configuration['jenkins_server_url']}/job/#{job_name}/#{build_id}"
302
+ Utils.test_results_jenkins(module_args[:jenkins_server_url], build_id, job_name, module_name)
303
+ end
304
+ end
305
+ if module_type == 'litmus'
306
+ PdkSync::Logger.info '(Error) Module Type is Litmus please use the rake task run_tests_locally to run'.red
307
+ end
308
+ end
309
+ if steps.include?(:test_results_jenkins)
310
+ Dir.chdir(main_path) unless Dir.pwd == main_path
311
+ PdkSync::Logger.info 'Fetch test results from jenkins, '
312
+ module_type = Utils.module_type(output_path, module_name)
313
+ if module_type == 'litmus'
314
+ PdkSync::Logger.info '(Error) Module Type is Litmus please use the rake task run_tests_locally to run'.red
315
+ next
316
+ end
334
317
 
335
- # @summary
336
- # This method when called will run the 'pdk update --force' command at the given location, with an error message being thrown if it is not successful.
337
- # @param [String] output_path
338
- # The location that the command is to be run from.
339
- # @return [Integer]
340
- # The status code of the pdk update run.
341
- def self.pdk_update(output_path)
342
- # Runs the pdk update command
343
- Dir.chdir(output_path) unless Dir.pwd == output_path
344
- _stdout, stderr, status = Open3.capture3("#{return_pdk_path} update --force")
345
- puts "(FAILURE) Unable to run `pdk update`: #{stderr}".red unless status.exitstatus.zero?
346
- status.exitstatus
347
- end
318
+ module_name = "puppetlabs-#{module_name}" if %w[cisco_ios device_manager].include?(module_name)
319
+ File.open("results_#{module_name}.out", 'r') do |f|
320
+ f.each_line do |line|
321
+ if line.include?('BUILD_ID')
322
+ build_id = line.split('=')[1].strip
323
+ elsif line.include?('MODULE_NAME')
324
+ module_name = line.split('=')[1].strip
325
+ end
326
+ end
348
327
 
349
- # @summary
350
- # This method when called will retrieve the template ref of the current module, i.e. the one that was navigated into in the 'pdk_update' method.
351
- # @param [String] metadata_file
352
- # An optional input that can be used to set the location of the metadata file.
353
- # @return [String]
354
- # A string value that represents the current pdk template.
355
- def self.return_template_ref(metadata_file = 'metadata.json')
356
- file = File.read(metadata_file)
357
- data_hash = JSON.parse(file)
358
- data_hash['template-ref']
359
- end
328
+ job_name = "forge-module_#{module_name}_init-manual-parameters_adhoc" if module_args[:job_name].nil?
329
+ job_name = "forge-windows_#{module_name}_init-manual-parameters_adhoc" if ['puppetlabs-reboot', 'puppetlabs-iis', 'puppetlabs-powershell', 'sqlserver'].include?(module_name)
330
+ Utils.test_results_jenkins(module_args[:jenkins_server_url], build_id, job_name, module_name)
331
+ end
332
+ end
333
+ if steps.include?(:multigem_file_update)
334
+ Dir.chdir(main_path) unless Dir.pwd == main_path
335
+ gemfury_readonly_token = Utils.configuration.gemfury_access_settings
336
+ Utils.update_gemfile_multigem(output_path, module_args[:gem_name], gemfury_readonly_token, module_args[:gemfury_username])
337
+ PdkSync::Logger.info 'Updated with multigem, '
338
+ end
360
339
 
361
- # @summary
362
- # This method when called will checkout a new local branch of the given repository.
363
- # @param [Git::Base] git_repo
364
- # A git object representing the local repository to be branched.
365
- # @param [String] branch_suffix
366
- # The string that is appended on the branch name. eg template_ref or a friendly name
367
- def self.checkout_branch(git_repo, branch_suffix)
368
- git_repo.branch("pdksync_#{branch_suffix}").checkout
369
- end
340
+ if steps.include?(:add_provision_list)
341
+ result = Utils.add_provision_list(output_path, module_args[:key], module_args[:provisioner], [module_args[:images], module_args.extras].flatten)
342
+ raise "#{output_path}/provision.yaml does not exist" unless result
343
+ end
370
344
 
371
- # @summary
372
- # This method when called will retrieve the pdk_version of the current module, i.e. the one that was navigated into in the 'pdk_update' method.
373
- # @param [String] metadata_file
374
- # An optional input that can be used to set the location of the metadata file.
375
- # @return [String]
376
- # A string value that represents the current pdk version.
377
- def self.return_pdk_version(metadata_file = 'metadata.json')
378
- file = File.read(metadata_file)
379
- data_hash = JSON.parse(file)
380
- data_hash['pdk-version']
381
- end
345
+ if steps.include?(:generate_vmpooler_release_checks)
346
+ Utils.generate_vmpooler_release_checks(output_path, module_args[:puppet_version].to_i)
347
+ end
382
348
 
383
- # @summary
384
- # This method when called will stage all changed files within the given repository, conditional on them being managed via the pdk.
385
- # @param [Git::Base] git_repo
386
- # A git object representing the local repository to be staged.
387
- def self.add_staged_files(git_repo)
388
- if git_repo.status.changed != {}
389
- git_repo.add(all: true)
390
- puts 'All files have been staged.'
391
- true
392
- else
393
- puts 'Nothing to commit.'
394
- false
395
- end
396
- end
349
+ if steps.include?(:update_os_support)
350
+ Utils.update_os_support(output_path)
351
+ end
397
352
 
398
- # @summary
399
- # This method when called will create a commit containing all currently staged files, with the name of the commit containing the template ref as a unique identifier.
400
- # @param [Git::Base] git_repo
401
- # A git object representing the local repository against which the commit is to be made.
402
- # @param [String] template_ref
403
- # The unique template_ref that is used as part of the commit name.
404
- # @param [String] commit_message
405
- # If specified it will be the message for the commit.
406
- def self.commit_staged_files(git_repo, template_ref, commit_message = nil)
407
- message = if commit_message.nil?
408
- "pdksync_#{template_ref}"
409
- else
410
- commit_message
411
- end
412
- git_repo.commit(message)
413
- end
353
+ if steps.include?(:remove_platform_from_metadata)
354
+ Utils.remove_platform_from_metadata(output_path, module_args[:os], module_args[:version])
355
+ end
414
356
 
415
- # @summary
416
- # This method when called will push the given local commit to local repository's origin.
417
- # @param [Git::Base] git_repo
418
- # A git object representing the local repository againt which the push is to be made.
419
- # @param [String] template_ref
420
- # The unique reference that that represents the template the update has ran against.
421
- # @param [String] repo_name
422
- # The name of the repository on which the commit is to be made.
423
- def self.push_staged_files(git_repo, current_branch, repo_name)
424
- git_repo.push(@push_file_destination, current_branch)
425
- rescue StandardError => error
426
- puts "(FAILURE) Pushing to #{@push_file_destination} for #{repo_name} has failed. #{error}".red
427
- end
357
+ if steps.include?(:add_platform_to_metadata)
358
+ Utils.add_platform_to_metadata(output_path, module_args[:os], module_args[:version])
359
+ end
428
360
 
429
- # @summary
430
- # This method when called will create a pr on the given repository that will create a pr to merge the given commit into the master with the pdk version as an identifier.
431
- # @param [PdkSync::GitPlatformClient] client
432
- # The Git platform client used to gain access to and manipulate the repository.
433
- # @param [String] repo_name
434
- # The name of the repository on which the commit is to be made.
435
- # @param [String] template_ref
436
- # The unique reference that that represents the template the update has ran against.
437
- # @param [String] pdk_version
438
- # The current version of the pdk on which the update is run.
439
- def self.create_pr(client, repo_name, template_ref, pdk_version, pr_title = nil)
440
- if pr_title.nil?
441
- title = "pdksync - Update using #{pdk_version}"
442
- message = "pdk version: `#{pdk_version}` \n pdk template ref: `#{template_ref}`"
443
- head = "pdksync_#{template_ref}"
444
- else
445
- title = "pdksync - #{pr_title}"
446
- message = "#{pr_title}\npdk version: `#{pdk_version}` \n"
447
- head = template_ref
448
- end
449
- pr = client.create_pull_request(repo_name, @create_pr_against,
450
- head,
451
- title,
452
- message)
453
- pr
454
- rescue StandardError => error
455
- puts "(FAILURE) PR creation for #{repo_name} has failed. #{error}".red
456
- end
361
+ if steps.include?(:update_requirements)
362
+ Utils.update_requirements(output_path, module_args[:name], module_args[:key], module_args[:value])
363
+ end
457
364
 
458
- # @summary
459
- # This method when called will check on the given repository for the existence of the supplied label
460
- # @param [PdkSync::GitPlatformClient] client
461
- # The Git platform client used to gain access to and manipulate the repository.
462
- # @param [String] repo_name
463
- # The name of the repository on which the commit is to be made.
464
- # @param [String] label
465
- # The label to check for.
466
- # @return [Boolean]
467
- # A boolean stating whether the label was found.
468
- def self.check_for_label(client, repo_name, label)
469
- # Get labels from repository
470
- repo_labels = client.labels(repo_name)
365
+ if steps.include?(:normalize_metadata_supported_platforms)
366
+ Utils.normalize_metadata_supported_platforms(output_path)
367
+ end
471
368
 
472
- # Look for label in the repository's labels
473
- match = false
474
- repo_labels.each do |repo_label|
475
- if repo_label.name == label
476
- match = true
477
- break
369
+ PdkSync::Logger.info 'done'
478
370
  end
371
+ table = Terminal::Table.new title: 'Module Test Results', headings: %w[Module Status Result From], rows: report_rows
372
+ puts table if steps.include?(:fetch_test_results_locally)
373
+ return if pr_list.size.zero?
374
+ PdkSync::Logger.info "\nPRs created:\n"
375
+ puts pr_list.join("\n")
479
376
  end
480
-
481
- # Raise error if a match was not found else return true
482
- (match == false) ? (raise StandardError, "Label '#{label}' not found in #{repo_name}") : (return true)
483
- rescue StandardError => error
484
- puts "(FAILURE) Retrieving labels for #{repo_name} has failed. #{error}".red
485
- return false
486
- end
487
-
488
- # @summary
489
- # This method when called will add a given label to a given repository
490
- # @param [PdkSync::GitPlatformClient] client
491
- # The Git Platform client used to gain access to and manipulate the repository.
492
- # @param [String] repo_name
493
- # The name of the repository on which the commit is to be made.
494
- # @param [Integer] issue_number
495
- # The id of the issue (i.e. pull request) to add the label to.
496
- # @param [String] label
497
- # The label to add.
498
- def self.add_label(client, repo_name, issue_number, label)
499
- client.update_issue(repo_name, issue_number, labels: [label])
500
- rescue StandardError => error
501
- puts "(FAILURE) Adding label to #{repo_name} issue #{issue_number} has failed. #{error}".red
502
- return false
503
- end
504
-
505
- # @summary
506
- # This method when called will delete any preexisting branch on the given repository that matches the given name.
507
- # @param [PdkSync::GitPlatformClient] client
508
- # The Git platform client used to gain access to and manipulate the repository.
509
- # @param [String] repo_name
510
- # The name of the repository from which the branch is to be deleted.
511
- # @param [String] branch_name
512
- # The name of the branch that is to be deleted.
513
- def self.delete_branch(client, repo_name, branch_name)
514
- client.delete_branch(repo_name, branch_name)
515
- rescue StandardError => error
516
- puts "(FAILURE) Deleting #{branch_name} in #{repo_name} failed. #{error}".red
517
377
  end
518
378
  end