pdksync 0.2.0 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA256:
3
- metadata.gz: 1ddb56d6bd4366f686243b4d773083709f966726caf0d2fd580aba1e9373c890
4
- data.tar.gz: 34063f7b4a545f18f89c58b260061ffb93575b7f15ad932cb8ddeb9ed50ea209
2
+ SHA1:
3
+ metadata.gz: dcb6ea51b43a295e28ab7a3bb90ccf3d398ccdbd
4
+ data.tar.gz: f214afd41acd5fc6bba7557e3ce79230a8e1dde8
5
5
  SHA512:
6
- metadata.gz: 027c7bf9b6d2482631119390863bccc0295a4c8737ef3e741a793cf163f57a726be46a99fb116d43055deeab3f69420ee88065878e8d58df637d0536e57055a1
7
- data.tar.gz: 25b0cec819fb71ee5030e3a357deacb8ce219bd81323bf33e861b3cd5b456bd9dacf2f6993e32e52fadcdcd298ea530d439eb1093aa9d21667a2a18b03abc66b
6
+ metadata.gz: 69ee152722be2fa9a862727de092981c1c9855a44c36e5b1033b22a4883585a0ef8596fa666ca8d65443ae2fec3244c16b590e7d034a479ba83e30baf3773ee5
7
+ data.tar.gz: 542e70e07027ad294e99d5d0933b36e586feed3bd55c3036edef2eb26832eea3cb8324d7ff50297be69eb01e78dd7dabd376679097e4a0686a83f45696c194d8
@@ -2,9 +2,22 @@
2
2
 
3
3
  All 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).
4
4
 
5
- ## [0.2.0](https://github.com/puppetlabs/pdksync/tree/0.1.0) (2018-11-02)
5
+ ## [0.3.0](https://github.com/puppetlabs/pdksync/tree/0.3.0) (2018-11-15)
6
6
 
