pdksync 0.2.0 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- 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