pdksync 0.5.0 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
data/Rakefile CHANGED
@@ -1,17 +1,23 @@
1
- require 'pdksync/rake_tasks'
2
- require 'github_changelog_generator/task'
3
- require 'rubocop/rake_task'
1
+ require "pdksync/rake_tasks"
2
+ require "github_changelog_generator/task"
3
+ require "rubocop/rake_task"
4
+ require "rspec/core/rake_task"
5
+ require "bundler/gem_tasks"
4
6
 
5
7
  RuboCop::RakeTask.new(:rubocop) do |t|
6
- t.options = ['--display-cop-names']
8
+ t.options = ["--display-cop-names"]
7
9
  end
8
10
 
11
+ RSpec::Core::RakeTask.new(:spec)
12
+
13
+ task :default => :spec
14
+
9
15
  GitHubChangelogGenerator::RakeTask.new :changelog do |config|
10
- config.user = 'puppetlabs'
11
- config.project = 'pdksync'
16
+ config.user = "puppetlabs"
17
+ config.project = "pdksync"
12
18
  # config.since_tag = '1.1.1'
13
- config.future_release = '0.5.0'
14
- config.exclude_labels = ['maintenance']
19
+ config.future_release = "0.6.0"
20
+ config.exclude_labels = ["maintenance"]
15
21
  config.header = "# Change log\n\nAll notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) and this project adheres to [Semantic Versioning](http://semver.org)."
16
22
  config.add_pr_wo_labels = true
17
23
  config.issues = false
data/lib/pdksync.rb CHANGED
@@ -4,59 +4,45 @@ 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
12
  require 'colorize'
12
13
  require 'bundler'
13
14
  require 'octokit'
15
+ require 'pdk/util/template_uri'
16
+ require 'pdksync/logger'
17
+ require 'pdksync/utils'
18
+ require 'terminal-table'
14
19
 
15
20
  # @summary
16
21
  # 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
22
  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
- }
23
+ def self.configuration
24
+ @configuration ||= PdkSync::Configuration.new
25
+ end
26
+
27
+ @main_path = Dir.pwd
28
+
29
+ def self.client
30
+ @client ||= Utils.setup_client
31
+ end
51
32
 
52
33
  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)
34
+ Utils.check_pdk_version if ENV['PDKSYNC_VERSION_CHECK'].eql?('true')
35
+ Utils.create_filespace
36
+ Utils.create_filespace_gem
37
+ module_names = Utils.return_modules
38
+
39
+ unless steps.include?(:clone_gem) || steps.include?(:multi_gem_testing)
40
+ raise "No modules found in '#{Utils.configuration.managed_modules}'" if module_names.nil?
41
+ end
42
+
59
43
  pr_list = []
44
+ report_rows = []
45
+ table = Terminal::Table.new
60
46
 
61
47
  # The current directory is saved for cleanup purposes
62
48
  main_path = Dir.pwd
@@ -64,455 +50,330 @@ module PdkSync
64
50
  # validation run_a_command
65
51
  if steps.include?(:run_a_command)
66
52
  raise '"run_a_command" requires an argument to run.' if args.nil?
67
- puts "Command '#{args}'"
53
+ PdkSync::Logger.info "Command '#{args}'"
68
54
  end
69
55
  # validation create_commit
70
56
  if steps.include?(:create_commit)
71
57
  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]}"
58
+ PdkSync::Logger.info "Commit branch_name=#{args[:branch_name]} commit_message=#{args[:commit_message]}"
73
59
  end
74
60
  # validation create_pr
75
61
  if steps.include?(:create_pr)
76
62
  raise 'Needs a pr_title' if args.nil? || args[:pr_title].nil?
77
- puts "PR title =#{args[:additional_title]} #{args[:pr_title]}"
63
+ PdkSync::Logger.info "PR title =#{args[:additional_title]} #{args[:pr_title]}"
78
64
  end
79
65
  # validation clean_branches
80
66
  if steps.include?(:clean_branches)
81
67
  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]}"
