gitlab_support_readiness 1.0.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.
Files changed (41) hide show
  1. checksums.yaml +7 -0
  2. data/lib/support_readiness/client.rb +108 -0
  3. data/lib/support_readiness/gitlab/client.rb +64 -0
  4. data/lib/support_readiness/gitlab/configuration.rb +46 -0
  5. data/lib/support_readiness/gitlab/groups.rb +180 -0
  6. data/lib/support_readiness/gitlab/issues.rb +410 -0
  7. data/lib/support_readiness/gitlab/namespaces.rb +190 -0
  8. data/lib/support_readiness/gitlab/projects.rb +510 -0
  9. data/lib/support_readiness/gitlab/repositories.rb +267 -0
  10. data/lib/support_readiness/gitlab/users.rb +488 -0
  11. data/lib/support_readiness/gitlab.rb +19 -0
  12. data/lib/support_readiness/pagerduty/client.rb +66 -0
  13. data/lib/support_readiness/pagerduty/configuration.rb +43 -0
  14. data/lib/support_readiness/pagerduty/escalation_policies.rb +123 -0
  15. data/lib/support_readiness/pagerduty/schedules.rb +223 -0
  16. data/lib/support_readiness/pagerduty/services.rb +132 -0
  17. data/lib/support_readiness/pagerduty.rb +16 -0
  18. data/lib/support_readiness/redis.rb +90 -0
  19. data/lib/support_readiness/zendesk/articles.rb +210 -0
  20. data/lib/support_readiness/zendesk/automations.rb +304 -0
  21. data/lib/support_readiness/zendesk/client.rb +84 -0
  22. data/lib/support_readiness/zendesk/configuration.rb +49 -0
  23. data/lib/support_readiness/zendesk/group_memberships.rb +256 -0
  24. data/lib/support_readiness/zendesk/groups.rb +249 -0
  25. data/lib/support_readiness/zendesk/job_statuses.rb +188 -0
  26. data/lib/support_readiness/zendesk/macros.rb +267 -0
  27. data/lib/support_readiness/zendesk/organization_fields.rb +233 -0
  28. data/lib/support_readiness/zendesk/organization_memberships.rb +257 -0
  29. data/lib/support_readiness/zendesk/organizations.rb +515 -0
  30. data/lib/support_readiness/zendesk/roles.rb +194 -0
  31. data/lib/support_readiness/zendesk/search.rb +159 -0
  32. data/lib/support_readiness/zendesk/sla_policies.rb +232 -0
  33. data/lib/support_readiness/zendesk/ticket_fields.rb +222 -0
  34. data/lib/support_readiness/zendesk/ticket_forms.rb +290 -0
  35. data/lib/support_readiness/zendesk/tickets.rb +854 -0
  36. data/lib/support_readiness/zendesk/triggers.rb +269 -0
  37. data/lib/support_readiness/zendesk/users.rb +946 -0
  38. data/lib/support_readiness/zendesk/views.rb +469 -0
  39. data/lib/support_readiness/zendesk.rb +31 -0
  40. data/lib/support_readiness.rb +29 -0
  41. metadata +215 -0
