pdksync 0.3.0 → 0.4.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
- SHA1:
3
- metadata.gz: dcb6ea51b43a295e28ab7a3bb90ccf3d398ccdbd
4
- data.tar.gz: f214afd41acd5fc6bba7557e3ce79230a8e1dde8
2
+ SHA256:
3
+ metadata.gz: ab2ac9994044ffbddbbe2a6a18933d764477c2cdff17578abc2b203272c0bca0
4
+ data.tar.gz: da3644827bdad46868369dd0297ebae4dedfd15225ccf41def3aecdb5c0bfd73
5
5
  SHA512:
6
- metadata.gz: 69ee152722be2fa9a862727de092981c1c9855a44c36e5b1033b22a4883585a0ef8596fa666ca8d65443ae2fec3244c16b590e7d034a479ba83e30baf3773ee5
7
- data.tar.gz: 542e70e07027ad294e99d5d0933b36e586feed3bd55c3036edef2eb26832eea3cb8324d7ff50297be69eb01e78dd7dabd376679097e4a0686a83f45696c194d8
6
+ metadata.gz: 9d35e566ef6c5f29fdff5536721343d9c21aeedca3c3465afc4813183cc6b3ff6919687e43c63167649a6024fb711f420fbd9d604f402880eb99d32d0c1483f1
7
+ data.tar.gz: e5a4b656cc8a940d106a652b6a3818e3fc7106020b3581d192eb2d5706183a069edf59e1d6196c4aaf06c495f876bfe6c2591079abbb3e9b585196a863bf91ba
data/CHANGELOG.md CHANGED
@@ -2,9 +2,23 @@
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.3.0](https://github.com/puppetlabs/pdksync/tree/0.3.0) (2018-11-15)
5
+ ## [0.4.0](https://github.com/puppetlabs/pdksync/tree/0.4.0) (2019-02-04)
6
6
 
7
- [Full Changelog](https://github.com/puppetlabs/pdksync/compare/0.2.0...0.3.0)
7
+ [Full Changelog](https://github.com/puppetlabs/pdksync/compare/v0.3.0...0.4.0)
8
+
9
+ ### Added
10
+
11
+ - \(MODULES-8419\) Refactor to add support for GitLab [\#85](https://github.com/puppetlabs/pdksync/pull/85) ([antaflos](https://github.com/antaflos))
12
+ - \(MODULES-7233\) - Add configurable file option [\#81](https://github.com/puppetlabs/pdksync/pull/81) ([eimlav](https://github.com/eimlav))
13
+
14
+ ### Fixed
15
+
16
+ - \(MODULES-8283\) - Fix PR title overwritten in pdksync runs [\#84](https://github.com/puppetlabs/pdksync/pull/84) ([eimlav](https://github.com/eimlav))
17
+ - \(MODULES-8382\) - Fix API rate limit false positive [\#83](https://github.com/puppetlabs/pdksync/pull/83) ([eimlav](https://github.com/eimlav))
18
+
19
+ ## [v0.3.0](https://github.com/puppetlabs/pdksync/tree/v0.3.0) (2018-11-15)
20
+
21
+ [Full Changelog](https://github.com/puppetlabs/pdksync/compare/0.2.0...v0.3.0)
8
22
 
9
23
  ### Added
10
24
 
data/README.md CHANGED
@@ -6,7 +6,7 @@ Table of Contents
6
6
  1. [Overview](#overview)
7
7
  2. [Usage](#usage)
8
8
  3. [How it works](#how-it-works)
9
- 4. [Installing](#installing)
9
+ 4. [Configuration](#configuration)
10
10
  5. [Workflow](#workflow)
11
11
  6. [Migrating from modulesync to pdksync](#migrating-from-modulesync-to-pdksync)
12
12
  7. [Contributing](#contributing)
@@ -14,17 +14,26 @@ Table of Contents
14
14
  ### Overview
15
15
  --------
16
16
 
17
- Pdksync is an efficient way to run a `pdk update` command against the various repositories that we manage — keeping them up-to-date with the changes made to PDK. It is a solution for converted modules that no longer run with modulesync.
17
+ Pdksync is an efficient way to run a `pdk update` command against the various Puppet module repositories that you manage — keeping them up-to-date with the changes made to PDK. It is a solution for converted modules that no longer run with modulesync.
18
+
19
+ Pdksync by default expects that your Puppet module repositories live on GitHub and will behave accordingly. It also supports GitLab as an alternative Git hosting platform.
18
20
 
19
21
  ### Usage
20
22
  ----------
21
23
 
22
- > Note: This tool creates a 'live' pull request against the master branch of the module it is running against — defined in `managed_modules.yml`. Before running this tool, ensure this file reflects the modules you wish it to run against, and that `constants.rb` is up-to-date with the correct namespace your modules reside in.
24
+ > Note: This tool creates a 'live' pull (merge) request against the master branch of the module it is running against — defined in `managed_modules.yml`. Before running this tool, ensure this file reflects the modules you wish it to run against. Additionally make sure that the Pdksync configuration file `$HOME/.pdksync.yml` sets the correct namespace, Git platform and Git base URI for your modules. See section [Configuration](#configuration) for details.
23
25
 
24
26
  1. To use pdksync, clone the GitHub repo or install it as a gem. Set up the environment by exporting a GitHub token:
25
- ```
26
- export GITHUB_TOKEN=<access_token>
27
- ```
27
+
28
+ ```
29
+ export GITHUB_TOKEN=<access_token>
30
+ ```
31
+
32
+ If you use GitLab instead of GitHub export your GitLab access token:
33
+
34
+ ```
35
+ export GITLAB_TOKEN=<access_token>
36
+ ```
28
37
  2. Before the script will run, you need to install the gems:
29
38
  ```
30
39
  bundle install --path .bundle/gems/
@@ -41,9 +50,10 @@ Pdksync is a gem that works to clone, update, and push module repositories. It i
41
50
 
42
51
  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
52
 
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.
53
+ By default, pdksync will supply a label to a PR (default is 'maintenance'). This can be changed by creating `$HOME/.pdksync.yml` and setting the `pdksync_label` key. 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
54
 
46
55
  The following rake tasks are available with pdksync:
56
+ - `show_config` Display the current configuration of pdksync
47
57
  - `git:clone_managed_modules` Clone managed modules.
48
58
  - `git:create_commit[:branch_name, :commit_message]` Stage commits for modules, branchname and commit message eg rake 'git:create_commit[flippity, commit messagez]'.
49
59
  - `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]'.
@@ -55,10 +65,80 @@ The following rake tasks are available with pdksync:
55
65
  - `rake 'pdksync[MODULES-8231]'` PR title outputs as `pdksync - MODULES-8231 - pdksync_heads/master-0-gabccfb1`
56
66
  - `run_a_command[:command]` Run a command against modules eg rake 'run_a_command[complex command here -f -gx]'
57
67
 
68
+ ### Configuration
69
+
70
+ By default pdksync will use hardcoded values for configuring itself. However, if you wish to override these values, simply create `$HOME/.pdksync.yml` and use the following format:
71
+ ```
72
+ ---
73
+ namespace: 'puppetlabs'
74
+ pdksync_dir: 'modules_pdksync'
75
+ push_file_destination: 'origin'
76
+ create_pr_against: 'master'
77
+ managed_modules: 'managed_modules.yml'
78
+ pdksync_label: 'maintenance'
79
+ git_platform: :github
80
+ git_base_uri: 'https://github.com'
81
+ # Only used when git_platform is set to :gitlab
82
+ gitlab_api_endpoint: 'https://gitlab.com/api/v4'
83
+ ```
84
+
85
+ You may override any property. Those that are not specified in your config file will use their corresponding default value from `lib/pdksync/constants.rb`.
86
+
87
+ #### Git platform support
88
+
89
+ By default pdksync assumes you are hosting your Puppet modules on GitHub, and GitHub is the only platform officially supported by Puppetlabs in pdksync.
90
+
91
+ Pdksync also supports the GitLab platform, but without official support by Puppetlabs.
92
+
93
+ ##### GitHub
94
+
95
+ To use GitHub you only need to export your GitHub access token as the
96
+ environment variable `GITHUB_TOKEN` and configure the namespace in which your
97
+ modules are hosted in `$HOME/.pdksync.yml` as described above.
98
+
99
+ ##### GitLab
100
+
101
+ To use GitLab at `https://gitlab.com` you need to set `git_platform: :gitlab`
102
+ and configure the namespace of your modules in `$HOME/.pdksync.yml`. You also
103
+ need to export your GitLab access token as the environment variable
104
+ `GITLAB_TOKEN`.
105
+
106
+ Your `$HOME/.pdksync.yml` then looks like this:
107
+
108
+ ```
109
+ # ~/pdksync.yml
110
+ ---
111
+ namespace: 'acme'
112
+ git_platform: :gitlab
113
+ ```
114
+
115
+ Export your GitLab access token:
116
+
117
+ ```
118
+ $ export GITLAB_TOKEN=<your GitLab access token here>
119
+ ```
120
+
121
+ If you are running your own GitLab instance on premise or use a GitLab instance
122
+ other than the official one at `https://gitlab.com` you also need to configure
123
+ `git_base_uri` and `gitlab_api_endpoint` in `$HOME/.pdksync.yml` so that
124
+ pdksync knows from where to clone your modules and where to access to GitLab
125
+ API to create the live merge requests:
126
+
127
+ ```
128
+ # ~/pdksync.yml
129
+ ---
130
+ namespace: 'puppetmodules'
131
+ git_platform: :gitlab
132
+ git_base_uri: 'https://gitlab.example.com'
133
+ # alternatively use SSH:
134
+ #git_base_uri: 'ssh://git@gitlab.example.com:2222'
135
+ gitlab_api_endpoint: 'https://gitlab.example.com/api/v4'
136
+ ```
137
+
58
138
  ### Workflow
59
139
  --------
60
140
 
61
- It currently runs without additional arguments. To alter how it runs, make alterations to either the `constants.rb` or `managed_modules.yml`.
141
+ It currently runs without additional arguments. To alter how it runs, make alterations to either `HOME/.pdksync.yml` or `managed_modules.yml`.
62
142
 
63
143
  ### Managed modules
64
144
  ----------
@@ -71,7 +151,8 @@ This module runs through a pre-set array of modules, with this array set within
71
151
  - puppetlabs-stdlib
72
152
  - puppetlabs-mysql
73
153
  ```
74
- To add a module, add it to the list. To remove a module, remove it from the list.
154
+
155
+ To add a module, add it to the list. To remove a module, remove it from the list. If you wish to specify a custom managed modules file, use the `managed_modules` property in your configuration file to specify the path to the file.
75
156
 
76
157
  ### Migrating from modulesync to pdksync
77
158
  --------
data/Rakefile CHANGED
@@ -1,6 +1,24 @@
1
1
  require_relative 'lib/pdksync'
2
+ require 'colorize'
2
3
  require 'github_changelog_generator/task'
3
4
 
5
+ desc 'Display the current configuration of pdksync'
6
+ task :show_config do
7
+ include PdkSync::Constants
8
+ puts 'PDKSync Configuration'.bold.yellow
9
+ puts '- Git hosting platform: '.bold + "#{PdkSync::Constants::GIT_PLATFORM}".cyan
10
+ puts '- Git base URI: '.bold + "#{PdkSync::Constants::GIT_BASE_URI}".cyan
11
+ if PdkSync::Constants::GIT_PLATFORM == :gitlab
12
+ puts '- Gitlab API endpoint: '.bold + "#{PdkSync::Constants::GITLAB_API_ENDPOINT}".cyan
13
+ end
14
+ puts '- Namespace: '.bold + "#{PdkSync::Constants::NAMESPACE}".cyan
15
+ puts '- PDKSync Dir: '.bold + "#{PdkSync::Constants::PDKSYNC_DIR}".cyan
16
+ puts '- Push File Destination: '.bold + "#{PdkSync::Constants::PUSH_FILE_DESTINATION}".cyan
17
+ puts '- Create PR Against: '.bold + "#{PdkSync::Constants::CREATE_PR_AGAINST}".cyan
18
+ puts '- Managed Modules: '.bold + "#{PdkSync::Constants::MANAGED_MODULES}".cyan
19
+ puts '- Default PDKSync Label: '.bold + "#{PdkSync::Constants::PDKSYNC_LABEL}".cyan
20
+ end
21
+
4
22
  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
23
  task :pdksync, [:additional_title] do |task, args|
6
24
  args = {:branch_name => "pdksync_{ref}",
@@ -10,7 +28,7 @@ task :pdksync, [:additional_title] do |task, args|
10
28
  PdkSync::main(steps: [:use_pdk_ref, :clone, :pdk_update, :create_commit, :push_and_create_pr], args: args)
11
29
  end
12
30
 
13
- namespace :pdk do
31
+ namespace :pdk do
14
32
  desc 'Runs PDK convert against modules'
15
33
  task :pdk_convert do
16
34
  PdkSync::main(steps: [:pdk_convert])
@@ -53,7 +71,7 @@ GitHubChangelogGenerator::RakeTask.new :changelog do |config|
53
71
  config.user = 'puppetlabs'
54
72
  config.project = 'pdksync'
55
73
  # config.since_tag = '1.1.1'
56
- config.future_release = '0.3.0'
74
+ config.future_release = '0.4.0'
57
75
  config.exclude_labels = ['maintenance']
58
76
  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)."
59
77
  config.add_pr_wo_labels = true
data/lib/pdksync.rb CHANGED
@@ -4,8 +4,8 @@ require 'open3'
4
4
  require 'fileutils'
5
5
  require 'rake'
6
6
  require 'pdk'
7
- require 'octokit'
8
7
  require 'pdksync/constants'
8
+ require 'pdksync/gitplatformclient'
9
9
  require 'json'
10
10
  require 'yaml'
11
11
  require 'colorize'
@@ -13,8 +13,6 @@ require 'bundler'
13
13
 
14
14
  # @summary
15
15
  # This module set's out and controls the pdksync process
16
- # @param [String] @access_token
17
- # The token used to access github, must be exported locally.
18
16
  # @param [String] @namspace
19
17
  # The namespace of the repositories we are updating.
20
18
  # @param [String] @pdksync_dir
@@ -25,22 +23,37 @@ require 'bundler'
25
23
  # The branch the the pull requests are to be made against.
26
24
  # @param [String] @managed_modules
27
25
  # The file that the array of managed modules is to be retrieved from.
26
+ # @param [Symbol] @git_platform
27
+ # The Git hosting platform to use for pull requests
28
+ # @param [String] @git_base_uri
29
+ # The base URI for Git repository access, for example 'https://github.com' or
30
+ # 'ssh://git@repo.example.com:2222'
31
+ # @param [Hash] @git_platform_access_settings
32
+ # Hash of access settings required to access the configured Git hosting
33
+ # platform API. Must always contain the key :access_token set to the exported
34
+ # GITHUB_TOKEN or GITLAB_TOKEN. In case of Gitlab it also must contain the
35
+ # key :gitlab_api_endpoint with an appropriate value.
28
36
  module PdkSync
29
37
  include Constants
30
- @access_token = Constants::ACCESS_TOKEN
31
38
  @namespace = Constants::NAMESPACE
32
39
  @pdksync_dir = Constants::PDKSYNC_DIR
33
40
  @push_file_destination = Constants::PUSH_FILE_DESTINATION
34
41
  @create_pr_against = Constants::CREATE_PR_AGAINST
35
42
  @managed_modules = Constants::MANAGED_MODULES
36
43
  @default_pdksync_label = Constants::PDKSYNC_LABEL
44
+ @git_platform = Constants::GIT_PLATFORM
45
+ @git_base_uri = Constants::GIT_BASE_URI
46
+ @git_platform_access_settings = {
47
+ access_token: Constants::ACCESS_TOKEN,
48
+ gitlab_api_endpoint: Constants::GITLAB_API_ENDPOINT
49
+ }
37
50
 
38
51
  def self.main(steps: [:clone], args: nil)
39
52
  create_filespace
40
53
  client = setup_client
41
54
  module_names = return_modules
42
55
  raise "No modules found in '#{@managed_modules}'" if module_names.nil?
43
- validate_modules_exist(module_names)
56
+ validate_modules_exist(client, module_names)
44
57
  pr_list = []
45
58
 
46
59
  # The current directory is saved for cleanup purposes
@@ -59,7 +72,7 @@ module PdkSync
59
72
  # validation push_and_create_pr
60
73
  if steps.include?(:push_and_create_pr)
61
74
  raise 'Needs a pr_title' if args.nil? || args[:pr_title].nil?
62
- puts "PR title =#{args[:pr_title]}"
75
+ puts "PR title =#{args[:additional_title]} #{args[:pr_title]}"
63
76
  end
64
77
  # validation clean_branches
65
78
  if steps.include?(:clean_branches)
@@ -69,6 +82,7 @@ module PdkSync
69
82
 
70
83
  abort "No modules listed in #{@managed_modules}" if module_names.nil?
71
84
  module_names.each do |module_name|
85
+ module_args = args.clone
72
86
  Dir.chdir(main_path) unless Dir.pwd == main_path
73
87
  print "#{module_name}, "
74
88
  repo_name = "#{@namespace}/#{module_name}"
@@ -98,7 +112,7 @@ module PdkSync
98
112
  if steps.include?(:run_a_command)
99
113
  Dir.chdir(main_path) unless Dir.pwd == main_path
100
114
  print 'run command, '
101
- exit_status = run_command(output_path, args)
115
+ exit_status = run_command(output_path, module_args)
102
116
  next unless exit_status.zero?
103
117
  end
104
118
  if steps.include?(:pdk_update)
@@ -106,18 +120,18 @@ module PdkSync
106
120
  next unless pdk_update(output_path).zero?
107
121
  if steps.include?(:use_pdk_ref)
108
122
  ref = return_template_ref
109
- pr_title = args[:additional_title] ? "#{args[:additional_title]} - pdksync_#{ref}" : "pdksync_#{ref}"
110
- args = { branch_name: "pdksync_#{ref}",
111
- commit_message: "pdksync_#{ref}",
112
- pr_title: pr_title,
113
- pdksync_label: @default_pdksync_label }
123
+ pr_title = module_args[:additional_title] ? "#{module_args[:additional_title]} - pdksync_#{ref}" : "pdksync_#{ref}"
124
+ module_args = module_args.merge(branch_name: "pdksync_#{ref}",
125
+ commit_message: pr_title,
126
+ pr_title: pr_title,
127
+ pdksync_label: @default_pdksync_label)
114
128
  end
115
129
  print 'pdk update, '
116
130
  end
117
131
  if steps.include?(:create_commit)
118
132
  Dir.chdir(main_path) unless Dir.pwd == main_path
119
133
  git_instance = Git.open(output_path)
120
- create_commit(git_instance, args[:branch_name], args[:commit_message])
134
+ create_commit(git_instance, module_args[:branch_name], module_args[:commit_message])
121
135
  print 'commit created, '
122
136
  end
123
137
  if steps.include?(:push_and_create_pr)
@@ -128,7 +142,7 @@ module PdkSync
128
142
  pdk_version = return_pdk_version("#{output_path}/metadata.json")
129
143
 
130
144
  # If a label is supplied, verify that it is available in the repo
131
- label = args[:pdksync_label] ? args[:pdksync_label] : args[:label]
145
+ label = module_args[:pdksync_label] ? module_args[:pdksync_label] : module_args[:label]
132
146
  label_valid = (label.is_a?(String) && !label.to_str.empty?) ? check_for_label(client, repo_name, label) : nil
133
147
 
134
148
  # Exit current iteration if an error occured retrieving a label
@@ -137,7 +151,7 @@ module PdkSync
137
151
  end
138
152
 
139
153
  # Create the PR and add link to pr list
140
- pr = create_pr(client, repo_name, git_instance.current_branch, pdk_version, args[:pr_title])
154
+ pr = create_pr(client, repo_name, git_instance.current_branch, pdk_version, module_args[:pr_title])
141
155
  if pr.nil?
142
156
  break
143
157
  end
@@ -153,7 +167,7 @@ module PdkSync
153
167
  end
154
168
  if steps.include?(:clean_branches)
155
169
  Dir.chdir(main_path) unless Dir.pwd == main_path
156
- delete_branch(client, repo_name, args[:branch_name])
170
+ delete_branch(client, repo_name, module_args[:branch_name])
157
171
  print 'branch deleted, '
158
172
  end
159
173
  puts 'done.'.green
@@ -173,14 +187,12 @@ module PdkSync
173
187
 
174
188
  # @summary
175
189
  # This method when called will create and return an octokit client with access to the upstream git repositories.
176
- # @return [Octokit::Client] client
177
- # The octokit client that has been created.
190
+ # @return [PdkSync::GitPlatformClient] client
191
+ # The Git platform client that has been created.
178
192
  def self.setup_client
179
- client = Octokit::Client.new(access_token: @access_token.to_s)
180
- client.user.login
181
- client
182
- rescue ArgumentError, Octokit::Unauthorized
183
- raise "Access Token not set up correctly - Use export 'GITHUB_TOKEN=<put your token here>' to set it."
193
+ PdkSync::GitPlatformClient.new(@git_platform, @git_platform_access_settings)
194
+ rescue StandardError => error
195
+ raise "Git platform access not set up correctly: #{error}"
184
196
  end
185
197
 
186
198
  # @summary
@@ -193,14 +205,19 @@ module PdkSync
193
205
  end
194
206
 
195
207
  # @summary
196
- # This method when called will parse an array of module names and verify whether they are valid GitHub repo names
208
+ # This method when called will parse an array of module names and verify
209
+ # whether they are valid repo or project names on the configured Git
210
+ # hosting platform.
211
+ # @param [PdkSync::GitPlatformClient] client
212
+ # The Git platform client used to get a repository.
197
213
  # @param [Array] module_names
198
- # String array of the names of GitHub repos
199
- def self.validate_modules_exist(module_names)
214
+ # String array of the names of Git platform repos
215
+ def self.validate_modules_exist(client, module_names)
200
216
  invalid_names = []
217
+ raise "Error reading in modules. Check syntax of '#{@managed_modules}'." unless !module_names.nil? && module_names.is_a?(Array)
201
218
  module_names.each do |module_name|
202
219
  # If module name is invalid, push it to invalid names array
203
- unless Octokit.repository?("#{@namespace}/#{module_name}")
220
+ unless client.repository?("#{@namespace}/#{module_name}")
204
221
  invalid_names.push(module_name)
205
222
  next
206
223
  end
@@ -250,7 +267,7 @@ module PdkSync
250
267
  # @return [Git::Base]
251
268
  # A git object representing the local repository.
252
269
  def self.clone_directory(namespace, module_name, output_path)
253
- Git.clone("https://github.com/#{namespace}/#{module_name}.git", output_path.to_s) # is returned
270
+ Git.clone("#{@git_base_uri}/#{namespace}/#{module_name}.git", output_path.to_s) # is returned
254
271
  rescue Git::GitExecuteError => error
255
272
  puts "(FAILURE) Cloning #{module_name} has failed. #{error}".red
256
273
  end
@@ -352,7 +369,7 @@ module PdkSync
352
369
  # @param [String] template_ref
353
370
  # The unique template_ref that is used as part of the commit name.
354
371
  # @param [String] commit_message
355
- # If sepecified it will be the message for the commit.
372
+ # If specified it will be the message for the commit.
356
373
  def self.commit_staged_files(git_repo, template_ref, commit_message = nil)
357
374
  message = if commit_message.nil?
358
375
  "pdksync_#{template_ref}"
@@ -378,8 +395,8 @@ module PdkSync
378
395
 
379
396
  # @summary
380
397
  # 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.
381
- # @param [Octokit::Client] client
382
- # The octokit client used to gain access to and manipulate the repository.
398
+ # @param [PdkSync::GitPlatformClient] client
399
+ # The Git platform client used to gain access to and manipulate the repository.
383
400
  # @param [String] repo_name
384
401
  # The name of the repository on which the commit is to be made.
385
402
  # @param [String] template_ref
@@ -407,8 +424,8 @@ module PdkSync
407
424
 
408
425
  # @summary
409
426
  # 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.
427
+ # @param [PdkSync::GitPlatformClient] client
428
+ # The Git platform client used to gain access to and manipulate the repository.
412
429
  # @param [String] repo_name
413
430
  # The name of the repository on which the commit is to be made.
414
431
  # @param [String] label
@@ -437,8 +454,8 @@ module PdkSync
437
454
 
438
455
  # @summary
439
456
  # 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.
457
+ # @param [PdkSync::GitPlatformClient] client
458
+ # The Git Platform client used to gain access to and manipulate the repository.
442
459
  # @param [String] repo_name
443
460
  # The name of the repository on which the commit is to be made.
444
461
  # @param [Integer] issue_number
@@ -454,8 +471,8 @@ module PdkSync
454
471
 
455
472
  # @summary
456
473
  # This method when called will delete any preexisting branch on the given repository that matches the given name.
457
- # @param [Octokit::Client] client
458
- # The octokit client used to gain access to and manipulate the repository.
474
+ # @param [PdkSync::GitPlatformClient] client
475
+ # The Git platform client used to gain access to and manipulate the repository.
459
476
  # @param [String] repo_name
460
477
  # The name of the repository from which the branch is to be deleted.
461
478
  # @param [String] branch_name
@@ -1,14 +1,78 @@
1
+ require 'yaml'
2
+
1
3
  # @summary
2
4
  # A module used to contain a set of variables that are expected to remain constant across all iterations of the main pdksync module.
5
+ # @note
6
+ # Configuration is loaded from `$HOME/.pdksync.yml`. If $HOME is not set, the config_path will use the current directory.
7
+ # Set PDKSYNC_LABEL to '' to disable adding a label during pdksync runs.
3
8
  module PdkSync # rubocop:disable Style/ClassAndModuleChildren
9
+ # Constants contains the configuration for pdksync to use
4
10
  module Constants
5
- ACCESS_TOKEN = ENV['GITHUB_TOKEN'].freeze
6
- NAMESPACE = 'puppetlabs'.freeze
7
- PDKSYNC_DIR = 'modules_pdksync'.freeze
8
- PUSH_FILE_DESTINATION = 'origin'.freeze
9
- CREATE_PR_AGAINST = 'master'.freeze
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
+ default_config = {
12
+ namespace: 'puppetlabs',
13
+ pdksync_dir: 'modules_pdksync',
14
+ push_file_destination: 'origin',
15
+ create_pr_against: 'master',
16
+ managed_modules: 'managed_modules.yml',
17
+ pdksync_label: 'maintenance',
18
+ git_platform: :github,
19
+ git_base_uri: 'https://github.com',
20
+ gitlab_api_endpoint: 'https://gitlab.com/api/v4'
21
+ }
22
+
23
+ supported_git_platforms = [:github, :gitlab]
24
+
25
+ config = {}
26
+
27
+ config_path = "#{ENV['HOME']}/.pdksync.yml"
28
+
29
+ # pdksync config file must exist, not be empty and not be an empty YAML file
30
+ if File.exist?(config_path) && YAML.load_file(config_path) && !YAML.load_file(config_path).nil?
31
+ custom_config = YAML.load_file(config_path)
32
+ config[:namespace] = custom_config['namespace'] ||= default_config[:namespace]
33
+ config[:pdksync_dir] = custom_config['pdksync_dir'] ||= default_config[:pdksync_dir]
34
+ config[:push_file_destination] = custom_config['push_file_destination'] ||= default_config[:push_file_destination]
35
+ config[:create_pr_against] = custom_config['create_pr_against'] ||= default_config[:create_pr_against]
36
+ config[:managed_modules] = custom_config['managed_modules'] ||= default_config[:managed_modules]
37
+ config[:pdksync_label] = custom_config['pdksync_label'] ||= default_config[:pdksync_label]
38
+ config[:git_platform] = custom_config['git_platform'] ||= default_config[:git_platform]
39
+ config[:git_base_uri] = custom_config['git_base_uri'] ||= case config[:git_platform]
40
+ when :gitlab
41
+ 'https://gitlab.com'
42
+ else
43
+ default_config[:git_base_uri]
44
+ end
45
+ config[:gitlab_api_endpoint] = custom_config['gitlab_api_endpoint'] ||= default_config[:gitlab_api_endpoint]
46
+ else
47
+ config = default_config
48
+ end
49
+
50
+ NAMESPACE = config[:namespace].freeze
51
+ PDKSYNC_DIR = config[:pdksync_dir].freeze
52
+ PUSH_FILE_DESTINATION = config[:push_file_destination].freeze
53
+ CREATE_PR_AGAINST = config[:create_pr_against].freeze
54
+ MANAGED_MODULES = config[:managed_modules].freeze
55
+ PDKSYNC_LABEL = config[:pdksync_label].freeze
56
+ GIT_PLATFORM = config[:git_platform].downcase.to_sym.freeze
57
+ GIT_BASE_URI = config[:git_base_uri].freeze
58
+ GITLAB_API_ENDPOINT = config[:gitlab_api_endpoint].freeze
59
+ ACCESS_TOKEN = case GIT_PLATFORM
60
+ when :github
61
+ ENV['GITHUB_TOKEN'].freeze
62
+ when :gitlab
63
+ ENV['GITLAB_TOKEN'].freeze
64
+ end
65
+
66
+ # Sanity checks
67
+
68
+ unless supported_git_platforms.include?(GIT_PLATFORM)
69
+ raise "Unsupported Git hosting platform '#{GIT_PLATFORM}'."\
70
+ " Supported platforms are: #{supported_git_platforms.join(', ')}"
71
+ end
72
+
73
+ if ACCESS_TOKEN.nil?
74
+ raise "Git platform access token for #{GIT_PLATFORM.capitalize} not set"\
75
+ " - use 'export #{GIT_PLATFORM.upcase}_TOKEN=\"<your token>\"' to set"
76
+ end
13
77
  end
14
78
  end
@@ -0,0 +1,75 @@
1
+ require 'octokit'
2
+
3
+ # @summary
4
+ # This class wraps Octokit::Client and provides the method implementations
5
+ # required by pdksync main to access the Github API for creating pull
6
+ # requests, adding labels, and so forth.
7
+ class PdkSync::GithubClient
8
+ # @summary
9
+ # Creates a new Octokit::Client and logs in the user based on the
10
+ # supplied access token
11
+ # @param access_token
12
+ # The Github access token, required to access the Github API
13
+ def initialize(access_token)
14
+ @client = Octokit::Client.new(access_token: access_token.to_s)
15
+ @client.user.login
16
+ end
17
+
18
+ # @summary Checks if the supplied repository exists on the Git hosting platform
19
+ # @param [String] repository
20
+ # The full repository name, i.e. "namespace/repo_name"
21
+ # @return [Boolean] true if the repository exists, false otherwise
22
+ def repository?(repository)
23
+ @client.repository?(repository)
24
+ end
25
+
26
+ # @summary Creates a new pull request against the Git hosting platform
27
+ # @param [String] repo_name
28
+ # The full repository name, i.e. "namespace/repo_name" in which to create
29
+ # the pull request
30
+ # @param [String] create_pr_against
31
+ # The target branch against which to create the pull request
32
+ # @param [String] head
33
+ # The source branch from which to create the pull request
34
+ # @param [String] title
35
+ # The title/name of the pull request to create
36
+ # @param [String] message
37
+ # The pull request message/body
38
+ # @return An Octokit pull request object for the newly created pull request
39
+ def create_pull_request(repo_name, create_pr_against, head, title, message)
40
+ @client.create_pull_request(repo_name, create_pr_against, head, title, message)
41
+ end
42
+
43
+ # @summary Gets the labels available in the repository
44
+ # @param [String] repo_name
45
+ # The full repository name, i.e. "namespace/repo_name", from which to get
46
+ # the available labels
47
+ # @return [Array] List of available labels in the repository
48
+ def labels(repo_name)
49
+ @client.labels(repo_name)
50
+ end
51
+
52
+ # @summary Updates an existing issue/pull request in the repository
53
+ # @param [String] repo_name
54
+ # The full repository name, i.e. "namespace/repo_name" in which to update
55
+ # the issue
56
+ # @param [Integer] issue_number
57
+ # The id number of the issue/pull request to update
58
+ # @param [Hash] options
59
+ # A hash of options definint the changes to the issue
60
+ # @return An Octokit issue object of the updated issue
61
+ def update_issue(repo_name, issue_number, options)
62
+ @client.update_issue(repo_name, issue_number, options)
63
+ end
64
+
65
+ # @summary Deletes a branch in the repository
66
+ # @param [String] repo_name
67
+ # The full repository name, i.e. "namespace/repo_name" in which to delete
68
+ # the branch
69
+ # @param [String] branch_name
70
+ # The name of the branch to delete
71
+ # @return [Boolean] true on success, false on failure
72
+ def delete_branch(repo_name, branch_name)
73
+ @client.delete_branch(repo_name, branch_name)
74
+ end
75
+ end
@@ -0,0 +1,91 @@
1
+ require 'gitlab'
2
+
3
+ # @summary
4
+ # This class wraps Gitlab::Client and provides the method implementations
5
+ # required by pdksync main to access the Gitlab API for creating merge
6
+ # requests, adding labels, and so forth.
7
+ class PdkSync::GitlabClient
8
+ # @summary
9
+ # Creates a new Gitlab::Client and logs in the user based on the
10
+ # supplied access token and the Gitlab API endpoint URL
11
+ # @param [String] access_token
12
+ # The Gitlab private access token, required to access the Gitlab API
13
+ # @param [String] gitlab_api_endpoint
14
+ # URL to the Gitlab API endpoint against which to work
15
+ def initialize(access_token, gitlab_api_endpoint)
16
+ @client = Gitlab.client(endpoint: gitlab_api_endpoint, private_token: access_token)
17
+ end
18
+
19
+ # @summary Checks if the supplied project exists on the Git hosting platform
20
+ # @param [String] project
21
+ # The full repository name, i.e. "namespace/project"
22
+ # @return [Boolean] true if the project exists, false otherwise
23
+ def repository?(project)
24
+ @client.project(project)
25
+
26
+ true
27
+ rescue Gitlab::Error::NotFound
28
+ false
29
+ end
30
+
31
+ # @summary
32
+ # Creates a new merge request (i.e. pull request) against the Gitlab
33
+ # platform
34
+ # @param [String] project
35
+ # The full project name, i.e. "namespace/project" in which to create
36
+ # the merge request
37
+ # @param [String] target_branch
38
+ # The target branch against which to create the merge request
39
+ # @param [String] source_branch
40
+ # The source branch from which to create the merge request
41
+ # @param [String] title
42
+ # The title/name of the merge request to create
43
+ # @param [String] message
44
+ # The pull request message/body
45
+ # @return
46
+ # A Gitlab merge request object for the newly created merge request
47
+ def create_pull_request(project, target_branch, source_branch, title, message)
48
+ mr_options = {
49
+ source_branch: source_branch,
50
+ target_branch: target_branch,
51
+ description: message
52
+ }
53
+ @client.create_merge_request(project, title, mr_options)
54
+ end
55
+
56
+ # @summary Gets the labels available in the project
57
+ # @param [String] project
58
+ # The full project name, i.e. "namespace/project", from which to get
59
+ # the available labels
60
+ # @return [Array] List of available labels in the project
61
+ def labels(project)
62
+ @client.labels(project)
63
+ end
64
+
65
+ # @summary Updates an existing merge request in the repository
66
+ # @note This method is specifically used to set labels for a merge request
67
+ # @param [String] project
68
+ # The full project name, i.e. "namespace/project" in which to update
69
+ # the issue
70
+ # @param [Integer] id
71
+ # The id number of the merge request to update
72
+ # @param [Hash] options
73
+ # A hash of options defining the changes to the merge request
74
+ # @return A Gitlab merge request object of the updated merge request
75
+ def update_issue(project, id, options)
76
+ # Gitlab requires labels to be supplied as a comma-separated string
77
+ labels = options[:labels].join(',')
78
+ @client.update_merge_request(project, id, labels: labels)
79
+ end
80
+
81
+ # @summary Deletes a branch in the project
82
+ # @param [String] project
83
+ # The full project name, i.e. "namespace/project" in which to delete
84
+ # the branch
85
+ # @param [String] branch_name
86
+ # The name of the branch to delete
87
+ # @return [Boolean] true on success, false on failure
88
+ def delete_branch(project, branch_name)
89
+ @client.delete_branch(project, branch_name)
90
+ end
91
+ end
@@ -0,0 +1,109 @@
1
+ require 'pdksync/pullrequest'
2
+
3
+ # @summary
4
+ # The GitPlatformClient class creates a PdkSync::GithubClient or
5
+ # PdkSync::GitlabClient and provides methods wrapping the client's
6
+ # corresponding methods
7
+ class PdkSync::GitPlatformClient
8
+ # @summary
9
+ # Creates a PdkSync::GithubClient or PdkSync::GitlabClient based on the
10
+ # value of git_platform.
11
+ # @param [Symbol] git_platform
12
+ # The symbol designating the Git hosting platform to use and thus which
13
+ # client to create
14
+ # @param [Hash] git_platform_access_settings
15
+ # Hash of Git platform access settings, such as access_token or
16
+ # gitlab_api_endpoint. access_token is always required,
17
+ # gitlab_api_endpoint only for Gitlab.
18
+ def initialize(git_platform, git_platform_access_settings)
19
+ @git_platform = git_platform
20
+
21
+ # TODO: raise exceptions when git_platform_access_settings hash is not
22
+ # set up correctly? Or let PdkSync::GithubClient or PdkSync::GitlabClient
23
+ # raise errors later and let them propagate upwards?
24
+ access_token = git_platform_access_settings[:access_token]
25
+ @client = case git_platform
26
+ when :github
27
+ require 'pdksync/githubclient'
28
+
29
+ PdkSync::GithubClient.new(access_token)
30
+ when :gitlab
31
+ require 'pdksync/gitlabclient'
32
+
33
+ gitlab_api_endpoint = git_platform_access_settings[:gitlab_api_endpoint]
34
+ PdkSync::GitlabClient.new(access_token, gitlab_api_endpoint)
35
+ end
36
+ end
37
+
38
+ # @summary Checks if the supplied project exists on the Git hosting platform
39
+ # @param [String] project
40
+ # The full repository name, i.e. "namespace/project"
41
+ # @return [Boolean] true if the project exists, false otherwise
42
+ def repository?(project)
43
+ @client.repository?(project)
44
+ end
45
+
46
+ # @summary
47
+ # Creates a new pull/merge request against the Git hosting platform and
48
+ # wraps the Github or Gitlab result in a PdkSync::PullRequest object for
49
+ # consumption by pdksync main
50
+ # @param [String] project
51
+ # The full project name, i.e. "namespace/project" in which to create
52
+ # the pull/merge request
53
+ # @param [String] target_branch
54
+ # The target branch against which to create the pull/merge request
55
+ # @param [String] source_branch
56
+ # The source branch from which to create the pull/merge request
57
+ # @param [String] title
58
+ # The title/name of the pull/merge request to create
59
+ # @param [String] message
60
+ # The pull/merge request message/body
61
+ # @return [PdkSync::PullRequest]
62
+ # A pdksync pull request object for the newly created pull/merge request
63
+ # for consumption by pdksync main
64
+ def create_pull_request(project, target_branch, source_branch, title, message)
65
+ client_pr = @client.create_pull_request(project, target_branch, source_branch, title, message)
66
+ pr = case @git_platform
67
+ when :github
68
+ PdkSync::PullRequest.github(client_pr)
69
+ when :gitlab
70
+ PdkSync::PullRequest.gitlab(client_pr)
71
+ end
72
+ pr
73
+ end
74
+
75
+ # @summary Gets the labels available in the project
76
+ # @param [String] project
77
+ # The full project name, i.e. "namespace/project", from which to get
78
+ # the available labels
79
+ # @return [Array] List of available labels in the project
80
+ def labels(project)
81
+ @client.labels(project)
82
+ end
83
+
84
+ # @summary Updates an existing pull/merge request in the repository
85
+ # @note
86
+ # This method is specifically used to set labels for a pull/merge request
87
+ # @param [String] project
88
+ # The full project name, i.e. "namespace/project" in which to update
89
+ # the issue
90
+ # @param [Integer] id
91
+ # The id number of the pull/merge request to update
92
+ # @param [Hash] options
93
+ # A hash of options defining the changes to the pull/merge request
94
+ # @return A pull/merge request object of the updated pull/merge request
95
+ def update_issue(project, id, options)
96
+ @client.update_issue(project, id, options)
97
+ end
98
+
99
+ # @summary Deletes a branch in the project
100
+ # @param [String] project
101
+ # The full project name, i.e. "namespace/project" in which to delete
102
+ # the branch
103
+ # @param [String] branch_name
104
+ # The name of the branch to delete
105
+ # @return [Boolean] true on success, false on failure
106
+ def delete_branch(project, branch_name)
107
+ @client.delete_branch(project, branch_name)
108
+ end
109
+ end
@@ -0,0 +1,35 @@
1
+ # @summary A simple wrapper class around Github pull request and Gitlab merge
2
+ # request objects used to abstract the differences and provide a common
3
+ # interface to PR URL and number/id.
4
+ class PdkSync::PullRequest
5
+ class << self
6
+ def github(pr_object)
7
+ new(pr_object)
8
+ end
9
+
10
+ def gitlab(pr_object)
11
+ new(pr_object, :gitlab)
12
+ end
13
+
14
+ private :new
15
+ end
16
+
17
+ attr_reader :html_url, :number
18
+
19
+ # Create a new PR wrapper object setting html_url and number
20
+ # @param pr_object
21
+ # The pull request object to wrap as created by Octokit::Client or
22
+ # Gitlab::Client
23
+ # @param [Symbol] git_platform
24
+ # The Git hosting platform against which the pull request is made
25
+ def initialize(pr_object, git_platform = :github)
26
+ case git_platform
27
+ when :github
28
+ @html_url = pr_object.html_url
29
+ @number = pr_object.number
30
+ when :gitlab
31
+ @html_url = pr_object.web_url
32
+ @number = pr_object.iid
33
+ end
34
+ end
35
+ end
data/pdksync.gemspec CHANGED
@@ -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.3.0'
6
+ spec.version = '0.4.0'
7
7
  spec.authors = ['Puppet']
8
8
  spec.email = ['']
9
9
  spec.summary = 'Puppet Module PDK Synchronizer'
@@ -17,11 +17,12 @@ Gem::Specification.new do |spec|
17
17
  spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
18
18
  spec.require_paths = ['lib']
19
19
 
20
- spec.add_development_dependency 'bundler'
20
+ spec.add_development_dependency 'bundler', '~> 1.15'
21
21
  spec.add_development_dependency 'rake'
22
22
  spec.add_development_dependency 'rspec'
23
23
  spec.add_development_dependency 'rubocop', '~> 0.50.0'
24
24
  spec.add_development_dependency 'octokit'
25
+ spec.add_development_dependency 'gitlab'
25
26
  spec.add_development_dependency 'pry'
26
27
 
27
28
  spec.add_runtime_dependency 'git', '~>1.3'
@@ -14,6 +14,7 @@ describe PdkSync do
14
14
 
15
15
  before(:each) do
16
16
  allow(PdkSync).to receive(:return_modules).and_return(@module_names)
17
+ allow(PdkSync).to receive(:validate_modules_exist).and_return(@module_names)
17
18
  Dir.chdir(@folder)
18
19
  end
19
20
 
metadata CHANGED
@@ -1,29 +1,29 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pdksync
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.4.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-15 00:00:00.000000000 Z
11
+ date: 2019-02-04 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - ">="
17
+ - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: '0'
19
+ version: '1.15'
20
20
  type: :development
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - ">="
24
+ - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: '0'
26
+ version: '1.15'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: rake
29
29
  requirement: !ruby/object:Gem::Requirement
@@ -80,6 +80,20 @@ dependencies:
80
80
  - - ">="
81
81
  - !ruby/object:Gem::Version
82
82
  version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: gitlab
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
83
97
  - !ruby/object:Gem::Dependency
84
98
  name: pry
85
99
  requirement: !ruby/object:Gem::Requirement
@@ -141,6 +155,10 @@ files:
141
155
  - Rakefile
142
156
  - lib/pdksync.rb
143
157
  - lib/pdksync/constants.rb
158
+ - lib/pdksync/githubclient.rb
159
+ - lib/pdksync/gitlabclient.rb
160
+ - lib/pdksync/gitplatformclient.rb
161
+ - lib/pdksync/pullrequest.rb
144
162
  - managed_modules.yml
145
163
  - pdksync.gemspec
146
164
  - spec/lib/pdksync_spec.rb
@@ -164,7 +182,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
164
182
  version: '0'
165
183
  requirements: []
166
184
  rubyforge_project:
167
- rubygems_version: 2.6.11
185
+ rubygems_version: 2.7.7
168
186
  signing_key:
169
187
  specification_version: 4
170
188
  summary: Puppet Module PDK Synchronizer