release_manager 0.7.0 → 0.8.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 +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
|