68
+ PdkSync::Logger.info "Removing branch_name =#{args[:branch_name]}"
69
+ end
70
+ # validation clone_gem
71
+ if steps.include?(:clone_gem)
72
+ raise 'Needs a gem_name' if args.nil? || args[:gem_name].nil?
73
+ PdkSync::Logger.info "Command '#{args}'"
74
+ end
75
+ # validation multi_gem_testing
76
+ if steps.include?(:multi_gem_testing)
77
+ raise '"multi_gem_testing" requires arguments to run version_file and build_gem.' if args.nil? || args[:version_file].nil? || args[:build_gem].nil?
78
+ puts "Command '#{args}'"
79
+ end
80
+ # validation multi_gem_file_update
81
+ if steps.include?(:multigem_file_update)
82
+ raise 'multigem_file_update requires arguments gem_to_test, gemfury_username to run.' if args[:gem_name].nil? || args[:gemfury_username].nil?
83
+ puts "Command '#{args}'"
84
+ end
85
+ # validation gem_file_update
86
+ if steps.include?(:gem_file_update)
87
+ raise '"gem_file_update" requires arguments (gem_to_test) to run.' if args[:gem_to_test].nil?
88
+ puts "Command '#{args}'"
89
+ end
90
+ # validation run_tests_locally
91
+ if steps.include?(:run_tests_locally)
92
+ puts "Command '#{args}'"
93
+ end
94
+ # validation fetch_test_results_locally
95
+ if steps.include?(:fetch_test_results_locally)
96
+ puts "Command '#{args}'"
97
+ end
98
+ # validation run_tests_jenkins
99
+ if steps.include?(:run_tests_jenkins)
100
+ raise 'run_tests_jenkins requires arguments (jenkins_server_url, github_branch) to run.' if args[:github_branch].nil? || args[:jenkins_server_url].nil?
101
+ puts "Command '#{args}'"
102
+ end
103
+ # validation test_results_jenkins
104
+ if steps.include?(:test_results_jenkins)
105
+ raise 'test_results_jenkins requires argument jenkins_server_url to run.' if args[:jenkins_server_url].nil?
106
+ puts "Command '#{args}'"
83
107
  end
84
108
 
85
- abort "No modules listed in #{@managed_modules}" if module_names.nil?
86
- module_names.each do |module_name|
87
- module_args = args.clone
109
+ unless steps.include?(:clone_gem) || steps.include?(:multi_gem_testing)
110
+ abort "No modules listed in #{Utils.configuration.managed_modules}" if module_names.nil?
111
+ end
112
+
113
+ if steps.include?(:clone_gem) || steps.include?(:multi_gem_testing)
114
+ gem_args = args.clone
88
115
  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?
116
+ PdkSync::Logger.info "#{gem_args[:gem_name]}, "
117
+ output_path = File.join(Utils.configuration.pdksync_gem_dir, gem_args[:gem_name])
118
+ if steps.include?(:clone_gem)
119
+ Utils.clean_env(output_path) if Dir.exist?(output_path)
120
+ PdkSync::Logger.info 'delete gem directory, '
121
+ @git_repo = Utils.clone_directory(Utils.configuration.namespace, gem_args[:gem_name], output_path)
122
+ PdkSync::Logger.info 'cloned'
123
+ PdkSync::Logger.error "Unable to clone repo for #{gem_args[:gem_name]}".red if @git_repo.nil?
98
124
  Dir.chdir(main_path) unless Dir.pwd == main_path
99
- next if @git_repo.nil?
100
125
  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)
126
+ puts '(WARNING) @output_path does not exist, gem'.red unless File.directory?(output_path)
127
+ if steps.include?(:multi_gem_testing)
109
128
  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)
129
+ PdkSync::Logger.info 'Multi Gem Testing, '
130
+ current_gem_version = Utils.check_gem_latest_version(gem_args[:gem_name])
131
+ PdkSync::Logger.info current_gem_version
132
+ new_gem_version = Utils.update_gem_latest_version_by_one(current_gem_version)
133
+ PdkSync::Logger.info new_gem_version
115
134
  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)
135
+ exit_status = Utils.run_command(output_path, "sed s/#{current_gem_version}/#{new_gem_version}/g #{gem_args[:version_file]} >> test.yml", nil)
136
+ PdkSync::Logger.info 'Updated the version'
121
137
  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)
138
+ exit_status = Utils.run_command(output_path, "cp test.yml #{gem_args[:version_file]}", nil)
134
139
  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)
140
+ exit_status = Utils.run_command(output_path, 'rm -rf test.yml', nil)
141
+ PdkSync::Logger.info 'bundle install'
142
+ Dir.chdir(main_path) unless Dir.pwd == main_path
143
+ exit_status = Utils.run_command(output_path, 'bundle install', nil)
144
+ PdkSync::Logger.info 'building gem'
145
+ Dir.chdir(main_path) unless Dir.pwd == main_path
146
+ exit_status = Utils.run_command(output_path, "bundle exec #{gem_args[:build_gem]}", nil)
147
+ PdkSync::Logger.info 'uploading packages'
140
148
  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, '
