release_manager 0.7.0 → 0.8.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
2
  SHA1:
3
- metadata.gz: 0056b26bafb18d0a01df0610acfc187b5b894416
4
- data.tar.gz: bd8a438f19dbee1ebb1ca73c277eac99b14222c9
3
+ metadata.gz: d6069b076747b74494e4aaf2d464abd5436d742b
4
+ data.tar.gz: 277bbc9bb132f094ccf4cdcc7a761741cd92eaef
5
5
  SHA512:
6
- metadata.gz: 548c678ef78f0a13b3d2c9c6e40e1b97b12a64590cb5eb5c71595d3547e711e8bdbe98d7d88ddd3e61d305d0fb7d9715056fb47c9b923c392c12ef5ebcb1e5f1
7
- data.tar.gz: fd8faf85ad2d821365a10d122c70683a4575db9769aaf9b54c765e07a8c59865229581c9863ba47a5a22f89d5bb8abcdddcb71b6f42b58014b17646970cf8f66
6
+ metadata.gz: 892cde4d6302725ada12b0b1e89f2854d61fac8d375492b1916a5d5d8e5cce99c6871107a2f8cac1bdd1a5cf2b51427297fdd7c0501448d7e6530ac9bd72ce46
7
+ data.tar.gz: 1fbc83551bdb199c07ea26835e98e0d9ddff4195de16ff5845419dff6f665b4024dd2518dc74322cd8ae381e7941b00372de578ae18c66687f9f60a3938b0486
@@ -1,6 +1,10 @@
1
1
  # Release Manager
2
2
 
3
- ## Unreleased
3
+ ## 0.8.0
4
+ * Allows for creating sandboxes from different targets
5
+ * Allow for releasing one off patches with release-mod
6
+ * Fixes #11 - release-mod should show which variables to set
7
+ ## 0.7.0
4
8
  * Fixes #3 - release-mod fails when trying to sort tags
5
9
  * Fixes #8 - files disappear from change set
6
10
  * Fixes #1 - deploy-mod creates commit everytime
data/Gemfile CHANGED
@@ -1,6 +1,6 @@
1
1
  source ENV['GEM_SOURCE'] ||'https://rubygems.org'
2
2
  # Specify your gem's dependencies in release_manager.gemspec
3
- gem 'gitlab', '~> 4.2.0'
3
+ gem 'gitlab'
4
4
  gem 'rugged', '~> 0.26'
5
5
  gem 'highline', '~> 1.7'
6
6
 
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- release_manager (0.7.0)
4
+ release_manager (0.8.0)
5
5
  gitlab (~> 4.2.0)
6
6
  highline (~> 1.7)
7
7
  rugged (~> 0.26)
@@ -21,15 +21,15 @@ GEM
21
21
  method_source (0.9.0)
22
22
  multi_xml (0.6.0)
23
23
  parallel (1.12.0)
24
- parser (2.4.0.0)
25
- ast (~> 2.2)
24
+ parser (2.4.0.2)
25
+ ast (~> 2.3)
26
26
  powerpack (0.1.1)
27
27
  pry (0.11.1)
28
28
  coderay (~> 1.1.0)
29
29
  method_source (~> 0.9.0)
30
30
  rainbow (2.2.2)
31
31
  rake
32
- rake (12.1.0)
32
+ rake (12.3.0)
33
33
  rspec (3.6.0)
34
34
  rspec-core (~> 3.6.0)
35
35
  rspec-expectations (~> 3.6.0)
@@ -43,14 +43,14 @@ GEM
43
43
  diff-lcs (>= 1.2.0, < 2.0)
44
44
  rspec-support (~> 3.6.0)
45
45
  rspec-support (3.6.0)
46
- rubocop (0.50.0)
46
+ rubocop (0.51.0)
47
47
  parallel (~> 1.10)
48
48
  parser (>= 2.3.3.1, < 3.0)
49
49
  powerpack (~> 0.1)
50
50
  rainbow (>= 2.2.2, < 3.0)
51
51
  ruby-progressbar (~> 1.7)
52
52
  unicode-display_width (~> 1.0, >= 1.0.1)
53
- ruby-progressbar (1.8.3)
53
+ ruby-progressbar (1.9.0)
54
54
  rugged (0.26.0)
55
55
  terminal-table (1.8.0)
56
56
  unicode-display_width (~> 1.1, >= 1.1.1)
@@ -61,7 +61,7 @@ PLATFORMS
61
61
 
62
62
  DEPENDENCIES
63
63
  bundler
