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 +4 -4
- data/CHANGELOG.md +5 -1
- data/Gemfile +1 -1
- data/Gemfile.lock +7 -7
- data/README.md +78 -9
- data/lib/release_manager.rb +8 -1
- data/lib/release_manager/cli/deploy_mod_cli.rb +1 -0
- data/lib/release_manager/cli/deploy_r10k_cli.rb +2 -2
- data/lib/release_manager/cli/release_mod_cli.rb +37 -0
- data/lib/release_manager/cli/sandbox_create_cli.rb +12 -8
- data/lib/release_manager/git/utilites.rb +53 -8
- data/lib/release_manager/puppet_module.rb +34 -11
- data/lib/release_manager/release.rb +4 -2
- data/lib/release_manager/sandbox.rb +15 -5
- data/lib/release_manager/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d6069b076747b74494e4aaf2d464abd5436d742b
|
4
|
+
data.tar.gz: 277bbc9bb132f094ccf4cdcc7a761741cd92eaef
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 892cde4d6302725ada12b0b1e89f2854d61fac8d375492b1916a5d5d8e5cce99c6871107a2f8cac1bdd1a5cf2b51427297fdd7c0501448d7e6530ac9bd72ce46
|
7
|
+
data.tar.gz: 1fbc83551bdb199c07ea26835e98e0d9ddff4195de16ff5845419dff6f665b4024dd2518dc74322cd8ae381e7941b00372de578ae18c66687f9f60a3938b0486
|
data/CHANGELOG.md
CHANGED
@@ -1,6 +1,10 @@
|
|
1
1
|
# Release Manager
|
2
2
|
|
3
|
-
##
|
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
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
release_manager (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.
|
25
|
-
ast (~> 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.
|
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.
|
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.
|
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
|
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.
|
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'
|
data/lib/release_manager.rb
CHANGED
@@ -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
|
-
|
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/
|
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/
|
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]
|
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
|
-
|
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
|
-
|
102
|
-
|
103
|
-
|
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
|
-
|
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
|
-
|
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
|
-
@
|
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
|
-
#
|
177
|
-
|
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(
|
186
|
+
create_branch(branch, "upstream/#{branch}")
|
180
187
|
# ensure we have updated our local branch
|
181
|
-
checkout_branch(
|
182
|
-
rebase_branch(
|
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
|
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
|
-
|
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.
|
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]
|
51
|
-
|
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}" :
|
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
|
-
|
139
|
-
|
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)
|
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.
|
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-
|
11
|
+
date: 2017-12-11 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: gitlab
|