149
+ Dir.chdir("#{output_path}/#{gem_args[:gem_path]}") unless Dir.pwd == output_path
150
+ gemfury_token = Utils.configuration.gemfury_access_settings
151
+ Dir.glob('*.gem') do |filename|
152
+ PdkSync::Logger.info filename
153
+ Dir.chdir(main_path) unless Dir.pwd == main_path
154
+ 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
155
  end
148
156
  end
149
- if steps.include?(:create_pr)
157
+ else
158
+ module_names.each do |module_name|
159
+ module_args = args.clone
150
160
  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'
161
+ PdkSync::Logger.info "#{module_name}, "
162
+ repo_name = File.join(Utils.configuration.namespace, module_name)
163
+ output_path = File.join(Utils.configuration.pdksync_dir, module_name)
164
+ if steps.include?(:clone)
165
+ Utils.validate_modules_exist(client, module_names)
166
+ Utils.clean_env(output_path) if Dir.exist?(output_path)
167
+ PdkSync::Logger.info 'delete module directory'
168
+ @git_repo = Utils.clone_directory(Utils.configuration.namespace, module_name, output_path)
169
+ PdkSync::Logger.info 'cloned'
170
+ PdkSync::Logger.error "Unable to clone repo for #{module_name}" if @git_repo.nil?
171
+ Dir.chdir(main_path) unless Dir.pwd == main_path
172
+ next if @git_repo.nil?
173
+ end
174
+ PdkSync::Logger.warn "#{output_path} does not exist, skipping module" unless File.directory?(output_path)
175
+ next unless File.directory?(output_path)
176
+ if steps.include?(:pdk_convert)
177
+ exit_status = Utils.run_command(output_path, "#{Utils.return_pdk_path} convert --force #{configuration.templates}", nil)
178
+ PdkSync::Logger.info 'converted'
179
+ next unless exit_status.zero?
180
+ end
181
+ if steps.include?(:pdk_validate)
182
+ Dir.chdir(main_path) unless Dir.pwd == main_path
183
+ exit_status = Utils.run_command(output_path, "#{Utils.return_pdk_path} validate -a", nil)
184
+ PdkSync::Logger.info 'validated' if exit_status.zero?
185
+ next unless exit_status.zero?
186
+ end
187
+ if steps.include?(:run_a_command)
188
+ Dir.chdir(main_path) unless Dir.pwd == main_path
189
+ PdkSync::Logger.info 'run command'
190
+ if module_args[:option].nil?
191
+ pid = Utils.run_command(output_path, module_args[:command], module_args[:option])
192
+ next unless pid != 0 # rubocop:disable Metrics/BlockNesting
193
+ else
194
+ exit_status = Utils.run_command(output_path, module_args[:command], nil)
195
+ next unless exit_status.zero? # rubocop:disable Metrics/BlockNesting
162
196
  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
197
+ end
198
+ if steps.include?(:gem_file_update)
199
+ Dir.chdir(main_path) unless Dir.pwd == main_path
200
+ print 'gem file update, '
201
+ 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
202
+ print 'gem file updated, '
203
+ end
204
+ if steps.include?(:run_tests_locally)
205
+ Dir.chdir(main_path) unless Dir.pwd == main_path
206
+ PdkSync::Logger.info 'Run tests '
207
+ module_type = Utils.module_type(output_path, module_name)
208
+ Utils.run_tests_locally(output_path, module_type, module_args[:provision_type], module_name, module_args[:puppet_collection])
209
+ end
210
+ if steps.include?(:fetch_test_results_locally)
211
+ Dir.chdir(main_path) unless Dir.pwd == main_path
212
+ PdkSync::Logger.info 'Fetch test results for local run '
213
+ module_type = Utils.module_type(output_path, module_name)
214
+ table = Utils.fetch_test_results_locally(output_path, module_type, module_name, report_rows)
215
+ end
216
+ if steps.include?(:pdk_update)
217
+ Dir.chdir(main_path) unless Dir.pwd == main_path
218
+ next unless Utils.pdk_update(output_path).zero?
219
+ if steps.include?(:use_pdk_ref)
220
+ ref = Utils.return_template_ref(File.join(output_path, 'metadata.json'))
221
+ pr_title = module_args[:additional_title] ? "#{module_args[:additional_title]} - pdksync_#{ref}" : "pdksync_#{ref}" # rubocop:disable Metrics/BlockNesting
222
+ module_args = module_args.merge(branch_name: "pdksync_#{ref}",
223
+ commit_message: pr_title,
224
+ pr_title: pr_title,
225
+ pdksync_label: Utils.configuration.default_pdksync_label)
168
226
  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}' "