@@ -0,0 +1,510 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Defines the module Readiness.
4
+ module Readiness
5
+ # Defines the module GitLab
6
+ module GitLab
7
+ ##
8
+ # Defines the class Projects within the module {Readiness::GitLab}.
9
+ #
10
+ # @author Jason Colyer
11
+ # @since 1.0.0
12
+ # @todo Anything listed on https://docs.gitlab.com/ee/api/projects.html not currently here
13
+ class Projects < Readiness::Client
14
+ attr_accessor :allow_merge_on_skipped_pipeline, :allow_pipeline_trigger_approve_deployment, :analytics_access_level, :approvals_before_merge, :archived, :auto_cancel_pending_pipelines, :autoclose_referenced_issues, :auto_devops_deploy_strategy, :auto_devops_enabled, :avatar_url, :build_git_strategy, :builds_access_level, :build_timeout, :can_create_merge_request_in, :ci_allow_fork_pipelines_to_run_in_parent_project, :ci_config_path, :ci_default_git_depth, :ci_forward_deployment_enabled, :ci_forward_deployment_rollback_allowed, :ci_id_token_sub_claim_components, :ci_job_token_scope_enabled, :ci_pipeline_variables_minimum_override_role, :ci_push_repository_for_job_token_allowed, :ci_restrict_pipeline_cancellation_role, :ci_separated_caches, :compliance_frameworks, :container_registry_access_level, :container_registry_enabled, :container_registry_image_prefix, :created_at, :creator_id, :custom_attributes, :default_branch, :description, :description_html, :emails_disabled, :emails_enabled, :empty_repo, :enforce_auth_checks_on_uploads, :environments_access_level, :external_authorization_classification_label, :feature_flags_access_level, :forked_from_project, :forking_access_level, :forks_count, :group_runners_enabled, :http_url_to_repo, :id, :import_error, :import_status, :import_type, :import_url, :infrastructure_access_level, :issue_branch_template, :issues_access_level, :issues_enabled, :issues_template, :jobs_enabled, :keep_latest_artifact, :last_activity_at, :lfs_enabled, :license, :license_url, :_links, :marked_for_deletion_at, :marked_for_deletion_on, :merge_commit_template, :merge_method, :merge_pipelines_enabled, :merge_requests_access_level, :merge_requests_enabled, :merge_requests_template, :merge_trains_enabled, :merge_trains_skip_train_allowed, :mirror, :model_experiments_access_level, :model_registry_access_level, :monitor_access_level, :mr_default_target_self, :name, :namespace, :name_with_namespace, :only_allow_merge_if_all_discussions_are_resolved, :only_allow_merge_if_all_status_checks_passed, :only_allow_merge_if_pipeline_succeeds, :open_issues_count, :packages_enabled, :pages_access_level, :path, :path_with_namespace, :permissions, :pre_receive_secret_detection_enabled, :prevent_merge_without_jira_issue, :printing_merge_request_link_enabled, :public_jobs, :readme_url, :releases_access_level, :remove_source_branch_after_merge, :repository_access_level, :repository_object_format, :repository_storage, :request_access_enabled, :requirements_access_level, :requirements_enabled, :resolve_outdated_diff_discussions, :restrict_user_defined_variables, :runners_token, :runner_token_expiration_interval, :security_and_compliance_access_level, :security_and_compliance_enabled, :service_desk_address, :service_desk_enabled, :shared_runners_enabled, :shared_with_groups, :snippets_access_level, :snippets_enabled, :squash_commit_template, :squash_option, :ssh_url_to_repo, :star_count, :statistics, :suggestion_commit_message, :tag_list, :topics, :updated_at, :visibility, :warn_about_potentially_unwanted_characters, :web_url, :wiki_access_level, :wiki_enabled
15
+
16
+ ##
17
+ # Creates a new {Readiness::GitLab::Projects} instance
18
+ #
19
+ # @author Jason Colyer
20
+ # @since 1.0.0
21
+ # @param object [Object] An instance of {Readiness::GitLab::Projects}
22
+ # @example
23
+ # require 'support_readiness'
24
+ # Readiness::GitLab::Projects.new
25
+ def initialize(object = {})
26
+ @allow_merge_on_skipped_pipeline = object['allow_merge_on_skipped_pipeline']
27
+ @allow_pipeline_trigger_approve_deployment = object['allow_pipeline_trigger_approve_deployment']
28
+ @analytics_access_level = object['analytics_access_level']
29
+ @approvals_before_merge = object['approvals_before_merge']
30
+ @archived = object['archived']
31
+ @auto_cancel_pending_pipelines = object['auto_cancel_pending_pipelines']
32
+ @autoclose_referenced_issues = object['autoclose_referenced_issues']
33
+ @auto_devops_deploy_strategy = object['auto_devops_deploy_strategy']
34
+ @auto_devops_enabled = object['auto_devops_enabled']
35
+ @avatar_url = object['avatar_url']
36
+ @build_git_strategy = object['build_git_strategy']
37
+ @builds_access_level = object['builds_access_level']
38
+ @build_timeout = object['build_timeout']
39
+ @can_create_merge_request_in = object['can_create_merge_request_in']
40
+ @ci_allow_fork_pipelines_to_run_in_parent_project = object['ci_allow_fork_pipelines_to_run_in_parent_project']
41
+ @ci_config_path = object['ci_config_path']
42
+ @ci_default_git_depth = object['ci_default_git_depth']
43
+ @ci_forward_deployment_enabled = object['ci_forward_deployment_enabled']
44
+ @ci_forward_deployment_rollback_allowed = object['ci_forward_deployment_rollback_allowed']
45
+ @ci_id_token_sub_claim_components = object['ci_id_token_sub_claim_components']
46
+ @ci_job_token_scope_enabled = object['ci_job_token_scope_enabled']
47
+ @ci_pipeline_variables_minimum_override_role = object['ci_pipeline_variables_minimum_override_role']
48
+ @ci_push_repository_for_job_token_allowed = object['ci_push_repository_for_job_token_allowed']
49
+ @ci_restrict_pipeline_cancellation_role = object['ci_restrict_pipeline_cancellation_role']
50
+ @ci_separated_caches = object['ci_separated_caches']
51
+ @compliance_frameworks = object['compliance_frameworks']
52
+ @container_registry_access_level = object['container_registry_access_level']
53
+ @container_registry_enabled = object['container_registry_enabled']
54
+ @container_registry_image_prefix = object['container_registry_image_prefix']
55
+ @created_at = object['created_at']
56
+ @creator_id = object['creator_id']
57
+ @custom_attributes = object['custom_attributes']
58
+ @default_branch = object['default_branch']
59
+ @description = object['description']
60
+ @description_html = object['description_html']
61
+ @emails_disabled = object['emails_disabled']
62
+ @emails_enabled = object['emails_enabled']
63
+ @empty_repo = object['empty_repo']
64
+ @enforce_auth_checks_on_uploads = object['enforce_auth_checks_on_uploads']
65
+ @environments_access_level = object['environments_access_level']
66
+ @external_authorization_classification_label = object['external_authorization_classification_label']
67
+ @feature_flags_access_level = object['feature_flags_access_level']
68
+ @forked_from_project = object['forked_from_project']
69
+ @forking_access_level = object['forking_access_level']
70
+ @forks_count = object['forks_count']
71
+ @group_runners_enabled = object['group_runners_enabled']
72
+ @http_url_to_repo = object['http_url_to_repo']
73
+ @id = object['id']
74
+ @import_error = object['import_error']
75
+ @import_status = object['import_status']
76
+ @import_type = object['import_type']
77
+ @import_url = object['import_url']
78
+ @infrastructure_access_level = object['infrastructure_access_level']
79
+ @issue_branch_template = object['issue_branch_template']
80
+ @issues_access_level = object['issues_access_level']
81
+ @issues_enabled = object['issues_enabled']
82
+ @issues_template = object['issues_template']
83
+ @jobs_enabled = object['jobs_enabled']
84
+ @keep_latest_artifact = object['keep_latest_artifact']
85
+ @last_activity_at = object['last_activity_at']
86
+ @lfs_enabled = object['lfs_enabled']
87
+ @license = object['license']
88
+ @license_url = object['license_url']
89
+ @_links = object['_links']
90
+ @marked_for_deletion_at = object['marked_for_deletion_at']
91
+ @marked_for_deletion_on = object['marked_for_deletion_on']
92
+ @merge_commit_template = object['merge_commit_template']
93
+ @merge_method = object['merge_method']
94
+ @merge_pipelines_enabled = object['merge_pipelines_enabled']
95
+ @merge_requests_access_level = object['merge_requests_access_level']
96
+ @merge_requests_enabled = object['merge_requests_enabled']
97
+ @merge_requests_template = object['merge_requests_template']
98
+ @merge_trains_enabled = object['merge_trains_enabled']
99
+ @merge_trains_skip_train_allowed = object['merge_trains_skip_train_allowed']
100
+ @mirror = object['mirror']
101
+ @model_experiments_access_level = object['model_experiments_access_level']
102
+ @model_registry_access_level = object['model_registry_access_level']
103
+ @monitor_access_level = object['monitor_access_level']
104
+ @mr_default_target_self = object['mr_default_target_self']
105
+ @name = object['name']
106
+ @namespace = object['namespace']
107
+ @name_with_namespace = object['name_with_namespace']
108
+ @only_allow_merge_if_all_discussions_are_resolved = object['only_allow_merge_if_all_discussions_are_resolved']
109
+ @only_allow_merge_if_all_status_checks_passed = object['only_allow_merge_if_all_status_checks_passed']
110
+ @only_allow_merge_if_pipeline_succeeds = object['only_allow_merge_if_pipeline_succeeds']
111
+ @open_issues_count = object['open_issues_count']
112
+ @packages_enabled = object['packages_enabled']
113
+ @pages_access_level = object['pages_access_level']
114
+ @path = object['path']
115
+ @path_with_namespace = object['path_with_namespace']
116
+ @permissions = object['permissions']
117
+ @pre_receive_secret_detection_enabled = object['pre_receive_secret_detection_enabled']
118
+ @prevent_merge_without_jira_issue = object['prevent_merge_without_jira_issue']
119
+ @printing_merge_request_link_enabled = object['printing_merge_request_link_enabled']
120
+ @public_jobs = object['public_jobs']
121
+ @readme_url = object['readme_url']
122
+ @releases_access_level = object['releases_access_level']
123
+ @remove_source_branch_after_merge = object['remove_source_branch_after_merge']
124
+ @repository_access_level = object['repository_access_level']
125
+ @repository_object_format = object['repository_object_format']
126
+ @repository_storage = object['repository_storage']
127
+ @request_access_enabled = object['request_access_enabled']
128
+ @requirements_access_level = object['requirements_access_level']
129
+ @requirements_enabled = object['requirements_enabled']
130
+ @resolve_outdated_diff_discussions = object['resolve_outdated_diff_discussions']
131
+ @restrict_user_defined_variables = object['restrict_user_defined_variables']
132
+ @runners_token = object['runners_token']
133
+ @runner_token_expiration_interval = object['runner_token_expiration_interval']
134
+ @security_and_compliance_access_level = object['security_and_compliance_access_level']
135
+ @security_and_compliance_enabled = object['security_and_compliance_enabled']
136
+ @service_desk_address = object['service_desk_address']
137
+ @service_desk_enabled = object['service_desk_enabled']
138
+ @shared_runners_enabled = object['shared_runners_enabled']
139
+ @shared_with_groups = object['shared_with_groups']
140
+ @snippets_access_level = object['snippets_access_level']
141
+ @snippets_enabled = object['snippets_enabled']
142
+ @squash_commit_template = object['squash_commit_template']
143
+ @squash_option = object['squash_option']
144
+ @ssh_url_to_repo = object['ssh_url_to_repo']
145
+ @star_count = object['star_count']
146
+ @statistics = object['statistics']
147
+ @suggestion_commit_message = object['suggestion_commit_message']
148
+ @tag_list = object['tag_list']
149
+ @topics = object['topics']
150
+ @updated_at = object['updated_at']
151
+ @visibility = object['visibility']
152
+ @warn_about_potentially_unwanted_characters = object['warn_about_potentially_unwanted_characters']
153
+ @web_url = object['web_url']
154
+ @wiki_access_level = object['wiki_access_level']
155
+ @wiki_enabled = object['wiki_enabled']
156
+ end
157
+
158
+ ##
159
+ # Lists projects. Does not stop until it ends or the page limit is hit.
160
+ # This method can take a long time to run depending on the parameters used.
161
+ #
162
+ # @author Jason Colyer
163
+ # @since 1.0.0
164
+ # @param client [Object] An instance of {Readiness::GitLab::Client}
165
+ # @param limit [Integer] The number of pages to stop at. Using 0 means to list all.
166
+ # @param filters [Array] An array of filter Strings to use. Should be in the format of key=value
167
+ # @return [Array]
168
+ # @see https://docs.gitlab.com/ee/api/projects.html#list-all-projects GitLab API > Projects > List all projects
169
+ # @example
170
+ # require 'support_readiness'
171
+ # config = Readiness::GitLab::Configuration.new
172
+ # config.token = 'test123abc'
173
+ # client = Readiness::GitLab::Client.new(config)
174
+ # projects = Readiness::GitLab::Projects.list(client, 1)
175
+ # pp projects.count
176
+ # # => 100
177
+ def self.list(client, limit = 0, filters = [])
178
+ array = []
179
+ url = "projects?per_page=100&pagination=keyset&order_by=id&sort=asc&id_after=0&#{to_param_string(filters)}"
180
+ loop do
181
+ response = client.connection.get url
182
+ handle_request_error(0, 'GitLab', response.status) unless response.status == 200
183
+ body = Oj.load(response.body)
184
+ array += body.map { |p| Projects.new(p) }
185
+ break if body.count < 100
186
+ break if limit != 0 && array.count >= (limit * 100)
187
+
188
+ url = "projects?per_page=100&pagination=keyset&order_by=id&sort=asc&id_after=#{body.last['id']}&#{to_param_string(filters)}"
189
+ end
190
+ array
191
+ end
192
+
193
+ ##
194
+ # Locates a project within GitLab. This will not exit on error (except Authentication errors)
195
+ #
196
+ # @author Jason Colyer
197
+ # @since 1.0.0
198
+ # @param client [Object] An instance of {Readiness::GitLab::Client}
199
+ # @param pid [Integer] The project ID to find
200
+ # @param attributes [Array] An array of attribute Strings to use. Should be in the format of key=value
201
+ # @return [Hash]
202
+ # @see https://docs.gitlab.com/ee/api/projects.html#get-single-project GitLab API > Projects > Get single project
203
+ # @example
204
+ # require 'support_readiness'
205
+ # config = Readiness::GitLab::Configuration.new
206
+ # config.token = 'test123abc'
207
+ # client = Readiness::GitLab::Client.new(config)
208
+ # project = Readiness::GitLab::Projects.find(client, 1083469)
209
+ # pp project.web_url
210
+ # # => "https://gitlab.com/gitlab-com/support/support-team-meta"
211
+ def self.find(client, pid, attributes = [])
212
+ response = client.connection.get("projects/#{pid}?#{to_param_string(attributes)}")
213
+ handle_request_error(0, 'GitLab', response.status, { action: 'get', id: pid }) unless response.status == 200
214
+ return Projects.new(Oj.load(response.body)) if response.status == 200
215
+
216
+ Oj.load(response.body)
217
+ end
218
+
219
+ ##
220
+ # Locates a project within GitLab. This will exit on error
221
+ #
222
+ # @author Jason Colyer
223
+ # @since 1.0.0
224
+ # @param client [Object] An instance of {Readiness::GitLab::Client}
225
+ # @param pid [Integer] The project ID to find
226
+ # @param attributes [Array] An array of attribute Strings to use. Should be in the format of key=value
227
+ # @return [Object] An instance of {Readiness::GitLab::Projects}
228
+ # @see https://docs.gitlab.com/ee/api/projects.html#get-single-project GitLab API > Projects > Get single project
229
+ # @example
230
+ # require 'support_readiness'
231
+ # config = Readiness::GitLab::Configuration.new
232
+ # config.token = 'test123abc'
233
+ # client = Readiness::GitLab::Client.new(config)
234
+ # project = Readiness::GitLab::Projects.find!(client, 1083469)
235
+ # pp project.web_url
236
+ # # => "https://gitlab.com/gitlab-com/support/support-team-meta"
237
+ def self.find!(client, pid, attributes = [])
238
+ response = client.connection.get("projects/#{pid}?#{to_param_string(attributes)}")
239
+ handle_request_error(1, 'GitLab', response.status, { action: 'Find project', id: pid }) unless response.status == 200
240
+ Projects.new(Oj.load(response.body))
241
+ end
242
+
243
+ ##
244
+ # Search for a project by name.
245
+ # This method can take a long time to run depending on the number of results found.
246
+ #
247
+ # @author Jason Colyer
248
+ # @since 1.0.0
249
+ # @param client [Object] An instance of {Readiness::GitLab::Client}
250
+ # @param query [String] The name to search for
251
+ # @return [Array]
252
+ # @see https://docs.gitlab.com/ee/api/projects.html#search-for-projects-by-name GitLab API > Projects > Search for projects by name
253
+ # @example
254
+ # require 'support_readiness'
255
+ # config = Readiness::GitLab::Configuration.new
256
+ # config.token = 'test123abc'
257
+ # client = Readiness::GitLab::Client.new(config)
258
+ # projects = Readiness::GitLab::Projects.search(client, "support-team-meta")
259
+ # pp projects.first.web_url
260
+ # # => "https://gitlab.com/gitlab-com/support/support-team-meta"
261
+ def self.search(client, query)
262
+ array = []
263
+ url = "projects?per_page=100&pagination=keyset&order_by=id&sort=asc&id_after=0&search=#{query}"
264
+ loop do
265
+ response = client.connection.get url
266
+ handle_request_error(0, 'GitLab', response.status) unless response.status == 200
267
+ body = Oj.load(response.body)
268
+ array += body.map { |p| Projects.new(p) }
269
+ break if body.count < 100
270
+
271
+ url = "projects?per_page=100&pagination=keyset&order_by=id&sort=asc&id_after=#{body.last['id']}&search=#{query}"
272
+ end
273
+ array
274
+ end
275
+
276
+ ##
277
+ # Lists all access tokens for a project
278
+ #
279
+ # @author Jason Colyer
280
+ # @since 1.0.0
281
+ # @param client [Object] An instance of {Readiness::GitLab::Client}
282
+ # @param project [Object] An instance of {Readiness::GitLab::Projects}
283
+ # @return [Array]
284
+ # @see https://docs.gitlab.com/ee/api/project_access_tokens.html#list-project-access-tokens GitLab API > Projects > Access tokens > List project access tokens
285
+ # @example
286
+ # require 'support_readiness'
287
+ # config = Readiness::GitLab::Configuration.new
288
+ # config.token = 'test123abc'
289
+ # client = Readiness::GitLab::Client.new(config)
290
+ # project = Readiness::GitLab::Projects.find!(client, 1083469)
291
+ # tokens = Readiness::GitLab::Projects.access_tokens(client, project)
292
+ # pp tokens.first['active']
293
+ # # => false
294
+ def self.access_tokens(client, project)
295
+ response = client.connection.get "projects/#{project.id}/access_tokens"
296
+ handle_request_error(0, 'GitLab', response.status) unless response.status == 200
297
+ Oj.load(response.body)
298
+ end
299
+
300
+ ##
301
+ # Rotates an access token for a project (revokes it and makes a new one with the same user)
302
+ #
303
+ # @author Jason Colyer
304
+ # @since 1.0.0
305
+ # @param client [Object] An instance of {Readiness::GitLab::Client}
306
+ # @param project [Object] An instance of {Readiness::GitLab::Projects}
307
+ # @param tid [Integer] The access token ID to rotate
308
+ # @param expiration [String] The expiration date to use (must be in ISO format)
309
+ # @return [Hash]
310
+ # @see https://docs.gitlab.com/ee/api/project_access_tokens.html#rotate-a-project-access-token GitLab API > Projects > Access tokens > Rotate a project access token
311
+ # @example
312
+ # require 'support_readiness'
313
+ # config = Readiness::GitLab::Configuration.new
314
+ # config.token = 'test123abc'
315
+ # client = Readiness::GitLab::Client.new(config)
316
+ # project = Readiness::GitLab::Projects.find!(client, 1083469)
317
+ # tokens = Readiness::GitLab::Projects.access_tokens(client, project)
318
+ # tokens.select { |t| Date.parse(t['expires_at']) <= (Date.today + 5.days) }.each do |token|
319
+ # new_token = Readiness::GitLab::Projects.rotate_token!(client, project, token['id'])
320
+ # pp new_token['token']
321
+ # end
322
+ # # => "s3cr3t1"
323
+ # # => "s3cr3t2"
324
+ # # => "s3cr3t3"
325
+ def self.rotate_token!(client, project, tid, expiration = (Date.today + 1.year).iso8601)
326
+ response = client.connection.post "projects/#{project.id}/access_tokens/#{tid}/rotate", { expires_at: expiration }.to_json
327
+ handle_request_error(1, 'GitLab', response.status, { action: 'Rotate access token', id: project.id }) unless response.status == 200
328
+ Oj.load(response.body)
329
+ end
330
+
331
+ ##
332
+ # Lists direct members in a project.
333
+ # This method can take a long time to run depending on the parameters used.
334
+ #
335
+ # @author Jason Colyer
336
+ # @since 1.0.0
337
+ # @param client [Object] An instance of {Readiness::GitLab::Client}
338
+ # @param project [Object] An instance of {Readiness::GitLab::Projects}
339
+ # @param filters [Array] An array of filter Strings to use. Should be in the format of key=value
340
+ # @return [Array]
341
+ # @see https://docs.gitlab.com/ee/api/members.html#list-all-members-of-a-group-or-project GitLab API > Members > List all members of a group or project
342
+ # @example
343
+ # require 'support_readiness'
344
+ # config = Readiness::GitLab::Configuration.new
345
+ # config.token = 'test123abc'
346
+ # client = Readiness::GitLab::Client.new(config)
347
+ # project = Readiness::GitLab::Projects.find!(client, 1083469)
348
+ # members = Readiness::GitLab::Projects.members(client, project)
349
+ # pp members.first['username']
350
+ # # => "jsmith"
351
+ def self.members(client, project, filters = [])
352
+ array = []
353
+ page = 1
354
+ loop do
355
+ response = client.connection.get "projects/#{project.id}/members?per_page=100&page=#{page}&#{to_param_string(filters)}"
356
+ handle_request_error(0, 'GitLab', response.status) unless response.status == 200
357
+ body = Oj.load(response.body)
358
+ array += body
359
+ break if body.count < 100
360
+
361
+ page += 1
362
+ end
363
+ array
364
+ end
365
+
366
+ ##
367
+ # Lists all members in a project.
368
+ # This method can take a long time to run depending on the parameters used.
369
+ #
370
+ # @author Jason Colyer
371
+ # @since 1.0.0
372
+ # @param client [Object] An instance of {Readiness::GitLab::Client}
373
+ # @param project [Object] An instance of {Readiness::GitLab::Projects}
374
+ # @param filters [Array] An array of filter Strings to use. Should be in the format of key=value
375
+ # @return [Array]
376
+ # @see https://docs.gitlab.com/ee/api/members.html#list-all-members-of-a-group-or-project-including-inherited-and-invited-members GitLab API > Members > List all members of a group or project including inherited and invited members
377
+ # @example
378
+ # require 'support_readiness'
379
+ # config = Readiness::GitLab::Configuration.new
380
+ # config.token = 'test123abc'
381
+ # client = Readiness::GitLab::Client.new(config)
382
+ # project = Readiness::GitLab::Projects.find!(client, 1083469)
383
+ # members = Readiness::GitLab::Projects.all_members(client, project)
384
+ # pp members.first['username']
385
+ # # => "alice_one"
386
+ def self.all_members(client, project, filters = [])
387
+ array = []
388
+ page = 1
389
+ loop do
390
+ response = client.connection.get "projects/#{project.id}/members/all?per_page=100&page=#{page}&#{to_param_string(filters)}"
391
+ handle_request_error(0, 'GitLab', response.status) unless response.status == 200
392
+ body = Oj.load(response.body)
393
+ array += body
394
+ break if body.count < 100
395
+
396
+ page += 1
397
+ end
398
+ array
399
+ end
400
+
401
+ ##
402
+ # Lists badges in a project.
403
+ #
404
+ # @author Jason Colyer
405
+ # @since 1.0.0
406
+ # @param client [Object] An instance of {Readiness::GitLab::Client}
407
+ # @param project [Object] An instance of {Readiness::GitLab::Projects}
408
+ # @return [Array]
409
+ # @see https://docs.gitlab.com/ee/api/project_badges.html#list-all-badges-of-a-project GitLab API > Projects > Badges > List all badges of a project
410
+ # @example
411
+ # require 'support_readiness'
412
+ # config = Readiness::GitLab::Configuration.new
413
+ # config.token = 'test123abc'
414
+ # client = Readiness::GitLab::Client.new(config)
415
+ # project = Readiness::GitLab::Projects.find!(client, 1083469)
416
+ # badges = Readiness::GitLab::Projects.list_badges(client, project)
417
+ # pp badges.first['name']
418
+ # # => "Coverage"
419
+ def self.list_badges(client, project)
420
+ response = client.connection.get "projects/#{project.id}/badges"
421
+ handle_request_error(0, 'GitLab', response.status) unless response.status == 200
422
+ Oj.load(response.body)
423
+ end
424
+
425
+ ##
426
+ # Creates a badge in a project.
427
+ #
428
+ # @author Jason Colyer
429
+ # @since 1.0.0
430
+ # @param client [Object] An instance of {Readiness::GitLab::Client}
431
+ # @param project [Object] An instance of {Readiness::GitLab::Projects}
432
+ # @param params [Hash] The parameters to use to create the badge
433
+ # @return [Hash]
434
+ # @see https://docs.gitlab.com/ee/api/project_badges.html#add-a-badge-to-a-project GitLab API > Projects > Badges > Add a badge to a project
435
+ # @example
436
+ # require 'support_readiness'
437
+ # config = Readiness::GitLab::Configuration.new
438
+ # config.token = 'test123abc'
439
+ # client = Readiness::GitLab::Client.new(config)
440
+ # project = Readiness::GitLab::Projects.find!(client, 1083469)
441
+ # bdge_params = {
442
+ # link_url: 'https://gitlab.com/gitlab-org/gitlab-foss/commits/main',
443
+ # image_url: 'https://shields.io/my/badge1',
444
+ # name: 'mybadge'
445
+ # }
446
+ # badge = Readiness::GitLab::Projects.create_badge!(client, project, bdge_params)
447
+ # pp badge['id']
448
+ # # => 7
449
+ def self.create_badge!(client, project, params)
450
+ response = client.connection.post "projects/#{project.id}/badges", to_clean_json(params)
451
+ handle_request_error(1, 'GitLab', response.status, { action: 'Create badge', id: project.id }) unless response.status == 200
452
+ Oj.load(response.body)
453
+ end
454
+
455
+ ##
456
+ # Updates a badge in a project.
457
+ #
458
+ # @author Jason Colyer
459
+ # @since 1.0.0
460
+ # @param client [Object] An instance of {Readiness::GitLab::Client}
461
+ # @param project [Object] An instance of {Readiness::GitLab::Projects}
462
+ # @param bid [Integer] The badge ID to update
463
+ # @param params [Hash] The parameters to use to update the badge
464
+ # @return [Hash]
465
+ # @see https://docs.gitlab.com/ee/api/project_badges.html#edit-a-badge-of-a-project GitLab API > Projects > Badges > Edit a badge to a project
466
+ # @example
467
+ # require 'support_readiness'
468
+ # config = Readiness::GitLab::Configuration.new
469
+ # config.token = 'test123abc'
470
+ # client = Readiness::GitLab::Client.new(config)
471
+ # project = Readiness::GitLab::Projects.find!(client, 1083469)
472
+ # bdge_params = {
473
+ # image_url: 'https://shields.io/my/badge'
474
+ # }
475
+ # badge = Readiness::GitLab::Projects.create_badge!(client, project, 7, bdge_params)
476
+ # pp badge['name']
477
+ # # => "mybadge"
478
+ def self.update_badge!(client, project, bid, params)
479
+ response = client.connection.put "projects/#{project.id}/badges/#{bid}", to_clean_json(params)
480
+ handle_request_error(1, 'GitLab', response.status, { action: 'Update badge', id: project.id }) unless response.status == 200
481
+ Oj.load(response.body)
482
+ end
483
+
484
+ ##
485
+ # Deletes a badge in a project.
486
+ #
487
+ # @author Jason Colyer
488
+ # @since 1.0.0
489
+ # @param client [Object] An instance of {Readiness::GitLab::Client}
490
+ # @param project [Object] An instance of {Readiness::GitLab::Projects}
491
+ # @param bid [Integer] The badge ID to update
492
+ # @return [Boolean]
493
+ # @see https://docs.gitlab.com/ee/api/project_badges.html#remove-a-badge-from-a-project GitLab API > Projects > Badges > Remove a badge from a project
494
+ # @example
495
+ # require 'support_readiness'
496
+ # config = Readiness::GitLab::Configuration.new
497
+ # config.token = 'test123abc'
498
+ # client = Readiness::GitLab::Client.new(config)
499
+ # project = Readiness::GitLab::Projects.find!(client, 1083469)
500
+ # badge = Readiness::GitLab::Projects.create_badge!(client, project, 7)
501
+ # pp badge
502
+ # # => true
503
+ def self.delete_badge!(client, project, bid)
504
+ response = client.connection.delete "projects/#{project.id}/badges/#{bid}"
505
+ handle_request_error(1, 'GitLab', response.status, { action: 'Delete badge', id: project.id }) unless response.status == 200
506
+ true
507
+ end
508
+ end
509
+ end
510
+ end