64
- gitlab (~> 4.2.0)
64
+ gitlab
65
65
  highline (~> 1.7)
66
66
  pry
67
67
  rake
data/README.md CHANGED
@@ -16,18 +16,27 @@ __________ .__ _____
16
16
  - [Prerequisites](#prerequisites)
17
17
  - [Installation](#installation)
18
18
  - [Install directly from source](#install-directly-from-source)
19
+ - [Usage Summary](#usage-summary)
19
20
  - [The workflow problem](#the-workflow-problem)
20
21
  - [R10k Sandbox Creation Steps (the hard way)](#r10k-sandbox-creation-steps-the-hard-way)
21
22
  - [R10k Sandbox Creation steps (the easy way)](#r10k-sandbox-creation-steps-the-easy-way)
22
- - [Usage](#usage)
23
+ - [Detailed Usage](#detailed-usage)
23
24
  - [sandbox-create](#sandbox-create)
24
25
  - [release-mod](#release-mod)
25
26
  - [deploy-mod](#deploy-mod)
26
27
  - [bump-changelog](#bump-changelog)
28
+ - [Common Workflows](#common-workflows)
29
+ - [Creating releases](#creating-releases)
30
+ - [Creating one off releases](#creating-one-off-releases)
27
31
  - [Configuration Settings](#configuration-settings)
28
32
  - [Sandbox-create environment variables](#sandbox-create-environment-variables)
29
33
  - [Ssh agent usage](#ssh-agent-usage)
30
34
  - [Development](#development)
35
+ - [Develpment Environment Setup](#develpment-environment-setup)
36
+ - [Setting up your Gitlab Instance](#setting-up-your-gitlab-instance)
37
+ - [Configure your release manager client](#configure-your-release-manager-client)
38
+ - [Testing the cli commands](#testing-the-cli-commands)
39
+ - [Debugging](#debugging)
31
40
  - [Contributing](#contributing)
32
41
  - [License](#license)
33
42
 
@@ -48,6 +57,8 @@ This gem provides workflow automations around releasing and deploying puppet mod
48
57
  7. Must have a Gitlab API Access token (per user)
49
58
  8. Must have the libssh-dev library package installed
50
59
  9. Must tag code with version tags ie. `v1.2.3`
60
+ 10. Must keep a CHANGELOG.md
61
+
51
62
  ## Installation
52
63
 
53
64
  Add this line to your application's Gemfile:
@@ -73,6 +84,15 @@ gem install specific_install # unless already installed
73
84
  gem specific_install https://github.com/nwops/release_manager
74
85
  ```
75
86
 
87
+ ## Usage Summary
88
+ There are several cli utilities bundled with the gem, each one can be used independently of the other. Detailed usage can be
89
+ found further below in this document.
90
+
91
+ * `sandbox-create -n my_sandbox` - Sandbox creation and module repo forking (most popular)
92
+ * `deploy-mod` - Sandbox creation and repo forking
93
+ * `deploy-r10k` - Deploying your r10k repo to other branches in the same repo using merge requests
94
+ * `release-mod` - Sandbox creation and repo forking (Also popular)
95
+ * `bump-changelog` - for directly manipulating the changelog
76
96
 
77
97
  ## The workflow problem
78
98
  R10k allows us to create a puppet environment for each branch on the r10k-control repository. This makes isolating code deployments
@@ -98,7 +118,7 @@ to use those new branches and forks. This can be a huge burden and consume some
98
118
  15. push new branch on each forked project
99
119
 
100
120
  Yikes! This is a long list of things to do. It is human nature to skip some or all of these steps to save time even though
101
- it is in our best interest to follow these steps. As humans we will always resort to the path of least resistance.
121
+ it is in our best interest to follow these steps. Most humans we will always resort to the path of least resistance.
102
122
 
103
123
  In an effort to force good practices and reduce time and effort, release-manager will automate almost all of the tasks into
104
124
  a single command called `sandbox-create`.
@@ -108,7 +128,7 @@ Additionally there are other commands that help with the release and deploy proc
108
128
  ### R10k Sandbox Creation steps (the easy way)
109
129
  `sandbox-create -n my_sandbox --modules='roles,profiles,hieradata,sqlserver'`
110
130
 
111
- ## Usage
131
+ ## Detailed Usage
112
132
 
113
133
  Release manager provides the following commands to help you create sandboxes, release and deploy puppet code.
114
134
 
@@ -127,22 +147,48 @@ Summary: Creates a new r10k sandbox by forking and creating a new branch on r10k
127
147
  for each module, updates the r10k-control Puppetfile to use those forks and branches
128
148
  and pushes the branch to the upstream r10k-control.
129
149
 
130
- Example: sandbox-create -n my_sandbox -m "roles,profiles,developer"
131
- Example: sandbox-create -n my_sandbox -m "roles,profiles,developer" --members="p1dksk2, p2ksdafs,devops,ci_runner"
132
-
133
150
 
134
151
  Note: If you already have any of these modules cloned, this script will attempt to update those modules
135
152
  using git fetch and git checkout -b sandbox_name upstream/master. So this should not destroy anything.
136
153
 
154
+ Configuration:
155
+
156
+ This script uses the following environment variables to automatically set some options, please ensure
157
+ they exist in your shell environment. You can set an environment variable in the shell or define
158
+ in your shell startup files.
159
+
160
+ Shell: export VARIABLE_NAME=value
161
+
162
+ R10K_REPO_URL - The git repo url to r10k-control (ie. git@gitlab.com:devops/r10k-control.git)
163
+ GITLAB_API_ENDPOINT - The api path to the gitlab server (ie. https://gitlab_server/api/v3)
164
+ replace gitlab_server with your server hostname
165
+ GITLAB_API_PRIVATE_TOKEN - The gitlab user api token.
166
+ You can get a token here (http://web/profile/personal_access_tokens,
167
+ Ensure api box is checked.
168
+ DEFAULT_MODULES - The default set of modules to fork use when
169
+ a sandbox (ie. export DEFAULT_MODULES='hieradata, roles')
170
+
171
+ DEFAULT_MEMBERS - The default members each forked project should add permissions
172
+ to ( ie, DEFAULT_MEMBERS='ci_runner,r10k_user' )
173
+
174
+ If your gitlab server has a invalid certificate you can set the following variable to "fix" that trust issue.
175
+ export GITLAB_API_HTTPARTY_OPTIONS="{verify: false}"
176
+
177
+ Examples:
178
+ sandbox-create -n my_sandbox -m "roles,profiles,developer"
179
+ sandbox-create -n my_sandbox -m "roles,profiles,developer" --members="p1dksk2,devops,ci_runner"
180
+ sandbox-create -n my_sandbox -s "upstream/v0.5.0"
181
+
182
+ Options:
137
183
  --members DEFAULT_MEMBERS A comman seperated list of members to add to forked projects
138
184
  -n, --name NAME The name of your sandbox
185
+ -s, --src-target REMOTE/REF The source of the target to create your sandbox from, defaults to upstream/dev
139
186
  --control-url R10K_REPO_URL git url to the r10k-control repo, defaults to R10K_CONTROL_URL env variable
140
187
  -m, --modules MODULES A comma separated list of modules names from the Puppetfile to fork and branch
141
188
  -r, --repos-dir [REPOS_PATH] The repos path to clone modules to. Defaults to: /home/appuser/repos
142
189
  -c, --control-dir [CONTROL_DIR] The r10k-control repo path. Defaults to: /home/appuser/repos/r10k-control
143
190
  --verbose Extra logging
144
191
 
145
-
146
192
  ```
147
193
 
148
194
  Example Run
@@ -243,6 +289,31 @@ and creates a new 'Unrelease Section on top
243
289
 
244
290
  If using the `release-mod` command there is no need to run the `bump-changelog`command as it is part of the process already.
245
291
 
292
+ ## Common Workflows
293
+ ### Creating releases
294
+ You worked hard on your code and now you want to release your software for others to enjoy.
295
+ Follow the steps below to version your code before deployment. This these changes are considered major
296
+ we want to create a 2.0.0 release.
297
+
298
+ 1. run `release-mod -l major` from the root of the module directory (use `-d` for a dry run)
299
+
300
+ That's it, all you need to do is run that command. Note, by design you are not allowed to enter a version number. Release Manager
301
+ uses the version in metadata.json file as a reference and increments to semver identifiers.
302
+
303
+
304
+ ### Creating one off releases
305
+
306
+ 1. Did you deploy a release all the way to production only to find a bug?
307
+ 2. Do you want to skip all other deployment stages with your patch?
308
+
309
+ Follow the steps below to create a new patch release and deploy straight to production
310
+
311
+ 1. Create a new sandbox based on the branch or tag you want to fix. `sandbox-create -s v0.5.0 -n patch_0.5.1`
312
+ 2. cd ~/repos/r10k-control
313
+ 3. Make your changes in that branch and update the changelog
314
+ 4. Push your code to the remote Git repo and activate your CI pipeline (optional)
315
+ 5. Release the new version `release-mod -l patch -s patch_0.5.1` (creates tag v0.5.1)
316
+ 6. Deploy the patch release to production `deploy-r10k -s v0.5.1 -d production`
246
317
 
247
318
  ## Configuration Settings
248
319
  The following environment variables will automatically set required parameters and defaults. It is suggested you put
@@ -322,8 +393,6 @@ To install this gem onto your local machine, run `bundle exec rake install`. To
322
393
  5. Login (root/password123)
323
394
  6. Create a user account for yourself (add Admin role)
324
395
  7. Logout as Admin and login as the new user account
325
- 8. Add a group named devops and add yourself to this group
326
- 9. Add another group called mirrors and add yourself to this group
327
396
  10. Create a `.env` file in the repo directory and paste these contents in it
328
397
  ```ruby
329
398
  GITLAB_API_ENDPOINT='http://web/api/v4'
@@ -28,6 +28,13 @@ class String
28
28
  end
29
29
  end
30
30
  module ReleaseManager
31
-
31
+ def self.gitlab_server
32
+ if ENV['GITLAB_API_ENDPOINT']
33
+ if data = ENV['GITLAB_API_ENDPOINT'].match(/(https?\:\/\/[\w\.]+)/)
34
+ return data[1]
35
+ end
36
+ end
37
+ 'https://gitlab.com'
38
+ end
32
39
  end
33
40
 
@@ -15,6 +15,7 @@ module ReleaseManager
15
15
  tag version. Revmoes any branch or ref reference and replaces
16
16
  with tag. Currently it is up to you to commit and push the Puppetfile change.
17
17
 
18
+ Options:
18
19
  EOF
19
20
  )
20
21
  opts.on('-p', "--puppetfile [PUPPETFILE]", 'Path to R10k Puppetfile, defaults to ~/repos/r10k-control/Puppetfile') do |p|
@@ -35,11 +35,11 @@ Summary: Deploys the source ref into the dest branch by diffing the two and appl
35
35
  6. push branch and create merge request
36
36
 
37
37
  Examples:
38
- deploy-r10k dev qa
39
38
  deploy-r10k -s dev -d qa
40
39
  deploy-r10k -p ~/repos/r10k-control -s dev -d qa
40
+ deploy-r10k -s v0.5.1 -d production
41
41
 
42
-
42
+ Options:
43
43
  EOF
44
44
  )
45
45
  opts.on('-p', "--puppetfile [PUPPETFILE]", "Path to R10k Puppetfile, defaults to #{puppetfile_path}") do |p|
@@ -30,6 +30,28 @@ Summary: Bumps the module version to the next revision and
30
30
  version by reading the metadata.json file. This should
31
31
  be run inside a module directory.
32
32
 
33
+ Examples:
34
+ release-mod -l minor
35
+ release-mod -l patch -s patch1
36
+ release-mod -m ~/repos/r10k-control
37
+
38
+
39
+ Configuration:
40
+
41
+ This script uses the following environment variables to automatically set some options, please ensure
42
+ they exist in your shell environment. You can set an environment variable in the shell or define
43
+ in your shell startup files.
44
+
45
+ Shell: export VARIABLE_NAME=value
46
+
47
+ R10K_REPO_URL - The git repo url to r10k-control (ie. git@gitlab.com:devops/r10k-control.git)
48
+ GITLAB_API_ENDPOINT - The api path to the gitlab server (ie. https://gitlab_server/api/v4)
49
+ replace gitlab_server with your server hostname
50
+ GITLAB_API_PRIVATE_TOKEN - The gitlab user api token.
51
+ You can get a token here (#{ReleaseManager.gitlab_server}/profile/personal_access_tokens),
52
+ Ensure api box is checked.
53
+
54
+ Options:
33
55
  EOF
34
56
  )
35
57
  opts.on("-d", "--dry-run", "Do a dry run, without making changes") do |c|
@@ -53,11 +75,26 @@ Summary: Bumps the module version to the next revision and
53
75
  opts.on('--verbose', "Extra logging") do |c|
54
76
  options[:verbose] = c
55
77
  end
78
+ opts.on('-s', '--src-branch [BRANCH]', 'The branch you want to base the release from, defaults to dev or master') do |c|
79
+ options[:src_branch] = c
80
+ end
56
81
  opts.on('-r', '--remote-release', "Perform a remote release (For CI systems)") do |c|
57
82
  options[:remote] = true
58
83
  end
59
84
  end.parse!
60
85
 
86
+ unless ENV['GITLAB_API_ENDPOINT']
87
+ puts "Please set the GITLAB_API_ENDPOINT environment variable".fatal
88
+ puts "Example: export GITLAB_API_ENDPOINT=https://gitlab.com/api/v4".fatal
89
+ exit 1
90
+ end
91
+
92
+ unless ENV['GITLAB_API_PRIVATE_TOKEN']
93
+ puts "Please set the GITLAB_API_PRIVATE_TOKEN environment variable".fatal
94
+ puts "Example: export GITLAB_API_PRIVATE_TOKEN=kdii2ljljijsldjfoa".fatal
95
+ exit 1
96
+ end
97
+
61
98
  # default to patch
62
99
  options[:level] ||= 'patch'
63
100
 
@@ -4,12 +4,7 @@ module ReleaseManager
4
4
  class SandboxCreateCli
5
5
 
6
6
  def self.gitlab_server
7
- if ENV['GITLAB_API_ENDPOINT']
8
- if data = ENV['GITLAB_API_ENDPOINT'].match(/(https?\:\/\/[\w\.]+)/)
9
- return data[1]
10
- end
11
- end
12
- 'https://gitlab.com'
7
+ ReleaseManager.gitlab_server
13
8
  end
14
9
 
15
10
  def self.run
@@ -37,7 +32,7 @@ in your shell startup files.
37
32
  Shell: export VARIABLE_NAME=value
38
33
 
39
34
  R10K_REPO_URL - The git repo url to r10k-control (ie. git@gitlab.com:devops/r10k-control.git)
40
- GITLAB_API_ENDPOINT - The api path to the gitlab server (ie. https://gitlab_server/api/v3)
35
+ GITLAB_API_ENDPOINT - The api path to the gitlab server (ie. https://gitlab_server/api/v4)
41
36
  replace gitlab_server with your server hostname
42
37
  GITLAB_API_PRIVATE_TOKEN - The gitlab user api token.
43
38
  You can get a token here (#{gitlab_server}/profile/personal_access_tokens,
@@ -54,6 +49,7 @@ export GITLAB_API_HTTPARTY_OPTIONS="{verify: false}"
54
49
  Examples:
55
50
  #{opts.program_name} -n my_sandbox -m "roles,profiles,developer"
56
51
  #{opts.program_name} -n my_sandbox -m "roles,profiles,developer" --members="p1dksk2,devops,ci_runner"
52
+ #{opts.program_name} -n my_sandbox -s "upstream/v0.5.0"
57
53
 
58
54
  Options:
59
55
  EOF
@@ -64,6 +60,9 @@ Options:
64
60
  opts.on('-n', "--name NAME", "The name of your sandbox") do |n|
65
61
  options[:sandbox_name] = n
66
62
  end
63
+ opts.on('-s', "--src-target REMOTE/REF", "The source of the target to create your sandbox from, defaults to upstream/dev") do |n|
64
+ options[:src_target] = n
65
+ end
67
66
  opts.on('--control-url R10K_REPO_URL', "git url to the r10k-control repo, defaults to R10K_CONTROL_URL env variable") do |r|
68
67
  options[:r10k_repo_url] = r
69
68
  end
@@ -84,7 +83,7 @@ Options:
84
83
  end.parse!
85
84
  unless ENV['GITLAB_API_ENDPOINT']
86
85
  puts "Please set the GITLAB_API_ENDPOINT environment variable".fatal
87
- puts "Example: export GITLAB_API_ENDPOINT=https://gitlab.com/api/v3".fatal
86
+ puts "Example: export GITLAB_API_ENDPOINT=https://gitlab.com/api/v4".fatal
88
87
  exit 1
89
88
  end
90
89
 
@@ -101,6 +100,11 @@ Options:
101
100
  options[:repos_path] ||= File.expand_path(File.join(ENV['HOME'], 'repos'))
102
101
  options[:r10k_repo_url] ||= ENV['R10K_REPO_URL']
103
102
 
103
+ options[:src_target] ||= 'upstream/dev'
104
+ if options[:src_target].split("/").count < 2
105
+ puts "Please use a source target that conforms to the remote/ref pattern".fatal
106
+ exit 1
107
+ end
104
108
  unless options[:r10k_repo_url]
105
109
  puts "Please set the R10K_REPO_URL environment variable or use the --control-url option".fatal
106
110
  puts "Example: export R10K_REPO_URL='git@gitlab.com:devops/r10k-control.git'".fatal
@@ -11,12 +11,14 @@ module ReleaseManager
11
11
  end
12
12
 
13
13
  # @param [String] remote_name - the name of the remote
14
- def fetch(remote_name = 'upstream')
14
+ def fetch(remote_name = 'upstream', tags = false)
15
+ remote_name ||= 'upstream'
15
16
  return unless remote_exists?(remote_name)
16
17
  remote = repo.remotes[remote_name]
17
18
  options = {credentials: credentials.call(remote.url)}
18
19
  logger.info("Fetching remote #{remote_name} from #{remote.url}")
19
20
  options[:certificate_check] = lambda { |valid, host| true } if ENV['GIT_SSL_NO_VERIFY']
21
+ fetch_cli(remote_name) # helps get tags
20
22
  remote.fetch(options)
21
23
  end
22
24
 
@@ -57,7 +59,7 @@ module ReleaseManager
57
59
  # @param [Boolean] reset_url - set to true if you wish to reset the remote url
58
60
  # @return [Rugged::Remote] a rugged remote object
59
61
  def add_remote(url, remote_name = 'upstream', reset_url = false )
60
- return unless git_url?(url)
62
+ return false unless git_url?(url)
61
63
  if remote_exists?(remote_name)
62
64
  # ensure the correct url is set
63
65
  # this sets a non persistant fetch url
@@ -87,10 +89,19 @@ module ReleaseManager
87
89
  repo.remotes[name].url.eql?(url)
88
90
  end
89
91
 
90
- # @param [String] name - the name of the branch
92
+ # @param name [String] - the name of the branch
91
93
  # @return [Boolean] - true if the branch exist
92
94
  def branch_exist?(name)
93
- repo.branches.exist?(name)
95
+ # ensure we have the latest branches
96
+ remote_name, ref = name.split('/', 2)
97
+ if name.include?('/')
98
+ remote_name, ref = name.split('/', 2)
99
+ else
100
+ ref = name
101
+ end
102
+ # check to see if we just needed to fetch the upstreams
103
+ fetch(remote_name) unless (repo.branches.exist?(name) || ref_exists?(name) || tag_exists?(ref))
104
+ repo.branches.exist?(name) || ref_exists?(name) || tag_exists?(ref)
94
105
  end
95
106
 
96
107
  # we should be creating the branch from upstream
@@ -98,9 +109,11 @@ module ReleaseManager
98
109
  def create_branch(name, target = 'upstream/master')
99
110
  # fetch the remote if defined in the target
100
111
  unless branch_exist?(name)
101
- fetch(target.split('/').first) if target.include?('/')
102
- logger.info("Creating branch: #{name} for #{path}")
103
- repo.create_branch(name, target)
112
+ remote_name, ref = target.split('/', 2)
113
+ fetch(remote_name)
114
+ logger.info("Creating branch: #{name} for #{path} from #{target}")
115
+ found_ref = find_ref(target)
116
+ repo.create_branch(name, found_ref)
104
117
  else
105
118
  repo.branches[name]
106
119
  end
@@ -124,6 +137,17 @@ module ReleaseManager
124
137
  remote.push(refs, credentials: credentials)
125
138
  end
126
139
 
140
+ # @return [Array] - returns an array of tag names
141
+ def tags
142
+ repo.tags.map(&:name)
143
+ end
144
+
145
+ # @param name [String] - the name of the tag to check for existence
146
+ # @return [Boolean] - return true if the tag exists
147
+ def tag_exists?(name)
148
+ tags.include?(name)
149
+ end
150
+
127
151
  # push all the tags to the remote
128
152
  # @param [String] remote_name - the remote name to push tags to
129
153
  def push_tags(remote_name)
@@ -239,6 +263,12 @@ module ReleaseManager
239
263
  raise PatchError.new(output) unless $?.success?
240
264
  end
241
265
 
266
+ # @param [String] - the name of the remote to fetch from
267
+ # @note this is a hack to get around libgit2 inability to get remote tags
268
+ def fetch_cli(remote)
269
+ `#{git_command} fetch #{remote} 2>&1 > /dev/null`
270
+ end
271
+
242
272
  # [Rugged::Diff] a rugged diff object
243
273
  # Not fully tested
244
274
  def apply_diff(diff)
@@ -385,6 +415,16 @@ module ReleaseManager
385
415
  dst.diff(src)
386
416
  end
387
417
 
418
+ # @param sha_or_ref [String] - the name or sha of the ref
419
+ # @return [Boolean] true if the ref exists
420
+ def ref_exists?(sha1_or_ref)
421
+ begin
422
+ find_ref(sha1_or_ref)
423
+ rescue Rugged::ReferenceError => e
424
+ false
425
+ end
426
+ end
427
+
388
428
  # @param sha_or_ref [String] - the name or sha of the ref
389
429
  # @return [String] the oid of the sha or ref
390
430
  def find_ref(sha_or_ref)
@@ -392,7 +432,12 @@ module ReleaseManager
392
432
  when Rugged::Object
393
433
  sha_or_ref.oid
394
434
  else
395
- repo.rev_parse_oid(sha_or_ref)
435
+ begin
436
+ repo.rev_parse_oid(sha_or_ref)
437
+ rescue Rugged::ReferenceError => e
438
+ tag = repo.tags.find{|t| t.name == sha_or_ref.split('/').last}
439
+ repo.rev_parse_oid(tag.target.oid) if tag
440
+ end
396
441
  end
397
442
  end
398
443
  end
@@ -6,17 +6,22 @@ require 'release_manager/git/utilites'
6
6
  require 'rugged'
7
7
 
8
8
  class PuppetModule < WorkflowAction
9
- attr_reader :name, :metadata_file, :path, :version, :upstream
9
+ attr_reader :name, :metadata_file, :path, :version, :upstream, :options
10
10
  attr_writer :version, :source
11
11
 
12
12
  include ReleaseManager::Git::Utilities
13
13
  include ReleaseManager::Logger
14
14
  include ReleaseManager::VCSManager
15
15
 
16
- def initialize(mod_path, upstream = nil)
16
+ # @param mod_path [String] - the path to the module
17
+ # @param options [Hash] - a hash of options
18
+ # @option upstream [String] - the upstream url
19
+ # @option src_branch [String] - the source of the branch
20
+ def initialize(mod_path, options = {})
17
21
  raise ModNotFoundException.new("#{mod_path} is not a valid puppet module path") if mod_path.nil?
18
22
  @path = mod_path
19
- @upstream = upstream
23
+ @options = options
24
+ @upstream = options[:upstream]
20
25
  @metadata_file = File.join(mod_path, 'metadata.json')
21
26
  end
22
27
 
@@ -165,6 +170,7 @@ class PuppetModule < WorkflowAction
165
170
  JSON.pretty_generate(metadata)
166
171
  end
167
172
 
173
+ # @return [Boolean] - true if the module is an r10k-control repository
168
174
  def r10k_module?
169
175
  mod_name =~ /r10k[-_]?control/i
170
176
  end
@@ -173,21 +179,31 @@ class PuppetModule < WorkflowAction
173
179
  @upstream ||= git_upstream_url
174
180
  end
175
181
 
176
- # ensures the dev branch has been created and is up to date
177
- def create_dev_branch
182
+ # @param branch [String] - the name of the source branch to create and rebase from
183
+ # creates a branch and checkouts out the branch with the latest source of the upstream source
184
+ def create_src_branch(branch = src_branch)
178
185
  fetch('upstream')
179
- create_branch(src_branch, "upstream/#{src_branch}")
186
+ create_branch(branch, "upstream/#{branch}")
180
187
  # ensure we have updated our local branch
181
- checkout_branch(src_branch)
182
- rebase_branch(src_branch, src_branch, 'upstream')
188
+ checkout_branch(branch)
189
+ rebase_branch(branch, branch, 'upstream')
190
+ end
191
+
192
+ # ensures the dev branch has been created and is up to date
193
+ # @deprecated Use {#create_src_branch} instead of this method which defaults to dev or master branch
194
+ def create_dev_branch
195
+ create_src_branch(src_branch)
183
196
  end
184
197
 
185
198
  # @returns [String] - the source branch to push to
186
- # if r10k-control this branch will be dev, otherwise master
199
+ # if the user supplied the src_branch we use that otherwise
200
+ # if the module is r10k-control this branch will be dev,
201
+ # if the module is not r10k-control we use master
187
202
  def src_branch
188
- r10k_module? ? 'dev' : 'master'
203
+ options[:src_branch] || (r10k_module? ? 'dev' : 'master')
189
204
  end
190
205
 
206
+ # pushes the source and tags
191
207
  def push_to_upstream
192
208
  push_branch(source, src_branch)
193
209
  push_tags(source)
@@ -230,6 +246,9 @@ class PuppetModule < WorkflowAction
230
246
  end
231
247
  end
232
248
 
249
+ # @param tag [String] - the name of the tag
250
+ # @param remote [String] - check the remote for the tag, defaults to false
251
+ # @return [Boolean] - returns true if the tag exists
233
252
  def tag_exists?(tag, remote = false)
234
253
  if remote
235
254
  remote_tag_exists?(source, tag)
@@ -238,14 +257,18 @@ class PuppetModule < WorkflowAction
238
257
  end
239
258
  end
240
259
 
260
+ # creates a file with the puppet metadata.json content written to disk
241
261
  def to_metadata_file
242
262
  logger.info("Writing to file #{metadata_file}")
243
263
  File.write(metadata_file, to_s)
244
264
  end
245
265
 
246
266
  # @return [ControlRepo] - creates a new control repo object and clones the url unless already cloned
267
+ # @param url [String] - the upstream url
268
+ # @param branch [String] - the source branch
247
269
  def self.create(path, url, branch = 'master')
248
- c = PuppetModule.new(path, url)
270
+ options = {upstream: url, src_branch: branch}
271
+ c = PuppetModule.new(path, options)
249
272
  c.clone(url, path)
250
273
  c
251
274
  end
@@ -11,9 +11,11 @@ class Release
11
11
  end
12
12
 
13
13
  def puppet_module
14
- @puppet_module ||= PuppetModule.new(path, upstream_repo)
14
+ @puppet_module ||= PuppetModule.new(path, {upstream: upstream_repo,
15
+ src_branch: options[:src_branch]})
15
16
  end
16
17
 
18
+ # @return [String] - the url of the repository defined in the options or environment variable
17
19
  def upstream_repo
18
20
  options[:repo] || ENV['UPSTREAM_REPO']
19
21
  end
@@ -156,7 +158,7 @@ class Release
156
158
  def run
157
159
  begin
158
160
  exit -1 unless check_requirements
159
- puppet_module.create_dev_branch
161
+ puppet_module.create_src_branch
160
162
  value = release
161
163
  unless value
162
164
  exit 1
@@ -47,8 +47,10 @@ class Sandbox
47
47
  end
48
48
 
49
49
  # @return [ControlRepo] - creates a new control repo object and clones the url unless already cloned
50
- # @param [String] url - the url to clone and fork
51
- def setup_control_repo(url)
50
+ # @param url [String] - the url to clone and fork
51
+ # @param src_target [String] - the source to checkout from, defaults to 'upstream/dev'
52
+ def setup_control_repo(url, src_target = 'upstream/dev')
53
+ src_target ||= 'upstream/dev'
52
54
  # clone r10k unless already cloned
53
55
  puts "## r10k-control ##".yellow
54
56
  fork = create_repo_fork(url)
@@ -57,9 +59,10 @@ class Sandbox
57
59
  c.fetch('myfork')
58
60
  c.fetch('origin')
59
61
  c.add_remote(url, 'upstream')
62
+ raise InvalidBranchName.new("The source #{src_target} does not exist") unless c.branch_exist?(src_target)
60
63
  # if the user doesn't have the branch, we create from upstream
61
64
  # and then checkout from the fork, we defer pushing the branch to later after updating the puppetfile
62
- target = c.branch_exist?("upstream/#{name}") ? "upstream/#{name}" : 'upstream/dev'
65
+ target = c.branch_exist?("upstream/#{name}") ? "upstream/#{name}" : src_target
63
66
  # if the user has previously created the branch but doesn't exist locally, no need to create
64
67
  c.create_branch(name, target)
65
68
  c.checkout_branch(name)
@@ -135,9 +138,15 @@ class Sandbox
135
138
  # set upstream to original namespace
136
139
  # cleanup branches
137
140
  def create(r10k_url)
138
- setup_repos_dir(repos_dir)
139
- @control_repo = setup_control_repo(r10k_url)
141
+ begin
142
+ setup_repos_dir(repos_dir)
143
+ @control_repo = setup_control_repo(r10k_url, options[:src_target])
140
144
  # get modules we are interested in
145
+ rescue InvalidBranchName => e
146
+ logger.error(e.message)
147
+ exit 1
148
+ end
149
+
141
150
  module_names.each do | mod_name |
142
151
  puts "## #{mod_name} ##".yellow
143
152
  begin
@@ -209,6 +218,7 @@ class Sandbox
209
218
  # if the user does not pass in the git url we assume the repo already exist
210
219
  # if the repo doesn't exist we clone the url
211
220
  def self.create(name, options)
221
+
212
222
  box = Sandbox.new(name, options[:modules],
213
223
  options[:r10k_repo_path],
214
224
  options[:repos_path], options)
@@ -1,3 +1,3 @@
1
1
  module ReleaseManager
2
- VERSION = "0.7.0"
2
+ VERSION = "0.8.0"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: release_manager
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.7.0
4
+ version: 0.8.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Corey Osman
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2017-10-25 00:00:00.000000000 Z
11
+ date: 2017-12-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: gitlab