227
+ PdkSync::Logger.info 'pdk update'
228
+ end
229
+ if steps.include?(:use_gem_ref)
230
+ pr_title = module_args[:additional_title] ? "#{module_args[:additional_title]} - pdksync_gem_testing" : 'pdksync_gem_testing'
231
+ module_args = module_args.merge(branch_name: "gem_testing_#{module_args[:gem_to_test]}",
232
+ commit_message: pr_title,
233
+ pr_title: pr_title,
234
+ pdksync_label: Utils.configuration.default_pdksync_label)
235
+ end
236
+ if steps.include?(:create_commit)
237
+ Dir.chdir(main_path) unless Dir.pwd == main_path
238
+ git_instance = Git.open(output_path)
239
+ Utils.create_commit(git_instance, module_args[:branch_name], module_args[:commit_message])
240
+ PdkSync::Logger.info 'commit created'
241
+ end
242
+ if steps.include?(:push)
243
+ Dir.chdir(main_path) unless Dir.pwd == main_path
244
+ git_instance = Git.open(output_path)
245
+ 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
246
+ PdkSync::Logger.info 'push'
247
+ Utils.push_staged_files(git_instance, git_instance.current_branch, repo_name)
248
+ else
249
+ PdkSync::Logger.info 'skipped push'
177
250
  end
178
- else
179
- print 'skipped pr, '
180
251
  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
