release_manager 0.3.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 +7 -0
- data/.bash_profile +27 -0
- data/.dockerignore +1 -0
- data/.env +3 -0
- data/.gitignore +13 -0
- data/.rspec +2 -0
- data/CHANGELOG.md +55 -0
- data/Dockerfile +14 -0
- data/Gemfile +14 -0
- data/Gemfile.lock +72 -0
- data/LICENSE.txt +21 -0
- data/README.md +311 -0
- data/Rakefile +6 -0
- data/app_startup_script.sh +4 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/docker-compose.yml +37 -0
- data/exe/bump-changelog +5 -0
- data/exe/deploy-mod +5 -0
- data/exe/release-mod +5 -0
- data/exe/sandbox-create +13 -0
- data/lib/release_manager.rb +33 -0
- data/lib/release_manager/changelog.rb +130 -0
- data/lib/release_manager/cli/deploy_mod_cli.rb +44 -0
- data/lib/release_manager/cli/release_mod_cli.rb +43 -0
- data/lib/release_manager/cli/sandbox_create_cli.rb +138 -0
- data/lib/release_manager/control_mod.rb +83 -0
- data/lib/release_manager/control_repo.rb +35 -0
- data/lib/release_manager/errors.rb +13 -0
- data/lib/release_manager/git/credentials.rb +98 -0
- data/lib/release_manager/git/utilites.rb +263 -0
- data/lib/release_manager/logger.rb +52 -0
- data/lib/release_manager/module_deployer.rb +77 -0
- data/lib/release_manager/puppet_module.rb +211 -0
- data/lib/release_manager/puppetfile.rb +148 -0
- data/lib/release_manager/release.rb +174 -0
- data/lib/release_manager/sandbox.rb +272 -0
- data/lib/release_manager/vcs_manager.rb +22 -0
- data/lib/release_manager/vcs_manager/gitlab_adapter.rb +112 -0
- data/lib/release_manager/vcs_manager/vcs_adapter.rb +22 -0
- data/lib/release_manager/version.rb +3 -0
- data/lib/release_manager/workflow_action.rb +5 -0
- data/release_manager.gemspec +38 -0
- data/setup_repos.rb +95 -0
- metadata +175 -0
@@ -0,0 +1,112 @@
|
|
1
|
+
require 'release_manager/vcs_manager/vcs_adapter'
|
2
|
+
require 'gitlab'
|
3
|
+
module ReleaseManager
|
4
|
+
module VCSManager
|
5
|
+
class GitlabAdapter < ReleaseManager::VCSManager::VcsAdapter
|
6
|
+
attr_reader :client
|
7
|
+
|
8
|
+
def initialize
|
9
|
+
@client = Gitlab.client
|
10
|
+
end
|
11
|
+
|
12
|
+
# creates an instance of the gitlab adapter
|
13
|
+
def self.create
|
14
|
+
new
|
15
|
+
end
|
16
|
+
|
17
|
+
# adds the ssh key to the user of the token
|
18
|
+
def add_ssh_key(public_key_filename = nil)
|
19
|
+
public_key_filename ||= File.expand_path(File.join(ENV['HOME'], '.ssh', 'id_rsa.pub'))
|
20
|
+
title = "#{ENV['USER']}@#{ENV['HOST']}"
|
21
|
+
raise InvalidSshkey.new("Ssh key does not exist #{public_key_filename}") unless File.exist?(public_key_filename)
|
22
|
+
begin
|
23
|
+
client.create_ssh_key(title, File.read(public_key_filename))
|
24
|
+
logger.info("Adding ssh key #{public_key_filename} to gitlab")
|
25
|
+
rescue Gitlab::Error::BadRequest => e
|
26
|
+
# if the key is already added no need to do anything else
|
27
|
+
return unless e.response_status == 400
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def project_name(project_id)
|
32
|
+
client.projects(project_id)
|
33
|
+
end
|
34
|
+
|
35
|
+
# https://docs.gitlab.com/ee/api/members.html
|
36
|
+
def add_permission(username, project_id, access_level = 20)
|
37
|
+
begin
|
38
|
+
project_name = client.project(project_id).path_with_namespace
|
39
|
+
user = client.user_search(username).find{|u| u.username == username}
|
40
|
+
unless user
|
41
|
+
logger.warn("No user found for #{username}")
|
42
|
+
return
|
43
|
+
end
|
44
|
+
unless check_access?(username, project_id, access_level)
|
45
|
+
logger.info("Adding member #{username} to project #{project_name}")
|
46
|
+
client.add_team_member(project_id, user.id, access_level)
|
47
|
+
end
|
48
|
+
rescue Gitlab::Error::BadRequest => e
|
49
|
+
# if the key is already added no need to do anything else
|
50
|
+
logger.warn(e.message)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
def check_access?(username, project_id, access_level)
|
55
|
+
client.team_members(project_id).find { |user| user.username == username && user.access_level == access_level}
|
56
|
+
end
|
57
|
+
|
58
|
+
# https://docs.gitlab.com/ee/api/members.html
|
59
|
+
def add_permissions(project_id, user_ids = [], access_level = 20)
|
60
|
+
user_ids.map {|id| add_permission(id, project_id, access_level)}
|
61
|
+
end
|
62
|
+
|
63
|
+
# @return String - the branch name that was created
|
64
|
+
def create_repo_branch(repo_id, branch_name)
|
65
|
+
Gitlab.repo_create_branch(repo_id, branch_name)
|
66
|
+
end
|
67
|
+
|
68
|
+
def clone_repo(branch_name, mod_name, url, repos_dir)
|
69
|
+
path = File.join(repos_dir, mod_name)
|
70
|
+
Rugged::Repository.clone_at(url, path, checkout_branch: branch_name)
|
71
|
+
end
|
72
|
+
|
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
|
+
|
79
|
+
# @return [Gitlab::ObjectifiedHash] Information about the forked project
|
80
|
+
# @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
|
97
|
+
#
|
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
|
109
|
+
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'release_manager/logger'
|
2
|
+
require 'release_manager/errors'
|
3
|
+
|
4
|
+
module ReleaseManager
|
5
|
+
module VCSManager
|
6
|
+
class VcsAdapter
|
7
|
+
include ReleaseManager::Logger
|
8
|
+
|
9
|
+
def self.create
|
10
|
+
raise NotImplementedError
|
11
|
+
end
|
12
|
+
|
13
|
+
def add_ssh_key(public_key)
|
14
|
+
raise NotImplementedError
|
15
|
+
end
|
16
|
+
|
17
|
+
def add_permission(user, repo)
|
18
|
+
raise NotImplementedError
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'release_manager/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "release_manager"
|
8
|
+
spec.version = ReleaseManager::VERSION
|
9
|
+
spec.authors = ["Corey Osman"]
|
10
|
+
spec.email = ["corey@nwops.io"]
|
11
|
+
|
12
|
+
spec.summary = %q{Release tools for puppet code}
|
13
|
+
spec.description = %q{Release management tools for releasing modules and r10k control repos}
|
14
|
+
spec.homepage = ""
|
15
|
+
spec.license = "MIT"
|
16
|
+
|
17
|
+
# Prevent pushing this gem to RubyGems.org. To allow pushes either set the 'allowed_push_host'
|
18
|
+
# to allow pushing to a single host or delete this section to allow pushing to any host.
|
19
|
+
if spec.respond_to?(:metadata)
|
20
|
+
#spec.metadata['allowed_push_host'] = "TODO: Set to 'http://mygemserver.com'"
|
21
|
+
else
|
22
|
+
raise "RubyGems 2.0 or newer is required to protect against " \
|
23
|
+
"public gem pushes."
|
24
|
+
end
|
25
|
+
|
26
|
+
spec.files = `git ls-files -z`.split("\x0").reject do |f|
|
27
|
+
f.match(%r{^(test|spec|features)/})
|
28
|
+
end
|
29
|
+
spec.bindir = "exe"
|
30
|
+
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
31
|
+
spec.require_paths = ["lib"]
|
32
|
+
spec.add_runtime_dependency "gitlab", "~>3.7.0"
|
33
|
+
spec.add_runtime_dependency "rugged"
|
34
|
+
spec.add_development_dependency "bundler", "~> 1.14"
|
35
|
+
spec.add_development_dependency "pry"
|
36
|
+
spec.add_development_dependency "rake", "~> 10.0"
|
37
|
+
spec.add_development_dependency "rspec", "~> 3.0"
|
38
|
+
end
|
data/setup_repos.rb
ADDED
@@ -0,0 +1,95 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
require 'gitlab'
|
3
|
+
|
4
|
+
def client
|
5
|
+
@client ||= Gitlab.client
|
6
|
+
end
|
7
|
+
|
8
|
+
def devops_group
|
9
|
+
unless @devops_group
|
10
|
+
begin
|
11
|
+
@devops_group = client.create_group('devops', 'devops')
|
12
|
+
rescue Gitlab::Error::BadRequest => e
|
13
|
+
if e.response_status == 400
|
14
|
+
@devops_group = client.group('devops')
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
@devops_group
|
19
|
+
end
|
20
|
+
|
21
|
+
def create_puppet_file(proj)
|
22
|
+
begin
|
23
|
+
client.create_file(proj.id, 'Puppetfile', 'master', puppetfile_content, 'init commit')
|
24
|
+
rescue Gitlab::Error::BadRequest => e
|
25
|
+
if e.response_status == 400
|
26
|
+
# already created
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def create_control_repo
|
32
|
+
begin
|
33
|
+
proj = client.create_project('control-repo', namespace_id: devops_group.id)
|
34
|
+
client.create_branch(proj.id, 'dev')
|
35
|
+
client.create_branch(proj.id, 'production')
|
36
|
+
create_puppet_file(proj)
|
37
|
+
rescue Gitlab::Error::BadRequest => e
|
38
|
+
if e.response_status == 400
|
39
|
+
# already created
|
40
|
+
proj = client.project("devops%2Fcontrol-repo")
|
41
|
+
create_puppet_file(proj)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def modules
|
47
|
+
<<-EOF
|
48
|
+
# Example42 v4.x modules (Used in various profiles)
|
49
|
+
mod 'docker',
|
50
|
+
:git => 'https://github.com/example42/puppet-docker'
|
51
|
+
mod 'network',
|
52
|
+
:git => 'https://github.com/example42/puppet-network'
|
53
|
+
mod 'apache',
|
54
|
+
:git => 'https://github.com/example42/puppet-apache',
|
55
|
+
:branch => '4.x'
|
56
|
+
mod 'puppet',
|
57
|
+
:git => 'https://github.com/example42/puppet-puppet',
|
58
|
+
:branch => 'master'
|
59
|
+
mod 'rails',
|
60
|
+
:git => 'https://github.com/example42/puppet-rails'
|
61
|
+
mod 'ansible',
|
62
|
+
:git => 'https://github.com/example42/puppet-ansible'
|
63
|
+
mod 'icinga',
|
64
|
+
:git => 'https://github.com/example42/puppet-icinga',
|
65
|
+
:branch => '4.x'
|
66
|
+
|
67
|
+
EOF
|
68
|
+
|
69
|
+
end
|
70
|
+
|
71
|
+
def puppetfile_content
|
72
|
+
@puppetfile_content ||= ''
|
73
|
+
end
|
74
|
+
|
75
|
+
def mod(name, *args)
|
76
|
+
url = args.first[:git]
|
77
|
+
begin
|
78
|
+
proj = client.create_project(name, import_url: url, namespace_id: devops_group.id)
|
79
|
+
rescue Gitlab::Error::BadRequest => e
|
80
|
+
if e.response_status == 400
|
81
|
+
proj = client.project("devops%2F#{name}")
|
82
|
+
end
|
83
|
+
end
|
84
|
+
args.first[:git] = proj.ssh_url_to_repo
|
85
|
+
data = args.first.sort.map { |k, v| ":#{k} => '#{v}'" }.join(",\n ")
|
86
|
+
puppetfile_content << "mod '#{name}',\n #{data}\n\n"
|
87
|
+
end
|
88
|
+
|
89
|
+
eval(modules)
|
90
|
+
create_control_repo
|
91
|
+
|
92
|
+
client.create_user('joe@foo.org', 'password', 'joe', { name: 'Joe Smith' })
|
93
|
+
|
94
|
+
# add the ssh key
|
95
|
+
# create_ssh_key(title, key)
|
metadata
ADDED
@@ -0,0 +1,175 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: release_manager
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.3.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Corey Osman
|
8
|
+
autorequire:
|
9
|
+
bindir: exe
|
10
|
+
cert_chain: []
|
11
|
+
date: 2017-05-15 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: gitlab
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ~>
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 3.7.0
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ~>
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 3.7.0
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rugged
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - '>='
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - '>='
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: bundler
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ~>
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '1.14'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ~>
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '1.14'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: pry
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - '>='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - '>='
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: rake
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ~>
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '10.0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ~>
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '10.0'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: rspec
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ~>
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '3.0'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ~>
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '3.0'
|
97
|
+
description: Release management tools for releasing modules and r10k control repos
|
98
|
+
email:
|
99
|
+
- corey@nwops.io
|
100
|
+
executables:
|
101
|
+
- bump-changelog
|
102
|
+
- deploy-mod
|
103
|
+
- release-mod
|
104
|
+
- sandbox-create
|
105
|
+
extensions: []
|
106
|
+
extra_rdoc_files: []
|
107
|
+
files:
|
108
|
+
- .bash_profile
|
109
|
+
- .dockerignore
|
110
|
+
- .env
|
111
|
+
- .gitignore
|
112
|
+
- .rspec
|
113
|
+
- CHANGELOG.md
|
114
|
+
- Dockerfile
|
115
|
+
- Gemfile
|
116
|
+
- Gemfile.lock
|
117
|
+
- LICENSE.txt
|
118
|
+
- README.md
|
119
|
+
- Rakefile
|
120
|
+
- app_startup_script.sh
|
121
|
+
- bin/console
|
122
|
+
- bin/setup
|
123
|
+
- docker-compose.yml
|
124
|
+
- exe/bump-changelog
|
125
|
+
- exe/deploy-mod
|
126
|
+
- exe/release-mod
|
127
|
+
- exe/sandbox-create
|
128
|
+
- lib/release_manager.rb
|
129
|
+
- lib/release_manager/changelog.rb
|
130
|
+
- lib/release_manager/cli/deploy_mod_cli.rb
|
131
|
+
- lib/release_manager/cli/release_mod_cli.rb
|
132
|
+
- lib/release_manager/cli/sandbox_create_cli.rb
|
133
|
+
- lib/release_manager/control_mod.rb
|
134
|
+
- lib/release_manager/control_repo.rb
|
135
|
+
- lib/release_manager/errors.rb
|
136
|
+
- lib/release_manager/git/credentials.rb
|
137
|
+
- lib/release_manager/git/utilites.rb
|
138
|
+
- lib/release_manager/logger.rb
|
139
|
+
- lib/release_manager/module_deployer.rb
|
140
|
+
- lib/release_manager/puppet_module.rb
|
141
|
+
- lib/release_manager/puppetfile.rb
|
142
|
+
- lib/release_manager/release.rb
|
143
|
+
- lib/release_manager/sandbox.rb
|
144
|
+
- lib/release_manager/vcs_manager.rb
|
145
|
+
- lib/release_manager/vcs_manager/gitlab_adapter.rb
|
146
|
+
- lib/release_manager/vcs_manager/vcs_adapter.rb
|
147
|
+
- lib/release_manager/version.rb
|
148
|
+
- lib/release_manager/workflow_action.rb
|
149
|
+
- release_manager.gemspec
|
150
|
+
- setup_repos.rb
|
151
|
+
homepage: ''
|
152
|
+
licenses:
|
153
|
+
- MIT
|
154
|
+
metadata: {}
|
155
|
+
post_install_message:
|
156
|
+
rdoc_options: []
|
157
|
+
require_paths:
|
158
|
+
- lib
|
159
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
160
|
+
requirements:
|
161
|
+
- - '>='
|
162
|
+
- !ruby/object:Gem::Version
|
163
|
+
version: '0'
|
164
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
165
|
+
requirements:
|
166
|
+
- - '>='
|
167
|
+
- !ruby/object:Gem::Version
|
168
|
+
version: '0'
|
169
|
+
requirements: []
|
170
|
+
rubyforge_project:
|
171
|
+
rubygems_version: 2.0.14.1
|
172
|
+
signing_key:
|
173
|
+
specification_version: 4
|
174
|
+
summary: Release tools for puppet code
|
175
|
+
test_files: []
|