labclient 0.1.2 → 0.1.3
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/lib/labclient.rb +7 -4
- data/lib/labclient/branches/branch.rb +25 -0
- data/lib/labclient/branches/create.rb +33 -0
- data/lib/labclient/client.rb +2 -2
- data/lib/labclient/epics/epic.rb +13 -0
- data/lib/labclient/error.rb +1 -0
- data/lib/labclient/files/create.rb +14 -8
- data/lib/labclient/generator/generator.rb +2 -14
- data/lib/labclient/generator/names.rb +17 -3
- data/lib/labclient/generator/template_helper.rb +82 -0
- data/lib/labclient/generator/templates/environments.rb +98 -0
- data/lib/labclient/generator/templates/pages.rb +24 -30
- data/lib/labclient/generator/templates/pipeline_trigger.rb +82 -0
- data/lib/labclient/generator/wizard.rb +23 -7
- data/lib/labclient/http.rb +2 -1
- data/lib/labclient/issues/issue.rb +6 -1
- data/lib/labclient/klass.rb +3 -2
- data/lib/labclient/lab_struct.rb +17 -0
- data/lib/labclient/license/list.rb +2 -2
- data/lib/labclient/merge_requests/accept.rb +15 -6
- data/lib/labclient/merge_requests/create.rb +12 -0
- data/lib/labclient/merge_requests/merge_request.rb +49 -4
- data/lib/labclient/notes/epics/create.rb +4 -4
- data/lib/labclient/notes/epics/delete.rb +3 -3
- data/lib/labclient/notes/epics/list.rb +21 -4
- data/lib/labclient/notes/epics/show.rb +4 -4
- data/lib/labclient/notes/epics/update.rb +4 -4
- data/lib/labclient/notes/issues/create.rb +3 -1
- data/lib/labclient/notes/issues/list.rb +18 -3
- data/lib/labclient/notes/issues/show.rb +1 -1
- data/lib/labclient/notes/merge_requests/list.rb +20 -2
- data/lib/labclient/notes/snippets/create.rb +1 -1
- data/lib/labclient/notes/snippets/list.rb +20 -3
- data/lib/labclient/notes/snippets/show.rb +1 -1
- data/lib/labclient/notifications/update.rb +1 -1
- data/lib/labclient/paginated_response.rb +1 -1
- data/lib/labclient/pipelines/pipeline.rb +41 -0
- data/lib/labclient/projects/methods.rb +30 -2
- data/lib/labclient/projects/reference.rb +5 -0
- data/lib/labclient/projects/snippets/project_snippet.rb +12 -0
- data/lib/labclient/snippets/snippet.rb +2 -2
- data/lib/labclient/users/user.rb +6 -0
- data/lib/labclient/version.rb +1 -1
- metadata +10 -7
- data/lib/labclient/generator/templates/template.rb +0 -23
- data/lib/labclient/open_struct.rb +0 -14
@@ -1,9 +1,24 @@
|
|
1
1
|
module LabClient
|
2
2
|
module Generator
|
3
|
+
# Docs for the wizard
|
4
|
+
class GeneratorDocs
|
5
|
+
doc 'Templates' do
|
6
|
+
title 'Pages'
|
7
|
+
markdown <<~DOC
|
8
|
+
Create GitLab Pages group and test projects. Projects imported from Gitlab's [demo pages projects](https://gitlab.com/pages)
|
9
|
+
|
10
|
+
| Setting | Default | Type | Description |
|
11
|
+
| ---------- | --------- | ------- | -------------------------------------- |
|
12
|
+
| group_name | Generated | String | Parent Group name for pages projects |
|
13
|
+
| group_path | Generated | String | Parent Group path |
|
14
|
+
| count | 5 | Integer | Number of projects to import (max: 28) |
|
15
|
+
DOC
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
3
19
|
# Page Import Creation
|
4
|
-
class Pages <
|
5
|
-
|
6
|
-
attr_accessor :group_name, :group_path, :count
|
20
|
+
class Pages < GroupTemplateHelper
|
21
|
+
attr_accessor :count
|
7
22
|
|
8
23
|
# All Available Pages Projects
|
9
24
|
def list
|
@@ -17,23 +32,10 @@ module LabClient
|
|
17
32
|
end
|
18
33
|
|
19
34
|
def setup
|
20
|
-
|
21
|
-
self.group_path = opts[:group_path] || group_name.downcase.gsub(' ', '-')
|
35
|
+
super
|
22
36
|
self.count = opts[:count] || 5
|
23
37
|
end
|
24
38
|
|
25
|
-
def generate_group
|
26
|
-
@group = client.groups.create(name: group_name, path: group_path)
|
27
|
-
puts "#{@group.name} - #{@group.web_url}"
|
28
|
-
raise 'Unable to Create Group' unless @group.success?
|
29
|
-
end
|
30
|
-
|
31
|
-
def generate_projects
|
32
|
-
@projects = list.sample(count).map do |name|
|
33
|
-
generate_project(name)
|
34
|
-
end
|
35
|
-
end
|
36
|
-
|
37
39
|
def generate_project(name)
|
38
40
|
@group.project_create(
|
39
41
|
name: name,
|
@@ -52,21 +54,13 @@ module LabClient
|
|
52
54
|
@projects.each(&:wait_for_import)
|
53
55
|
end
|
54
56
|
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
generate_projects
|
59
|
-
wait_for_import
|
60
|
-
generate_pipelines
|
61
|
-
|
62
|
-
@projects.each do |project|
|
63
|
-
puts "#{project.name} - #{project.web_url}"
|
57
|
+
def setup_projects
|
58
|
+
@projects = list.sample(count).map do |name|
|
59
|
+
generate_project(name)
|
64
60
|
end
|
65
61
|
|
66
|
-
|
67
|
-
|
68
|
-
projects: @projects
|
69
|
-
}
|
62
|
+
wait_for_import
|
63
|
+
generate_pipelines
|
70
64
|
end
|
71
65
|
end
|
72
66
|
end
|
@@ -0,0 +1,82 @@
|
|
1
|
+
module LabClient
|
2
|
+
module Generator
|
3
|
+
# Docs for the wizard
|
4
|
+
class GeneratorDocs
|
5
|
+
doc 'Templates' do
|
6
|
+
title 'Pipeline Triggers'
|
7
|
+
markdown <<~DOC
|
8
|
+
Create GitLab Pipeline Triggers group and test projects.
|
9
|
+
|
10
|
+
- Child Pipeline: Parent pipeline with artifact, that is then executed as a child pipeline
|
11
|
+
|
12
|
+
| Setting | Default | Type | Description |
|
13
|
+
| ---------- | --------- | ------- | -------------------------------------- |
|
14
|
+
| group_name | Generated | String | Parent Group name for pages projects |
|
15
|
+
| group_path | Generated | String | Parent Group path |
|
16
|
+
DOC
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
# Child and other Trigger Examples
|
21
|
+
# https://docs.gitlab.com/ee/ci/yaml/#trigger
|
22
|
+
class PipelineTrigger < GroupTemplateHelper
|
23
|
+
def setup_projects
|
24
|
+
create_child_pipeline
|
25
|
+
end
|
26
|
+
|
27
|
+
def trigger_child_pipeline_yaml
|
28
|
+
<<~YAML
|
29
|
+
image: busybox:latest
|
30
|
+
|
31
|
+
build_child:
|
32
|
+
stage: build
|
33
|
+
script:
|
34
|
+
- cp child_pipeline.yml artifact.yml
|
35
|
+
artifacts:
|
36
|
+
paths:
|
37
|
+
- artifact.yml
|
38
|
+
|
39
|
+
trigger_child:
|
40
|
+
stage: deploy
|
41
|
+
trigger:
|
42
|
+
include:
|
43
|
+
- artifact: artifact.yml
|
44
|
+
job: build_child
|
45
|
+
|
46
|
+
YAML
|
47
|
+
end
|
48
|
+
|
49
|
+
def child_pipeline_yaml
|
50
|
+
<<~YAML
|
51
|
+
image: busybox:latest
|
52
|
+
|
53
|
+
child:
|
54
|
+
script:
|
55
|
+
- echo "Do your build here"
|
56
|
+
YAML
|
57
|
+
end
|
58
|
+
|
59
|
+
def create_child_pipeline
|
60
|
+
project = @group.project_create(
|
61
|
+
name: 'Child Pipeline',
|
62
|
+
description: 'Child Pipeline',
|
63
|
+
auto_devops_enabled: false
|
64
|
+
)
|
65
|
+
|
66
|
+
# Create Child
|
67
|
+
project.file_create(
|
68
|
+
'child_pipeline.yml',
|
69
|
+
create_file(child_pipeline_yaml)
|
70
|
+
)
|
71
|
+
|
72
|
+
# Create Parent
|
73
|
+
project.file_create(
|
74
|
+
'.gitlab-ci.yml',
|
75
|
+
create_file(trigger_child_pipeline_yaml)
|
76
|
+
)
|
77
|
+
|
78
|
+
@projects.push project
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
@@ -8,7 +8,15 @@ module LabClient
|
|
8
8
|
attr_accessor :count, :random, :password, :templates, :domain
|
9
9
|
|
10
10
|
def inspect
|
11
|
-
"#<Wizard count=#{count}, random=#{random}, domain=#{domain}>"
|
11
|
+
"#<Wizard count=#{count}, random=#{random}, domain=#{domain}> templates=#{templates}"
|
12
|
+
end
|
13
|
+
|
14
|
+
def templates_default
|
15
|
+
%i[pages pipeline_trigger environments]
|
16
|
+
end
|
17
|
+
|
18
|
+
def templates_all
|
19
|
+
LabClient::Generator::TemplateHelper.descendants
|
12
20
|
end
|
13
21
|
|
14
22
|
def initialize(client)
|
@@ -19,16 +27,17 @@ module LabClient
|
|
19
27
|
self.count = default_count
|
20
28
|
self.password = SecureRandom.uuid
|
21
29
|
self.domain = URI.parse(client.settings[:url]).hostname
|
30
|
+
|
31
|
+
# Default Templates
|
32
|
+
self.templates ||= templates_default
|
22
33
|
end
|
23
34
|
|
24
35
|
def template(name, opts = {})
|
25
|
-
|
26
|
-
when :pages then Pages.new(client, opts)
|
27
|
-
end
|
28
|
-
end
|
36
|
+
template_klass = templates_all.find { |x| x.template_name == name.to_sym }
|
29
37
|
|
30
|
-
|
31
|
-
|
38
|
+
raise "Invalid Template! Available Templates: #{templates_all.map(&:template_name).join(', ')}" unless template_klass
|
39
|
+
|
40
|
+
template_klass.new(client, opts)
|
32
41
|
end
|
33
42
|
|
34
43
|
# Random Counters
|
@@ -42,6 +51,7 @@ module LabClient
|
|
42
51
|
end
|
43
52
|
|
44
53
|
def generate_users
|
54
|
+
puts 'Generating Users'
|
45
55
|
@users = @user_names.map do |name|
|
46
56
|
username = name.downcase.gsub(/[^0-9A-Za-z]/, '')
|
47
57
|
email = "#{username}@#{domain}"
|
@@ -57,6 +67,7 @@ module LabClient
|
|
57
67
|
end
|
58
68
|
|
59
69
|
def generate_groups
|
70
|
+
puts 'Generating Groups'
|
60
71
|
@groups = @group_names.map do |name|
|
61
72
|
path = name.downcase.gsub(/[^0-9A-Za-z]/, '')
|
62
73
|
puts "Group -- #{name}/#{path}"
|
@@ -65,6 +76,7 @@ module LabClient
|
|
65
76
|
end
|
66
77
|
|
67
78
|
def generate_group_membership
|
79
|
+
puts 'Adding Group members'
|
68
80
|
## Group Access Level
|
69
81
|
@groups.each do |group|
|
70
82
|
@users.sample(rand(1..@users.count)).each do |user|
|
@@ -81,6 +93,7 @@ module LabClient
|
|
81
93
|
end
|
82
94
|
|
83
95
|
def generate_projects(group)
|
96
|
+
puts 'Generating Projects'
|
84
97
|
# Collect Group Members
|
85
98
|
members = group.members
|
86
99
|
|
@@ -115,6 +128,9 @@ module LabClient
|
|
115
128
|
generate_projects(group)
|
116
129
|
end
|
117
130
|
|
131
|
+
# Run Templates
|
132
|
+
templates.each { |template_klass| template(template_klass).run! }
|
133
|
+
|
118
134
|
nil
|
119
135
|
end
|
120
136
|
end
|
data/lib/labclient/http.rb
CHANGED
@@ -3,6 +3,7 @@ module LabClient
|
|
3
3
|
# Request Helper
|
4
4
|
class HTTP
|
5
5
|
attr_accessor :settings
|
6
|
+
|
6
7
|
def initialize(settings)
|
7
8
|
self.settings = settings
|
8
9
|
end
|
@@ -75,7 +76,7 @@ module Typhoeus
|
|
75
76
|
elsif headers['content-type'] == 'text/plain'
|
76
77
|
body
|
77
78
|
else
|
78
|
-
Oj.load(body, mode: :compat, object_class:
|
79
|
+
Oj.load(body, mode: :compat, object_class: LabClient::LabStruct)
|
79
80
|
end
|
80
81
|
end
|
81
82
|
|
@@ -66,6 +66,10 @@ module LabClient
|
|
66
66
|
client.notes.issues.list(project_id, iid)
|
67
67
|
end
|
68
68
|
|
69
|
+
def note_create(query)
|
70
|
+
client.notes.issues.create(project_id, iid, query)
|
71
|
+
end
|
72
|
+
|
69
73
|
def agent_detail
|
70
74
|
client.issues.agent_detail(project_id, iid)
|
71
75
|
end
|
@@ -100,7 +104,8 @@ module LabClient
|
|
100
104
|
option 'subscribe', 'Subscribe to notifications'
|
101
105
|
option 'unsubscribe', 'Unsubscribe to notifications'
|
102
106
|
option 'participants', 'List participants in this issue.'
|
103
|
-
option 'notes', 'List notes/comments.'
|
107
|
+
option 'notes', 'List notes/comments. [Hash]'
|
108
|
+
option 'note_create', 'Creates a new note for issue. [Hash]'
|
104
109
|
option 'agent_detail', 'Get user agent details.'
|
105
110
|
option 'related_merge_requests', 'Get all related Merge Requests.'
|
106
111
|
option 'closed_by', 'Get all Merge Requests that will close this issue.'
|
data/lib/labclient/klass.rb
CHANGED
@@ -1,14 +1,15 @@
|
|
1
1
|
# Top Namesapce
|
2
2
|
module LabClient
|
3
3
|
# Common Configuration for all Class Helpers
|
4
|
-
class Klass <
|
4
|
+
class Klass < LabStruct
|
5
5
|
include CurlHelper
|
6
6
|
|
7
7
|
attr_reader :client, :response
|
8
|
+
|
8
9
|
extend Docs
|
9
10
|
|
10
11
|
def verbose
|
11
|
-
ap self
|
12
|
+
ap self, ruby19_syntax: true
|
12
13
|
end
|
13
14
|
|
14
15
|
# API Methods here have to be explicitly documented / custom helpers
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# Extensions for OpenStruct specific to LabClient
|
2
|
+
module LabClient
|
3
|
+
# Unique inherited class to not override top level openstruct
|
4
|
+
class LabStruct < OpenStruct
|
5
|
+
def keys
|
6
|
+
to_h.keys.sort
|
7
|
+
end
|
8
|
+
|
9
|
+
def inspect
|
10
|
+
to_h.inspect
|
11
|
+
end
|
12
|
+
|
13
|
+
def as_json(*args)
|
14
|
+
super.as_json['table']
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -32,12 +32,12 @@ module LabClient
|
|
32
32
|
:expires_at => "2050-11-14",
|
33
33
|
:historical_max => 0,
|
34
34
|
:maximum_user_count => 48,
|
35
|
-
:licensee =>
|
35
|
+
:licensee => LabStruct {
|
36
36
|
:Name => "GitLab Henley",
|
37
37
|
:Email => "test_user@gitlab.com",
|
38
38
|
:Company => "GitLab, Inc."
|
39
39
|
},
|
40
|
-
:add_ons =>
|
40
|
+
:add_ons => LabStruct {},
|
41
41
|
:expired => false,
|
42
42
|
:overage => 0,
|
43
43
|
:user_limit => 100,
|
@@ -7,10 +7,19 @@ module LabClient
|
|
7
7
|
desc 'Merge changes submitted with MR. [Project ID, merge request iid]'
|
8
8
|
|
9
9
|
markdown <<~DOC
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
10
|
+
- <small>if merge request is unable to be accepted (ie: Work in Progress, Closed, Pipeline Pending Completion, or Failed while requiring Success) - you'll get a `405` and the error message 'Method Not Allowed'</small>
|
11
|
+
- <small>If it has some conflicts and can not be merged - you'll get a `406` and the error message 'Branch cannot be merged'</small>
|
12
|
+
- <small>If the `sha` parameter is passed and does not match the HEAD of the source - you'll get a `409` and the error message 'SHA </small>does not match HEAD of source branch'
|
13
|
+
- <small>If you don't have permissions to accept this merge request - you'll get a `401`</small>
|
14
|
+
|
15
|
+
| **Attribute** | **Attribute** |
|
16
|
+
| ---------------------------- | ------------------------------------------------------------------------------------------------- |
|
17
|
+
| merge_commit_message | Custom merge commit message |
|
18
|
+
| squash_commit_message | Custom squash commit message |
|
19
|
+
| squash | if true the commits will be squashed into a single commit on merge |
|
20
|
+
| should_remove_source_branch | if true removes the source branch |
|
21
|
+
| merge_when_pipeline_succeeds | if true the MR is merged when the pipeline succeeds |
|
22
|
+
| sha | if present, then this SHA must match the HEAD of the source branch, otherwise the merge will fail |
|
14
23
|
DOC
|
15
24
|
|
16
25
|
example 'client.merge_requests.accept(343, 3)'
|
@@ -29,11 +38,11 @@ module LabClient
|
|
29
38
|
end
|
30
39
|
|
31
40
|
# Accept
|
32
|
-
def accept(project_id, merge_request_id)
|
41
|
+
def accept(project_id, merge_request_id, query = {})
|
33
42
|
project_id = format_id(project_id)
|
34
43
|
merge_request_id = format_id(merge_request_id)
|
35
44
|
|
36
|
-
client.request(:put, "projects/#{project_id}/merge_requests/#{merge_request_id}/merge", MergeRequest)
|
45
|
+
client.request(:put, "projects/#{project_id}/merge_requests/#{merge_request_id}/merge", MergeRequest, query)
|
37
46
|
end
|
38
47
|
end
|
39
48
|
end
|
@@ -41,6 +41,18 @@ module LabClient
|
|
41
41
|
DOC
|
42
42
|
end
|
43
43
|
|
44
|
+
doc 'Create' do
|
45
|
+
desc 'via Project'
|
46
|
+
example <<~DOC
|
47
|
+
project = client.projects.show(264)
|
48
|
+
project.merge_request_create(
|
49
|
+
title: 'New MR!',
|
50
|
+
source_branch: 'sweet-release',
|
51
|
+
target_branch: :master
|
52
|
+
)
|
53
|
+
DOC
|
54
|
+
end
|
55
|
+
|
44
56
|
# Create
|
45
57
|
def create(project_id, query)
|
46
58
|
project_id = format_id(project_id)
|
@@ -51,8 +51,8 @@ module LabClient
|
|
51
51
|
client.merge_requests.delete(project_id, iid)
|
52
52
|
end
|
53
53
|
|
54
|
-
def accept
|
55
|
-
client.merge_requests.accept(project_id, iid)
|
54
|
+
def accept(query = {})
|
55
|
+
client.merge_requests.accept(project_id, iid, query)
|
56
56
|
end
|
57
57
|
|
58
58
|
def merge_ref
|
@@ -99,6 +99,10 @@ module LabClient
|
|
99
99
|
client.notes.merge_requests.list(project_id, iid)
|
100
100
|
end
|
101
101
|
|
102
|
+
def note_create(query)
|
103
|
+
client.notes.merge_requests.create(project_id, iid, query)
|
104
|
+
end
|
105
|
+
|
102
106
|
def todo
|
103
107
|
client.merge_requests.todo(project_id, iid)
|
104
108
|
end
|
@@ -166,9 +170,42 @@ module LabClient
|
|
166
170
|
client.resource_labels.merge_requests.show(project_id, iid, resource_event_id)
|
167
171
|
end
|
168
172
|
|
173
|
+
# Reload
|
174
|
+
def reload
|
175
|
+
update_self client.merge_requests.show(project_id, iid)
|
176
|
+
end
|
177
|
+
|
178
|
+
# Wait for Import / Set a Hard Limit
|
179
|
+
def wait_for_merge_status(total_time = 300, sleep_time = 15)
|
180
|
+
# :unchecked
|
181
|
+
# :cannot_be_merged_recheck
|
182
|
+
# :checking
|
183
|
+
# :cannot_be_merged_rechecking
|
184
|
+
# :can_be_merged
|
185
|
+
# :cannot_be_merged
|
186
|
+
|
187
|
+
# Success
|
188
|
+
# [unchecked, can_be_merged]
|
189
|
+
|
190
|
+
# Fail
|
191
|
+
# [cannot_be_merged cannot_be_merged_recheck]
|
192
|
+
|
193
|
+
Timeout.timeout(total_time) do
|
194
|
+
loop do
|
195
|
+
reload
|
196
|
+
puts "Waiting for Merge Status: #{merge_status}"
|
197
|
+
break if %w[can_be_merged unchecked].include? merge_status
|
198
|
+
raise "Cannot be merged! #{import_error}" if %w[cannot_be_merged cannot_be_merged_recheck].include? merge_status
|
199
|
+
|
200
|
+
sleep sleep_time
|
201
|
+
end
|
202
|
+
end
|
203
|
+
end
|
204
|
+
|
205
|
+
# rubocop:disable Metrics/BlockLength
|
169
206
|
help do
|
170
207
|
subtitle 'MergeRequest'
|
171
|
-
option 'accept', 'Merge changes submitted'
|
208
|
+
option 'accept', 'Merge changes submitted [Hash]'
|
172
209
|
option 'add_time_spent', 'Adds spent time. Accepts Duration or Human Format. (1.hour or "1h")'
|
173
210
|
option 'changes', 'Show merge request changes'
|
174
211
|
option 'closes_issues', 'Show issues that this merge request will close'
|
@@ -176,7 +213,13 @@ module LabClient
|
|
176
213
|
option 'create_pipeline', 'Create new pipeline for this merge request.'
|
177
214
|
option 'delete', 'Delete this merge request.'
|
178
215
|
option 'merge_ref', 'Show Merge Ref'
|
179
|
-
option '
|
216
|
+
option 'reload', 'Reload this merge request object (New API Call)'
|
217
|
+
option 'wait_for_merge_status', 'Looping, wait for merge request status [Timeout, Interval]'
|
218
|
+
|
219
|
+
# Notes
|
220
|
+
option 'notes', 'List notes/comments. [Hash]'
|
221
|
+
option 'note_create', 'Creates a new note. [Hash]'
|
222
|
+
|
180
223
|
option 'participants', 'List participants in this merge request.'
|
181
224
|
option 'pipelines', 'List pipelines in this merge request.'
|
182
225
|
option 'reset_spent_time', 'Resets the spent time'
|
@@ -206,6 +249,8 @@ module LabClient
|
|
206
249
|
option 'resource_labels', 'List of all label events'
|
207
250
|
option 'resource_label', 'Show single label event [Resource Event ID]'
|
208
251
|
end
|
252
|
+
|
253
|
+
# rubocop:enable Metrics/BlockLength
|
209
254
|
end
|
210
255
|
# rubocop:enable Metrics/ClassLength
|
211
256
|
end
|