252
+ if steps.include?(:create_pr)
253
+ Dir.chdir(main_path) unless Dir.pwd == main_path
254
+ git_instance = Git.open(output_path)
255
+ 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
256
+ pdk_version = Utils.return_pdk_version("#{output_path}/metadata.json")
257
+
258
+ # If a label is supplied, verify that it is available in the repo
259
+ label = module_args[:pdksync_label] ? module_args[:pdksync_label] : module_args[:label] # rubocop:disable Metrics/BlockNesting
260
+ label_valid = (label.is_a?(String) && !label.to_str.empty?) ? Utils.check_for_label(client, repo_name, label) : nil # rubocop:disable Metrics/BlockNesting
261
+
262
+ # Exit current iteration if an error occured retrieving a label
263
+ if label_valid == false # rubocop:disable Metrics/BlockNesting
264
+ raise 'Ensure label is valid'
265
+ end
266
+
267
+ # Create the PR and add link to pr list
268
+ pr = Utils.create_pr(client, repo_name, git_instance.current_branch, pdk_version, module_args[:pr_title])
269
+ break if pr.nil? # rubocop:disable Metrics/BlockNesting
270
+
271
+ pr_list.push(pr.html_url)
272
+ PdkSync::Logger.info 'created pr'
273
+
274
+ # If a valid label is supplied, add this to the PR
275
+ if label_valid == true # rubocop:disable Metrics/BlockNesting
276
+ Utils.add_label(client, repo_name, pr.number, label)
277
+ PdkSync::Logger.info "added label '#{label}' "
278
+ end
279
+ else
280
+ PdkSync::Logger.info 'skipped pr'
281
+ end
282
+ end
283
+ if steps.include?(:clean_branches)
284
+ Dir.chdir(main_path) unless Dir.pwd == main_path
285
+ Utils.delete_branch(client, repo_name, module_args[:branch_name])
286
+ PdkSync::Logger.info 'branch deleted'
287
+ end
288
+ if steps.include?(:run_tests_jenkins)
289
+ jenkins_client = Utils.setup_jenkins_client(module_args[:jenkins_server_url])
290
+ Dir.chdir(main_path) unless Dir.pwd == main_path
291
+ PdkSync::Logger.info 'Run tests in jenkins '
292
+ module_type = Utils.module_type(output_path, module_name)
293
+ if module_type == 'traditional'
294
+ github_user = 'puppetlabs' if module_args[:test_framework].nil? # rubocop:disable Metrics/BlockNesting
295
+ github_user = module_args[:github_user] unless module_args[:github_user].nil? # rubocop:disable Metrics/BlockNesting
296
+ if module_args[:test_framework] == 'jenkins' || module_args[:test_framework].nil? # rubocop:disable Metrics/BlockNesting
297
+ module_name = "puppetlabs-#{module_name}" if %w[cisco_ios device_manager].include?(module_name) # rubocop:disable Metrics/BlockNesting
298
+ job_name = "forge-module_#{module_name}_init-manual-parameters_adhoc"
299
+ 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
300
+ build_id = Utils.run_tests_jenkins(jenkins_client, module_name, module_args[:github_branch], github_user, job_name)
301
+ next if build_id.nil? # rubocop:disable Metrics/BlockNesting
302
+ PdkSync::Logger.info "New adhoc TEST EXECUTION has started. \nYou can check progress here: #{configuration['jenkins_server_url']}/job/#{job_name}/#{build_id}"
303
+ Utils.test_results_jenkins(module_args[:jenkins_server_url], build_id, job_name, module_name)
304
+ end
305
+ end
306
+ if module_type == 'litmus'
307
+ PdkSync::Logger.info '(Error) Module Type is Litmus please use the rake task run_tests_locally to run'.red
308
+ end
309
+ end
310
+ if steps.include?(:test_results_jenkins)
311
+ Dir.chdir(main_path) unless Dir.pwd == main_path
312
+ PdkSync::Logger.info 'Fetch test results from jenkins, '
313
+ module_type = Utils.module_type(output_path, module_name)
314
+ if module_type == 'litmus'
315
+ PdkSync::Logger.info '(Error) Module Type is Litmus please use the rake task run_tests_locally to run'.red
316
+ next
317
+ end
334
318
 
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
319
+ module_name = "puppetlabs-#{module_name}" if %w[cisco_ios device_manager].include?(module_name)
320
+ File.open("results_#{module_name}.out", 'r') do |f|
321
+ f.each_line do |line|
322
+ if line.include?('BUILD_ID')
323
+ build_id = line.split('=')[1].strip
324
+ elsif line.include?('MODULE_NAME')
325
+ module_name = line.split('=')[1].strip
326
+ end
327
+ end
348
328
 
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
329
+ job_name = "forge-module_#{module_name}_init-manual-parameters_adhoc" if module_args[:job_name].nil?
330
+ job_name = "forge-windows_#{module_name}_init-manual-parameters_adhoc" if ['puppetlabs-reboot', 'puppetlabs-iis', 'puppetlabs-powershell', 'sqlserver'].include?(module_name)
331
+ Utils.test_results_jenkins(module_args[:jenkins_server_url], build_id, job_name, module_name)
332
+ end
333
+ end
334
+ if steps.include?(:multigem_file_update)
335
+ Dir.chdir(main_path) unless Dir.pwd == main_path
336
+ gemfury_readonly_token = Utils.configuration.gemfury_access_settings
337
+ Utils.update_gemfile_multigem(output_path, module_args[:gem_name], gemfury_readonly_token, module_args[:gemfury_username])
338
+ PdkSync::Logger.info 'Updated with multigem, '
339
+ end
360
340
 
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
341
+ if steps.include?(:add_provision_list)
342
+ result = Utils.add_provision_list(output_path, module_args[:key], module_args[:provisioner], [module_args[:images], module_args.extras].flatten)
343
+ raise "#{output_path}/provision.yaml does not exist" unless result
344
+ end
370
345
 
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
346
+ if steps.include?(:generate_vmpooler_release_checks)
347
+ Utils.generate_vmpooler_release_checks(output_path, module_args[:puppet_version].to_i)
348
+ end
382
349
 
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
350
+ if steps.include?(:update_os_support)
351
+ Utils.update_os_support(output_path)
352
+ end
397
353
 
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
354
+ if steps.include?(:remove_platform_from_metadata)
355
+ Utils.remove_platform_from_metadata(output_path, module_args[:os], module_args[:version])
356
+ end
414
357
 
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
358
+ if steps.include?(:add_platform_to_metadata)
359
+ Utils.add_platform_to_metadata(output_path, module_args[:os], module_args[:version])
360
+ end
428
361
 
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
362
+ if steps.include?(:update_requirements)
363
+ Utils.update_requirements(output_path, module_args[:name], module_args[:key], module_args[:value])
364
+ end
457
365
 
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)
366
+ if steps.include?(:normalize_metadata_supported_platforms)
367
+ Utils.normalize_metadata_supported_platforms(output_path)
368
+ end
471
369
 
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
370
+ PdkSync::Logger.info 'done'
478
371
  end
372
+ table = Terminal::Table.new title: 'Module Test Results', headings: %w[Module Status Result From], rows: report_rows
373
+ puts table if steps.include?(:fetch_test_results_locally)
374
+ return if pr_list.size.zero?
375
+ PdkSync::Logger.info "\nPRs created:\n"
376
+ puts pr_list.join("\n")
479
377
  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
378
  end
518
379
  end