labclient 0.1.2 → 0.1.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (47) hide show
  1. checksums.yaml +4 -4
  2. data/lib/labclient.rb +7 -4
  3. data/lib/labclient/branches/branch.rb +25 -0
  4. data/lib/labclient/branches/create.rb +33 -0
  5. data/lib/labclient/client.rb +2 -2
  6. data/lib/labclient/epics/epic.rb +13 -0
  7. data/lib/labclient/error.rb +1 -0
  8. data/lib/labclient/files/create.rb +14 -8
  9. data/lib/labclient/generator/generator.rb +2 -14
  10. data/lib/labclient/generator/names.rb +17 -3
  11. data/lib/labclient/generator/template_helper.rb +82 -0
  12. data/lib/labclient/generator/templates/environments.rb +98 -0
  13. data/lib/labclient/generator/templates/pages.rb +24 -30
  14. data/lib/labclient/generator/templates/pipeline_trigger.rb +82 -0
  15. data/lib/labclient/generator/wizard.rb +23 -7
  16. data/lib/labclient/http.rb +2 -1
  17. data/lib/labclient/issues/issue.rb +6 -1
  18. data/lib/labclient/klass.rb +3 -2
  19. data/lib/labclient/lab_struct.rb +17 -0
  20. data/lib/labclient/license/list.rb +2 -2
  21. data/lib/labclient/merge_requests/accept.rb +15 -6
  22. data/lib/labclient/merge_requests/create.rb +12 -0
  23. data/lib/labclient/merge_requests/merge_request.rb +49 -4
  24. data/lib/labclient/notes/epics/create.rb +4 -4
  25. data/lib/labclient/notes/epics/delete.rb +3 -3
  26. data/lib/labclient/notes/epics/list.rb +21 -4
  27. data/lib/labclient/notes/epics/show.rb +4 -4
  28. data/lib/labclient/notes/epics/update.rb +4 -4
  29. data/lib/labclient/notes/issues/create.rb +3 -1
  30. data/lib/labclient/notes/issues/list.rb +18 -3
  31. data/lib/labclient/notes/issues/show.rb +1 -1
  32. data/lib/labclient/notes/merge_requests/list.rb +20 -2
  33. data/lib/labclient/notes/snippets/create.rb +1 -1
  34. data/lib/labclient/notes/snippets/list.rb +20 -3
  35. data/lib/labclient/notes/snippets/show.rb +1 -1
  36. data/lib/labclient/notifications/update.rb +1 -1
  37. data/lib/labclient/paginated_response.rb +1 -1
  38. data/lib/labclient/pipelines/pipeline.rb +41 -0
  39. data/lib/labclient/projects/methods.rb +30 -2
  40. data/lib/labclient/projects/reference.rb +5 -0
  41. data/lib/labclient/projects/snippets/project_snippet.rb +12 -0
  42. data/lib/labclient/snippets/snippet.rb +2 -2
  43. data/lib/labclient/users/user.rb +6 -0
  44. data/lib/labclient/version.rb +1 -1
  45. metadata +10 -7
  46. data/lib/labclient/generator/templates/template.rb +0 -23
  47. 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 < TemplateHelper
5
- include Names
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
- self.group_name = opts[:group_name] || "#{gen_groups.sample} Pages"
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
- # Execute Template
56
- def run!
57
- generate_group
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
- group: @group,
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
- case name
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
- def pages(opts = {})
31
- Pages.new(client, opts)
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
@@ -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: OpenStruct)
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.'
@@ -1,14 +1,15 @@
1
1
  # Top Namesapce
2
2
  module LabClient
3
3
  # Common Configuration for all Class Helpers
4
- class Klass < OpenStruct
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 => OpenStruct {
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 => OpenStruct {},
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
- - <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>
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 'notes', 'List notes/comments.'
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