7
- [Full Changelog](https://github.com/puppetlabs/pdksync/compare/0.1.0...0.1.0)
7
+ [Full Changelog](https://github.com/puppetlabs/pdksync/compare/0.2.0...0.3.0)
8
+
9
+ ### Added
10
+
11
+ - \(MODULES-8231\) - Add additional title info for pdksync runs [\#76](https://github.com/puppetlabs/pdksync/pull/76) ([eimlav](https://github.com/eimlav))
12
+ - \(MODULES-7695\) - Add maintenance labels for PRs [\#75](https://github.com/puppetlabs/pdksync/pull/75) ([eimlav](https://github.com/eimlav))
13
+
14
+ ### Fixed
15
+
16
+ - \(MODULES-8002\) - Fix bundle commands not running in correct dir [\#79](https://github.com/puppetlabs/pdksync/pull/79) ([eimlav](https://github.com/eimlav))
17
+
18
+ ## [0.2.0](https://github.com/puppetlabs/pdksync/tree/0.2.0) (2018-11-02)
19
+
20
+ [Full Changelog](https://github.com/puppetlabs/pdksync/compare/0.1.0...0.2.0)
8
21
 
9
22
  ### Added
10
23
 
data/README.md CHANGED
@@ -41,6 +41,20 @@ Pdksync is a gem that works to clone, update, and push module repositories. It i
41
41
 
42
42
  The gem takes in a file, `managed_modules.yml`, stored within the gem that lists all the repositories that need to be updated. It then clones them, one after another, so that a local copy exists. The update command is ran against this local copy, with the subsequent changes being added into a commit on a unique branch. It is then pushed back to the remote master — where the local copy was originally cloned. The commit is merged to the master via a pull request, causing the gem to begin to clone the next repository.
43
43
 
44
+ By default, pdksync will supply a label to a PR (default is 'maintenance'). This can be changed by opening `lib/pdksync/constants.rb` and modifying the `PDKSYNC_LABEL` constant. You must ensure that the label selected exists on the modules that you are applying pdksync to. Should you wish to disable this feature, simply change `PDKSYNC_LABEL` to an empty string i.e. ''. Similarly, when supplying a label using the `git:push_and_create_pr` rake task, the label must exist on each of the managed modules to run successfully.
45
+
46
+ The following rake tasks are available with pdksync:
47
+ - `git:clone_managed_modules` Clone managed modules.
48
+ - `git:create_commit[:branch_name, :commit_message]` Stage commits for modules, branchname and commit message eg rake 'git:create_commit[flippity, commit messagez]'.
49
+ - `git:push_and_create_pr[:pr_title, :label]` Push commit, and create PR for modules. Label is optional eg rake 'git:push_and_create_pr[pr title goes here, optional label right here]'.
50
+ - `git:clean[:branch_name]` Clean up origin branches, (branches must include pdksync in their name) eg rake 'git:clean[pdksync_origin_branch]'.
51
+ - `pdk:pdk_convert` Runs PDK convert against modules.
52
+ - `pdk:pdk_validate` Runs PDK validate against modules.
53
+ - `pdksync[:additional_title]` Run full pdksync process, clone repository, pdk update, create pr. Additional information can be added to the title, which will be appended before the reference section.
54
+ - `rake pdksync` PR title outputs as `pdksync - pdksync_heads/master-0-gabccfb1`
55
+ - `rake 'pdksync[MODULES-8231]'` PR title outputs as `pdksync - MODULES-8231 - pdksync_heads/master-0-gabccfb1`
56
+ - `run_a_command[:command]` Run a command against modules eg rake 'run_a_command[complex command here -f -gx]'
57
+
44
58
  ### Workflow
45
59
  --------
46
60
 
data/Rakefile CHANGED
@@ -1,11 +1,12 @@
1
1
  require_relative 'lib/pdksync'
2
2
  require 'github_changelog_generator/task'
3
3
 
4
- desc 'Run full pdksync process, clone repository, pdk update, create pr.'
5
- task :pdksync do
6
- args = {:branch_name => "pdksync_{ref}",
7
- :commit_message => "pdksync_{ref}",
8
- :pr_title => "pdksync_{ref}"}
4
+ desc 'Run full pdksync process, clone repository, pdk update, create pr. Additional title information can be added to the title, which will be appended before the reference section.'
5
+ task :pdksync, [:additional_title] do |task, args|
6
+ args = {:branch_name => "pdksync_{ref}",
7
+ :commit_message => "pdksync_{ref}",
8
+ :pr_title => "pdksync_{ref}",
9
+ :additional_title => args[:additional_title]}
9
10
  PdkSync::main(steps: [:use_pdk_ref, :clone, :pdk_update, :create_commit, :push_and_create_pr], args: args)
10
11
  end
11
12
 
@@ -32,8 +33,8 @@ namespace :git do
32
33
  PdkSync::main(steps: [:create_commit], args: args)
33
34
  end
34
35
 
35
- desc "Push commit, and create PR for modules eg rake 'git:push_and_create_pr[pr title goes here]'"
36
- task :push_and_create_pr, [:pr_title] do |task, args|
36
+ desc "Push commit, and create PR for modules eg rake 'git:push_and_create_pr[pr title goes here, optional label right here]'"
37
+ task :push_and_create_pr, [:pr_title, :label] do |task, args|
37
38
  PdkSync::main(steps: [:push_and_create_pr], args: args)
38
39
  end
39
40
 
@@ -52,7 +53,7 @@ GitHubChangelogGenerator::RakeTask.new :changelog do |config|
52
53
  config.user = 'puppetlabs'
53
54
  config.project = 'pdksync'
54
55
  # config.since_tag = '1.1.1'
55
- config.future_release = '0.1.0'
56
+ config.future_release = '0.3.0'
56
57
  config.exclude_labels = ['maintenance']
57
58
  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)."
58
59
  config.add_pr_wo_labels = true
@@ -9,6 +9,7 @@ require 'pdksync/constants'
9
9
  require 'json'
10
10
  require 'yaml'
11
11
  require 'colorize'
12
+ require 'bundler'
12
13
 
13
14
  # @summary
14
15
  # This module set's out and controls the pdksync process
@@ -32,12 +33,16 @@ module PdkSync
32
33
  @push_file_destination = Constants::PUSH_FILE_DESTINATION
33
34
  @create_pr_against = Constants::CREATE_PR_AGAINST
34
35
  @managed_modules = Constants::MANAGED_MODULES
36
+ @default_pdksync_label = Constants::PDKSYNC_LABEL
35
37
 
36
38
  def self.main(steps: [:clone], args: nil)
37
39
  create_filespace
38
40
  client = setup_client
39
41
  module_names = return_modules
42
+ raise "No modules found in '#{@managed_modules}'" if module_names.nil?
43
+ validate_modules_exist(module_names)
40
44
  pr_list = []
45
+
41
46
  # The current directory is saved for cleanup purposes
42
47
  main_path = Dir.pwd
43
48
 
@@ -101,9 +106,11 @@ module PdkSync
101
106
  next unless pdk_update(output_path).zero?
102
107
  if steps.include?(:use_pdk_ref)
103
108
  ref = return_template_ref
109
+ pr_title = args[:additional_title] ? "#{args[:additional_title]} - pdksync_#{ref}" : "pdksync_#{ref}"
104
110
  args = { branch_name: "pdksync_#{ref}",
105
111
  commit_message: "pdksync_#{ref}",
106
- pr_title: "pdksync_#{ref}" }
112
+ pr_title: pr_title,
113
+ pdksync_label: @default_pdksync_label }
107
114
  end
108
115
  print 'pdk update, '
109
116
  end
@@ -119,9 +126,30 @@ module PdkSync
119
126
  push_staged_files(git_instance, git_instance.current_branch, repo_name)
120
127
  print 'push, '
121
128
  pdk_version = return_pdk_version("#{output_path}/metadata.json")
129
+
130
+ # If a label is supplied, verify that it is available in the repo
131
+ label = args[:pdksync_label] ? args[:pdksync_label] : args[:label]
132
+ label_valid = (label.is_a?(String) && !label.to_str.empty?) ? check_for_label(client, repo_name, label) : nil
133
+
134
+ # Exit current iteration if an error occured retrieving a label
135
+ if label_valid == false
136
+ raise 'Ensure label is valid'
137
+ end
138
+
139
+ # Create the PR and add link to pr list
122
140
  pr = create_pr(client, repo_name, git_instance.current_branch, pdk_version, args[:pr_title])
141
+ if pr.nil?
142
+ break
143
+ end
144
+
123
145
  pr_list.push(pr.html_url)
124
146
  print 'created pr, '
147
+
148
+ # If a valid label is supplied, add this to the PR
149
+ if label_valid == true
150
+ add_label(client, repo_name, pr.number, label)
151
+ print "added label '#{label}' "
152
+ end
125
153
  end
126
154
  if steps.include?(:clean_branches)
127
155
  Dir.chdir(main_path) unless Dir.pwd == main_path
@@ -160,9 +188,27 @@ module PdkSync
160
188
  # @return [Array]
161
189
  # An array of different module names.
162
190
  def self.return_modules
191
+ raise "File '#{@managed_modules}' is empty/does not exist" if File.size?(@managed_modules).nil?
163
192
  YAML.safe_load(File.open(@managed_modules))
164
193
  end
165
194
 
195
+ # @summary
196
+ # This method when called will parse an array of module names and verify whether they are valid GitHub repo names
197
+ # @param [Array] module_names
198
+ # String array of the names of GitHub repos
199
+ def self.validate_modules_exist(module_names)
200
+ invalid_names = []
201
+ module_names.each do |module_name|
202
+ # If module name is invalid, push it to invalid names array
203
+ unless Octokit.repository?("#{@namespace}/#{module_name}")
204
+ invalid_names.push(module_name)
205
+ next
206
+ end
207
+ end
208
+ # Raise error if any invalid matches were found
209
+ raise "Could not find the following repositories: #{invalid_names}" unless invalid_names.empty?
210
+ end
211
+
166
212
  # @summary
167
213
  # Try to use a fully installed pdk, otherwise fall back to the bundled pdk gem.
168
214
  # @return String
@@ -218,8 +264,21 @@ module PdkSync
218
264
  # @return [Integer]
219
265
  # The status code of the command run.
220
266
  def self.run_command(output_path, command)
267
+ stdout = ''
268
+ stderr = ''
269
+ status = Process::Status
270
+
221
271
  Dir.chdir(output_path) unless Dir.pwd == output_path
222
- stdout, stderr, status = Open3.capture3(command)
272
+
273
+ # Environment cleanup required due to Ruby subshells using current Bundler environment
274
+ if command =~ %r{^bundle}
275
+ Bundler.with_clean_env do
276
+ stdout, stderr, status = Open3.capture3(command)
277
+ end
278
+ else
279
+ stdout, stderr, status = Open3.capture3(command)
280
+ end
281
+
223
282
  puts "\n#{stdout}\n".yellow
224
283
  puts "(FAILURE) Unable to run command '#{command}': #{stderr}".red unless status.exitstatus.zero?
225
284
  status.exitstatus
@@ -346,6 +405,53 @@ module PdkSync
346
405
  puts "(FAILURE) PR creation for #{repo_name} has failed. #{error}".red
347
406
  end
348
407
 
408
+ # @summary
409
+ # This method when called will check on the given repository for the existence of the supplied label
410
+ # @param [Octokit::Client] client
411
+ # The octokit client used to gain access to and manipulate the repository.
412
+ # @param [String] repo_name
413
+ # The name of the repository on which the commit is to be made.
414
+ # @param [String] label
415
+ # The label to check for.
416
+ # @return [Boolean]
417
+ # A boolean stating whether the label was found.
418
+ def self.check_for_label(client, repo_name, label)
419
+ # Get labels from repository
420
+ repo_labels = client.labels(repo_name)
421
+
422
+ # Look for label in the repository's labels
423
+ match = false
424
+ repo_labels.each do |repo_label|
425
+ if repo_label.name == label
426
+ match = true
427
+ break
428
+ end
429
+ end
430
+
431
+ # Raise error if a match was not found else return true
432
+ (match == false) ? (raise StandardError, "Label '#{label}' not found in #{repo_name}") : (return true)
433
+ rescue StandardError => error
434
+ puts "(FAILURE) Retrieving labels for #{repo_name} has failed. #{error}".red
435
+ return false
436
+ end
437
+
438
+ # @summary
439
+ # This method when called will add a given label to a given repository
440
+ # @param [Octokit::Client] client
441
+ # The octokit client used to gain access to and manipulate the repository.
442
+ # @param [String] repo_name
443
+ # The name of the repository on which the commit is to be made.
444
+ # @param [Integer] issue_number
445
+ # The id of the issue (i.e. pull request) to add the label to.
446
+ # @param [String] label
447
+ # The label to add.
448
+ def self.add_label(client, repo_name, issue_number, label)
449
+ client.update_issue(repo_name, issue_number, labels: [label])
450
+ rescue StandardError => error
451
+ puts "(FAILURE) Adding label to #{repo_name} issue #{issue_number} has failed. #{error}".red
452
+ return false
453
+ end
454
+
349
455
  # @summary
350
456
  # This method when called will delete any preexisting branch on the given repository that matches the given name.
351
457
  # @param [Octokit::Client] client
@@ -8,5 +8,7 @@ module PdkSync # rubocop:disable Style/ClassAndModuleChildren
8
8
  PUSH_FILE_DESTINATION = 'origin'.freeze
9
9
  CREATE_PR_AGAINST = 'master'.freeze
10
10
  MANAGED_MODULES = 'managed_modules.yml'.freeze
11
+ # Set PDKSYNC_LABEL to '' to disable adding a label during pdksync runs
12
+ PDKSYNC_LABEL = 'maintenance'.freeze
11
13
  end
12
14
  end
@@ -3,7 +3,7 @@ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
3
3
 
4
4
  Gem::Specification.new do |spec|
5
5
  spec.name = 'pdksync'
6
- spec.version = '0.2.0'
6
+ spec.version = '0.3.0'
7
7
  spec.authors = ['Puppet']
8
8
  spec.email = ['']
9
9
  spec.summary = 'Puppet Module PDK Synchronizer'
@@ -47,6 +47,9 @@ describe PdkSync do
47
47
  it 'raise when push_and_create_pr with no arguments' do
48
48
  expect { PdkSync.main(steps: [:push_and_create_pr]) }.to raise_error(RuntimeError, %r{Needs a pr_title})
49
49
  end
50
+ it 'raise when push_and_create_pr with invalid label' do
51
+ expect { PdkSync.main(steps: [:push_and_create_pr], args: { pr_title: 'My amazing PR', label: 'doot doot' }) }.to raise_error(RuntimeError, %r{Ensure label is valid})
52
+ end
50
53
  it 'raise when clean_branches with no arguments' do
51
54
  expect { PdkSync.main(steps: [:clean_branches]) }.to raise_error(RuntimeError, %r{Needs a branch_name, and the branch name contains the string pdksync})
52
55
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pdksync
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Puppet
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-11-02 00:00:00.000000000 Z
11
+ date: 2018-11-15 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -164,7 +164,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
164
164
  version: '0'
165
165
  requirements: []
166
166
  rubyforge_project:
167
- rubygems_version: 2.7.6
167
+ rubygems_version: 2.6.11
168
168
  signing_key:
169
169
  specification_version: 4
170
170
  summary: Puppet Module PDK Synchronizer