release_manager 0.4.0 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -57,12 +57,13 @@ module ReleaseManager
57
57
 
58
58
  # https://docs.gitlab.com/ee/api/members.html
59
59
  def add_permissions(project_id, user_ids = [], access_level = 20)
60
+ user_ids ||= [] # default to empty if nil
60
61
  user_ids.map {|id| add_permission(id, project_id, access_level)}
61
62
  end
62
63
 
63
64
  # @return String - the branch name that was created
64
65
  def create_repo_branch(repo_id, branch_name)
65
- Gitlab.repo_create_branch(repo_id, branch_name)
66
+ client.repo_create_branch(repo_id, branch_name)
66
67
  end
67
68
 
68
69
  def clone_repo(branch_name, mod_name, url, repos_dir)
@@ -70,43 +71,196 @@ module ReleaseManager
70
71
  Rugged::Repository.clone_at(url, path, checkout_branch: branch_name)
71
72
  end
72
73
 
73
- # TODO: extract this out to an adapter
74
- # replaces namespace from the url with the supplied or default namespace
75
- def swap_namespace(url, namespace = nil)
76
- url.gsub(/\:([\w-]+)\//, ":#{namespace || Gitlab.user.username}/")
77
- end
78
-
74
+ # TODO verify the proposed fork does not match the upstream
79
75
  # @return [Gitlab::ObjectifiedHash] Information about the forked project
80
76
  # @param [ControlMod] the module you want to fork
81
- # TODO: extract this out to an adapter
82
- # def create_repo_fork(url, namespace = nil )
83
- # new_url = swap_namespace(url, namespace)
84
- # repo = repo_exists?(new_url)
85
- # unless repo
86
- # upstream_repo_id = repo_id(url)
87
- # logger.info("Forking project from #{url} to #{new_url}")
88
- # repo = Gitlab.create_fork(upstream_repo_id)
89
- # # gitlab lies about having completed the forking process, so lets sleep until it is actually done
90
- # loop do
91
- # sleep(1)
92
- # break if repo_exists?(repo.ssh_url_to_repo)
93
- # end
94
- # end
95
- # repo
96
- # end
77
+ def create_repo_fork(url, options = {} )
78
+ namespace = options[:namespace] || client.user.username
79
+ new_url = swap_namespace(url, namespace)
80
+ repo = repo_exists?(new_url)
81
+ unless repo or url == new_url
82
+ upstream_repo_id = name_to_id(repo_id(url))
83
+ logger.info("Forking project from #{url} to #{new_url}")
84
+ repo = client.create_fork(upstream_repo_id)
85
+ # gitlab lies about having completed the forking process, so lets sleep until it is actually done
86
+ loop do
87
+ sleep(1)
88
+ break if repo_exists?(repo.ssh_url_to_repo)
89
+ end
90
+ end
91
+ add_permissions(repo.id, options[:default_members])
92
+ repo
93
+ end
94
+
95
+ # @param [String] url - a git url
96
+ # @param [String] tag_name The name of the new tag.
97
+ # @param [String] ref The ref (commit sha, branch name, or another tag) the tag will point to.
98
+ # @param [String] message Optional message for tag, creates annotated tag if specified.
99
+ # @param [String] description Optional release notes for tag.
100
+ # @return [Gitlab::ObjectifiedHash]
101
+ def create_tag(url, tag_name, ref, message = nil, description = nil)
102
+ id = repo_id(url)
103
+ logger.info("Creating tag #{tag_name} which points to #{ref}")
104
+ client.create_tag(id, tag_name, ref, message, description)
105
+ end
106
+
107
+ # Creates a single commit with one or more changes
108
+ #
109
+ #
110
+ # @example
111
+ # create_commit(2726132, 'master', 'refactors everything', [{action: 'create', file_path: '/foo.txt', content: 'bar'}])
112
+ # create_commit(2726132, 'master', 'refactors everything', [{action: 'delete', file_path: '/foo.txt'}])
97
113
  #
98
- # # @param [String] url - the git url of the repository
99
- # # @return [Boolean] returns the project object (true) if found, false otherwise
100
- # # TODO: extract this out to an adapter
101
- # def repo_exists?(url)
102
- # upstream_repo_id = repo_id(url)
103
- # begin
104
- # Gitlab.project(upstream_repo_id)
105
- # rescue
106
- # false
107
- # end
108
- # end
114
+ # @param [String] url - a git url
115
+ # @param [String] branch the branch name you wish to commit to
116
+ # @param [String] message the commit message
117
+ # @param [Array[Hash]] An array of action hashes to commit as a batch. See the next table for what attributes it can take.
118
+ # @option options [String] :author_email the email address of the author
119
+ # @option options [String] :author_name the name of the author
120
+ # @return [Gitlab::ObjectifiedHash] hash of commit related data
121
+ def vcs_create_commit(url, branch, message, actions, options={})
122
+ if actions.empty?
123
+ logger.info("Nothing to commit, no changes")
124
+ return false
125
+ end
126
+ project = name_to_id(repo_id(url))
127
+ logger.debug("Creating commit for #{url} on branch #{branch} with project id: #{project}")
128
+ logger.info("Creating commit #{message}")
129
+ client.create_commit(project, branch, message, actions, options)
130
+ end
131
+
132
+ # Creates a merge request.
133
+ #
134
+ # @example
135
+ # create_merge_request(5, 'New merge request',
136
+ # { source_branch: 'source_branch', target_branch: 'target_branch' })
137
+ # create_merge_request(5, 'New merge request',
138
+ # { source_branch: 'source_branch', target_branch: 'target_branch', assignee_id: 42 })
139
+ #
140
+ # @param [String] url - a git url
141
+ # @param [String] title The title of a merge request.
142
+ # @param [Hash] options A customizable set of options.
143
+ # @option options [String] :source_branch (required) The source branch name.
144
+ # @option options [String] :target_branch (required) The target branch name.
145
+ # @option options [Integer] :assignee_id (optional) The ID of a user to assign merge request.
146
+ # @option options [Integer] :target_project_url (optional) The target project url.
147
+ # @return [Gitlab::ObjectifiedHash] Information about created merge request.
148
+ def create_merge_request(url, title, options={})
149
+ logger.debug("Creating merge request at #{url}")
150
+ project = name_to_id(repo_id(url))
151
+ options[:target_project_id] = name_to_id(repo_id(options.delete(:target_project_url))) if options[:target_project_url]
152
+ raise ArgumentError unless options[:source_branch] and options[:target_branch]
153
+ output = client.create_merge_request(project, title, options)
154
+ logger.info("Merge request created: #{output.web_url}")
155
+ output
156
+ end
157
+
158
+ # @param Array[Hash] the changed files in the commit or all the commits in the diff between src and dst
159
+ # @return Array[Hash] the gitlab specific hash of action hashes
160
+ def diff_2_commit(diff_obj)
161
+ diff_obj.map do |obj|
162
+ {
163
+ action: convert_status(obj[:status]),
164
+ file_path: obj[:new_path],
165
+ content: obj[:content]
166
+ }
167
+ end
168
+ end
169
+
170
+ # @param [String] url - a git url
171
+ # @param [String] name The name of the new branch.
172
+ # @param [String] ref The ref (commit sha, branch name, or another tag) the tag will point to.
173
+ def vcs_create_branch(url, name, ref)
174
+ project = name_to_id(repo_id(url))
175
+ logger.info("Creating remote branch #{name} from #{ref}")
176
+ client.create_branch(project, name, ref)
177
+ end
178
+
179
+ def remote_tags(url)
180
+ project = name_to_id(repo_id(url))
181
+ client.tags(project).map(&:name)
182
+ end
183
+
184
+ def remote_tag_names(url)
185
+ remote_tags(url)
186
+ end
187
+
188
+ def remote_tag_exists?(url, tag)
189
+ begin
190
+ project = name_to_id(repo_id(url))
191
+ client.tag(project, tag)
192
+ rescue Gitlab::Error::NotFound
193
+ false
194
+ end
195
+ end
196
+
197
+ private
198
+
199
+ # converts the git status symbol to the status required for gitlab
200
+ # @param [Symbol] status the status symbol
201
+ # @return [String] the string conversion of the status to gitlab action name
202
+ def convert_status(status)
203
+ case status
204
+ when :added
205
+ 'create'
206
+ when :deleted
207
+ 'delete'
208
+ when :modified
209
+ 'update'
210
+ when :renamed
211
+ 'move'
212
+ else
213
+ raise ArgumentError
214
+ end
215
+ end
216
+
217
+ # @param namespace [String] - the namespace / project name
218
+ # @return [Integer] - the id number of the project
219
+ def name_to_id(namespace)
220
+ p = client.project(namespace)
221
+ p.id
222
+ end
223
+
224
+ # @param [String] url - a git url
225
+ # @return [String] a string representing the project id from gitlab
226
+ # gets the project id from gitlab using the remote API
227
+ def repo_id(url)
228
+ # ie. git@server:namespace/project.git
229
+ proj = url.match(/:(.*\/.*)\.git/)
230
+ raise RepoNotFound unless proj
231
+ proj[1]
232
+ end
233
+
234
+ # @param [String] url - the git url of the repository
235
+ # @return [Boolean] returns the project object (true) if found, false otherwise
236
+ def repo_exists?(url)
237
+ upstream_repo_id = repo_id(url)
238
+ begin
239
+ client.project(upstream_repo_id)
240
+ rescue Gitlab::Error::NotFound => e
241
+ false
242
+ end
243
+ end
244
+
245
+ # replaces namespace from the url with the supplied or default namespace
246
+ def swap_namespace(url, namespace = nil)
247
+ url.gsub(/\:([\w-]+)\//, ":#{namespace || client.user.username}/")
248
+ end
109
249
 
110
250
  end
111
251
  end
112
- end
252
+ end
253
+
254
+ #class Gitlab::Client
255
+ # monkey patch correct api method until next version is released
256
+ # module Commits
257
+ # def create_commit(project, branch, message, actions, options={})
258
+ # payload = {
259
+ # branch: branch,
260
+ # commit_message: message,
261
+ # actions: actions,
262
+ # }.merge(options)
263
+ # post("/projects/#{url_encode project}/repository/commits", body: payload)
264
+ # end
265
+ # end
266
+ #end
@@ -17,6 +17,109 @@ module ReleaseManager
17
17
  def add_permission(user, repo)
18
18
  raise NotImplementedError
19
19
  end
20
+
21
+ def create_repo_fork(url, options = {} )
22
+ raise NotImplementedError
23
+ end
24
+
25
+ def swap_namespace(url, namespace = nil)
26
+ raise NotImplementedError
27
+ end
28
+
29
+ def clone_repo(mod_name, url)
30
+ raise NotImplementedError
31
+ end
32
+
33
+ def create_repo_branch(repo_id, branch_name)
34
+ raise NotImplementedError
35
+ end
36
+
37
+ def repo_exists?(url)
38
+ raise NotImplementedError
39
+ end
40
+
41
+ def repo_id(url)
42
+ raise NotImplementedError
43
+ end
44
+
45
+ # @param [String] url - a git url
46
+ # @param [String] name The name of the new branch.
47
+ # @param [String] ref The ref (commit sha, branch name, or another tag) the tag will point to.
48
+ def vcs_create_branch(url, name, ref)
49
+ raise NotImplementedError
50
+ end
51
+
52
+ # @param [String] url - a git url
53
+ # @param [String] mr_id The id of the merge request
54
+ def rebase_mr(url, mr_id)
55
+ raise NotImplementedError
56
+ end
57
+
58
+ # @param [String] url - a git url
59
+ # @param [String] tag_name The name of the new tag.
60
+ # @param [String] ref The ref (commit sha, branch name, or another tag) the tag will point to.
61
+ # @param [String] message Optional message for tag, creates annotated tag if specified.
62
+ # @param [String] description Optional release notes for tag.
63
+ # @return [Gitlab::ObjectifiedHash]
64
+ def create_tag(url, tag_name, ref, message = nil, description = nil)
65
+ raise NotImplementedError
66
+ end
67
+
68
+ # Creates a single commit with one or more changes
69
+ #
70
+ # @example
71
+ # create_commit(2726132, 'master', 'refactors everything', [{action: 'create', file_path: '/foo.txt', content: 'bar'}])
72
+ # create_commit(2726132, 'master', 'refactors everything', [{action: 'delete', file_path: '/foo.txt'}])
73
+ #
74
+ # @param [String] url - a git url
75
+ # @param [String] branch the branch name you wish to commit to
76
+ # @param [String] message the commit message
77
+ # @param [Array[Hash]] An array of action hashes to commit as a batch. See the next table for what attributes it can take.
78
+ # @option options [String] :author_email the email address of the author
79
+ # @option options [String] :author_name the name of the author
80
+ # @return [Gitlab::ObjectifiedHash] hash of commit related data
81
+ def vcs_create_commit(url, branch, message, actions, options={})
82
+ raise NotImplementedError
83
+ end
84
+
85
+ # Creates a merge request.
86
+ #
87
+ # @example
88
+ # create_merge_request(5, 'New merge request',
89
+ # { source_branch: 'source_branch', target_branch: 'target_branch' })
90
+ # create_merge_request(5, 'New merge request',
91
+ # { source_branch: 'source_branch', target_branch: 'target_branch', assignee_id: 42 })
92
+ #
93
+ # @param [Integer, String] project The ID or name of a project.
94
+ # @param [String] title The title of a merge request.
95
+ # @param [Hash] options A customizable set of options.
96
+ # @option options [String] :source_branch (required) The source branch name.
97
+ # @option options [String] :target_branch (required) The target branch name.
98
+ # @option options [Integer] :assignee_id (optional) The ID of a user to assign merge request.
99
+ # @option options [Integer] :target_project_id (optional) The target project ID.
100
+ # @return [Gitlab::ObjectifiedHash] Information about created merge request.
101
+ def create_merge_request(project, title, options={})
102
+ raise NotImplementedError
103
+ end
104
+
105
+ # @param Array[Hash] the changed files in the commit or all the commits in the diff between src and dst
106
+ # @return Array[Hash]
107
+ def diff_2_commit(diff_obj)
108
+ raise NotImplementedError
109
+ end
110
+
111
+ def remote_tags(url)
112
+ raise NotImplementedError
113
+ end
114
+
115
+ def remote_tag_names(url)
116
+ raise NotImplementedError
117
+ end
118
+
119
+ def remote_tag_exists?(url, tag)
120
+ raise NotImplementedError
121
+ end
122
+
20
123
  end
21
124
  end
22
125
  end
@@ -1,7 +1,18 @@
1
1
  require 'release_manager/vcs_manager/gitlab_adapter'
2
-
2
+ require 'forwardable'
3
3
  module ReleaseManager
4
4
  module VCSManager
5
+ extend Forwardable
6
+ attr_accessor :vcs
7
+ def_delegators :vcs, :add_ssh_key, :add_permission, :create_repo_fork, :swap_namespace, :create_tag,
8
+ :clone_repo, :create_repo_branch, :repo_exists?, :repo_id, :add_permissions,
9
+ :vcs_create_commit, :create_merge_request, :diff_2_commit, :vcs_create_branch, :rebase_mr,
10
+ :remote_tags, :remote_tag_names, :remote_tag_exists?
11
+
12
+ def vcs
13
+ @vcs ||= ReleaseManager::VCSManager.default_instance
14
+ end
15
+
5
16
  def self.default_instance
6
17
  ReleaseManager::VCSManager::GitlabAdapter.create
7
18
  end
@@ -1,3 +1,3 @@
1
1
  module ReleaseManager
2
- VERSION = "0.4.0"
2
+ VERSION = "0.5.0"
3
3
  end
@@ -29,8 +29,8 @@ Gem::Specification.new do |spec|
29
29
  spec.bindir = "exe"
30
30
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
31
31
  spec.require_paths = ["lib"]
32
- spec.add_runtime_dependency "gitlab", "~>3.7.0"
33
- spec.add_runtime_dependency "rugged"
32
+ spec.add_runtime_dependency "gitlab", "~> 4.2.0"
33
+ spec.add_runtime_dependency "rugged", "~> 0.26"
34
34
  spec.add_runtime_dependency "highline", '~> 1.7'
35
35
  spec.add_development_dependency "bundler", "~> 1.14"
36
36
  spec.add_development_dependency "pry"
data/scratchcode.rb ADDED
@@ -0,0 +1,13 @@
1
+ if remote
2
+ raise NotImplemented
3
+ diff_obj = control_repo.create_diff_obj(src_ref, dest_ref)
4
+ actions = diff_2_commit(diff_obj)
5
+ vcs_create_branch(url, branch_name, dest_ref)
6
+ control_repo.commit(message, diff_obj, branch_name, remote)
7
+ #rebase_mr(url, mr.id)
8
+ #commit = vcs_create_commit(control_repo.url, branch_name, message, actions)
9
+ else
10
+
11
+ opts.on('-r', '--remote-deploy', "Perform a remote deploy (For CI systems)") do |c|
12
+ options[:remote] = c
13
+ end
data/setup_repos.rb CHANGED
@@ -32,6 +32,9 @@ def create_control_repo
32
32
  begin
33
33
  proj = client.create_project('control-repo', namespace_id: devops_group.id)
34
34
  client.create_branch(proj.id, 'dev')
35
+ client.create_branch(proj.id, 'qa')
36
+ client.create_branch(proj.id, 'integration')
37
+ client.create_branch(proj.id, 'acceptance')
35
38
  client.create_branch(proj.id, 'production')
36
39
  create_puppet_file(proj)
37
40
  rescue Gitlab::Error::BadRequest => e
@@ -86,10 +89,10 @@ def mod(name, *args)
86
89
  puppetfile_content << "mod '#{name}',\n #{data}\n\n"
87
90
  end
88
91
 
89
- eval(modules)
90
- create_control_repo
91
-
92
- client.create_user('joe@foo.org', 'password', 'joe', { name: 'Joe Smith' })
92
+ # eval(modules)
93
+ # create_control_repo
94
+ #
95
+ # client.create_user('joe@foo.org', 'password', 'joe', { name: 'Joe Smith' })
93
96
 
94
97
  # add the ssh key
95
98
  # create_ssh_key(title, key)
data/test_release.sh ADDED
@@ -0,0 +1,3 @@
1
+ puts `rm -rf ~/repos`
2
+ puts `bundle exec sandbox-create -n box12323 -m apache`
3
+ bundle exec release-mod -m ~/repos/apache/`
data/test_sandbox.rb ADDED
File without changes
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.0
4
+ version: 0.5.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-06-01 00:00:00.000000000 Z
11
+ date: 2017-07-21 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: gitlab
@@ -16,28 +16,28 @@ dependencies:
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: 3.7.0
19
+ version: 4.2.0
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: 3.7.0
26
+ version: 4.2.0
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: rugged
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - ">="
31
+ - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: '0'
33
+ version: '0.26'
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
- - - ">="
38
+ - - "~>"
39
39
  - !ruby/object:Gem::Version
40
- version: '0'
40
+ version: '0.26'
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: highline
43
43
  requirement: !ruby/object:Gem::Requirement
@@ -114,6 +114,7 @@ email:
114
114
  executables:
115
115
  - bump-changelog
116
116
  - deploy-mod
117
+ - deploy-r10k
117
118
  - release-mod
118
119
  - sandbox-create
119
120
  extensions: []
@@ -123,6 +124,7 @@ files:
123
124
  - ".dockerignore"
124
125
  - ".env"
125
126
  - ".gitignore"
127
+ - ".gitlab-ci-dev.yml"
126
128
  - ".rspec"
127
129
  - CHANGELOG.md
128
130
  - Dockerfile
@@ -137,11 +139,14 @@ files:
137
139
  - docker-compose.yml
138
140
  - exe/bump-changelog
139
141
  - exe/deploy-mod
142
+ - exe/deploy-r10k
140
143
  - exe/release-mod
141
144
  - exe/sandbox-create
142
145
  - lib/release_manager.rb
143
146
  - lib/release_manager/changelog.rb
147
+ - lib/release_manager/cli/bump_changelog_cli.rb
144
148
  - lib/release_manager/cli/deploy_mod_cli.rb
149
+ - lib/release_manager/cli/deploy_r10k_cli.rb
145
150
  - lib/release_manager/cli/release_mod_cli.rb
146
151
  - lib/release_manager/cli/sandbox_create_cli.rb
147
152
  - lib/release_manager/control_mod.rb
@@ -153,7 +158,9 @@ files:
153
158
  - lib/release_manager/module_deployer.rb
154
159
  - lib/release_manager/puppet_module.rb
155
160
  - lib/release_manager/puppetfile.rb
161
+ - lib/release_manager/r10k_deployer.rb
156
162
  - lib/release_manager/release.rb
163
+ - lib/release_manager/remote_release.rb
157
164
  - lib/release_manager/sandbox.rb
158
165
  - lib/release_manager/vcs_manager.rb
159
166
  - lib/release_manager/vcs_manager/gitlab_adapter.rb
@@ -161,7 +168,10 @@ files:
161
168
  - lib/release_manager/version.rb
162
169
  - lib/release_manager/workflow_action.rb
163
170
  - release_manager.gemspec
171
+ - scratchcode.rb
164
172
  - setup_repos.rb
173
+ - test_release.sh
174
+ - test_sandbox.rb
165
175
  homepage: ''
166
176
  licenses:
167
177
  - MIT