release_manager 0.4.0 → 0.5.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.
@@ -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