gitlab-customer-support-operations_gitlab 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 (35) hide show
  1. checksums.yaml +7 -0
  2. data/lib/support_ops_gitlab/gitlab/badges.rb +229 -0
  3. data/lib/support_ops_gitlab/gitlab/base.rb +552 -0
  4. data/lib/support_ops_gitlab/gitlab/client.rb +51 -0
  5. data/lib/support_ops_gitlab/gitlab/commits.rb +198 -0
  6. data/lib/support_ops_gitlab/gitlab/configuration.rb +86 -0
  7. data/lib/support_ops_gitlab/gitlab/epics.rb +325 -0
  8. data/lib/support_ops_gitlab/gitlab/events.rb +167 -0
  9. data/lib/support_ops_gitlab/gitlab/gpg_keys.rb +64 -0
  10. data/lib/support_ops_gitlab/gitlab/group_memberships.rb +33 -0
  11. data/lib/support_ops_gitlab/gitlab/groups.rb +431 -0
  12. data/lib/support_ops_gitlab/gitlab/invitations.rb +72 -0
  13. data/lib/support_ops_gitlab/gitlab/issues.rb +606 -0
  14. data/lib/support_ops_gitlab/gitlab/jobs.rb +61 -0
  15. data/lib/support_ops_gitlab/gitlab/markdown.rb +54 -0
  16. data/lib/support_ops_gitlab/gitlab/merge_requests.rb +411 -0
  17. data/lib/support_ops_gitlab/gitlab/milestones.rb +195 -0
  18. data/lib/support_ops_gitlab/gitlab/namespaces.rb +184 -0
  19. data/lib/support_ops_gitlab/gitlab/notes.rb +182 -0
  20. data/lib/support_ops_gitlab/gitlab/pipelines.rb +258 -0
  21. data/lib/support_ops_gitlab/gitlab/project_access_tokens.rb +245 -0
  22. data/lib/support_ops_gitlab/gitlab/project_memberships.rb +33 -0
  23. data/lib/support_ops_gitlab/gitlab/project_webhook_events.rb +33 -0
  24. data/lib/support_ops_gitlab/gitlab/project_webhooks.rb +218 -0
  25. data/lib/support_ops_gitlab/gitlab/projects.rb +741 -0
  26. data/lib/support_ops_gitlab/gitlab/repository_files.rb +102 -0
  27. data/lib/support_ops_gitlab/gitlab/repository_submodules.rb +78 -0
  28. data/lib/support_ops_gitlab/gitlab/ssh_keys.rb +67 -0
  29. data/lib/support_ops_gitlab/gitlab/user_emails.rb +147 -0
  30. data/lib/support_ops_gitlab/gitlab/user_memberships.rb +21 -0
  31. data/lib/support_ops_gitlab/gitlab/user_tokens.rb +344 -0
  32. data/lib/support_ops_gitlab/gitlab/users.rb +1059 -0
  33. data/lib/support_ops_gitlab/gitlab.rb +45 -0
  34. data/lib/support_ops_gitlab.rb +28 -0
  35. metadata +251 -0
@@ -0,0 +1,198 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Defines the module SupportOps.
4
+ module SupportOps
5
+ # Defines the module GitLab
6
+ module GitLab
7
+ ##
8
+ # Defines the class Commits within the module {SupportOps::GitLab}.
9
+ #
10
+ # @author Jason Colyer
11
+ # @since 1.0.0
12
+ # @attr [Array] actions An array of action hashes to commit as a batch; see API documentation on gitlab for more information (create only)
13
+ # @attr [String] authored_date
14
+ # @attr [String] author_email
15
+ # @attr [String] author_name
16
+ # @attr [String] commit_message
17
+ # @attr [String] committed_date
18
+ # @attr [String] committer_email
19
+ # @attr [String] committer_name
20
+ # @attr [String] created_at
21
+ # @attr [Hash] extended_trailers
22
+ # @attr [Boolean] force
23
+ # @attr [String] id
24
+ # @attr [Hash] last_pipeline
25
+ # @attr [String] message
26
+ # @attr [Array] parent_ids
27
+ # @attr [Integer] project_id
28
+ # @attr [String] short_id
29
+ # @attr [String] start_branch
30
+ # @attr [Integer] start_project
31
+ # @attr [String] start_sha
32
+ # @attr [Hash] stats
33
+ # @attr [String] status
34
+ # @attr [String] title
35
+ # @attr [Boolean] trailers Git trailers for a commit
36
+ # @attr [String] web_url
37
+ # @todo Document attributes
38
+ # @todo Stuff at https://docs.gitlab.com/api/commits/
39
+ class Commits < SupportOps::GitLab::Base
40
+ # @!parse
41
+ # # Creates a commit
42
+ # #
43
+ # # @author Jason Colyer
44
+ # # @since 1.0.0
45
+ # # @return [Object] Instance of {SupportOps::GitLab::Commits}
46
+ # # @note This is inherited from {SupportOps::GitLab::Base#save!}
47
+ # # @see
48
+ # # https://docs.gitlab.com/api/commits/#create-a-commit-with-multiple-files-and-actions
49
+ # # GitLab API > Commits > Create a commit with multiple files and actions
50
+ # # @example
51
+ # # require 'support_ops_gitlab'
52
+ # #
53
+ # # SupportOps::GitLab::Configuration.configure do |config|
54
+ # # config.token = ENV.fetch('GL_TOKEN')
55
+ # # config.url = 'https://gitlab.com/api/v4'
56
+ # # end
57
+ # #
58
+ # # new_commit = SupportOps::GitLab::Commits.new
59
+ # # new_commit.branch = 'master'
60
+ # # new_commit.commit_message = 'Changing some stuff'
61
+ # # new_commit.project_id = 123456
62
+ # # new_commit.actions = [
63
+ # # { action: 'create', file_path: 'foo/bar', content: 'some content' },
64
+ # # { action: 'update', file_path: 'foo/bar5', content: 'new content' },
65
+ # # { action: 'delete', file_path': 'foo/bar2' },
66
+ # # { action: 'move', file_path: 'foo/bar3', previous_path: 'foo/bar4', content: 'some content' },
67
+ # # { action: 'chmod', file_path: 'foo/bar5', execute_filemode: true }
68
+ # # ]
69
+ # #
70
+ # # new_commit.save!
71
+ # #
72
+ # # pp new_commit.id
73
+ # # # => "ed899a2f4b50b4370feeea94676502b42383c746"
74
+ # def save!; end
75
+ define_attributes :actions, :authored_date, :author_email, :author_name,
76
+ :commit_message, :committed_date, :committer_email,
77
+ :committer_name, :created_at, :extended_trailers,
78
+ :force, :id, :last_pipeline, :message, :parent_ids,
79
+ :project_id, :short_id, :start_branch, :start_project,
80
+ :start_sha, :stats, :status, :title, :trailers, :web_url
81
+ readonly_attributes :authored_date, :committed_date, :committer_email,
82
+ :committer_name, :created_at, :extended_trailers,
83
+ :id, :last_pipeline, :message, :parent_ids,
84
+ :project_id, :short_id, :stats, :status, :title,
85
+ :trailers, :web_url
86
+
87
+ ##
88
+ # List repository commits
89
+ #
90
+ # @author Jason Colyer
91
+ # @since 1.0.0
92
+ # @overload list(key: value)
93
+ # @param project_id [Integer required] The project ID to look in
94
+ # @param all [Boolean optional] Retrieve every commit from the
95
+ # repository; when set to true, the ref_name parameter is ignored
96
+ # @param author [String optional] Search commits by commit author
97
+ # @param first_parent [Boolean optional] Follow only the first parent
98
+ # commit upon seeing a merge commit
99
+ # @param order [String optional] List commits in order; possible values:
100
+ # default, topo; defaults to default, the commits are shown in reverse
101
+ # chronological order
102
+ # @param path [String optional] The file path
103
+ # @param ref_name [String optional] The name of a repository branch, tag
104
+ # or revision range, or if not given the default branch
105
+ # @param since [String optional] Only commits after or on this date are
106
+ # returned in ISO 8601 format YYYY-MM-DDTHH:MM:SSZ
107
+ # @param until [String optional] Only commits before or on this date are
108
+ # returned in ISO 8601 format YYYY-MM-DDTHH:MM:SSZ
109
+ # @param limit [Integer optional] The limit to the number of users
110
+ # returned. Default to 0 (i.e. no limit)
111
+ # @return [Array]
112
+ # @see
113
+ # https://docs.gitlab.com/api/commits/#list-repository-commits
114
+ # GitLab API > Commits > List repository commits
115
+ # @see SupportOps::GitLab::Configuration Setting up a client
116
+ # @example
117
+ # require 'support_ops_gitlab'
118
+ #
119
+ # SupportOps::GitLab::Configuration.configure do |config|
120
+ # config.url = 'https://gitlab.example.com/api/v4'
121
+ # config.token = 'abc123'
122
+ # end
123
+ #
124
+ # commits = SupportOps::GitLab::Commits.list(project_id: 123)
125
+ # pp commits.count
126
+ # # => 115
127
+ # pp commits.last.title
128
+ # # => "Aweomse commit"
129
+ def self.list(**args)
130
+ args[:project_id] = nil unless args[:project_id]
131
+ raise 'You have to provide a project_id' if args[:project_id].nil?
132
+ args[:all] = nil unless args[:all]
133
+ args[:author] = nil unless args[:author]
134
+ args[:first_parent] = nil unless args[:first_parent]
135
+ args[:order] = nil unless args[:order]
136
+ args[:path] = nil unless args[:path]
137
+ args[:ref_name] = nil unless args[:ref_name]
138
+ args[:since] = nil unless args[:since]
139
+ args[:until] = nil unless args[:until]
140
+ args[:limit] = 0 unless args[:limit]
141
+ params = 'with_stats=true&trailers=true&'
142
+ params += "all=#{args[:all]}&" unless args[:all].nil?
143
+ params += "author=#{args[:author]}&" unless args[:author].nil?
144
+ params += "first_parent=#{args[:first_parent]}&" unless args[:first_parent].nil?
145
+ params += "order=#{args[:order]}&" unless args[:order].nil?
146
+ params += "path=#{args[:path]}&" unless args[:path].nil?
147
+ params += "ref_name=#{args[:ref_name]}&" unless args[:ref_name].nil?
148
+ params += "since=#{args[:since]}&" unless args[:since].nil?
149
+ params += "until=#{args[:until]}&" unless args[:until].nil?
150
+ array = []
151
+ page = 1
152
+ loop do
153
+ response = client.connection.get("projects/#{args[:project_id]}/repository/commits?#{params}&page=#{page}&per_page=100")
154
+ body = Oj.load(response.body)
155
+ array += body.map do |c|
156
+ c['project_id'] = args[:project_id]
157
+ Commits.new(c)
158
+ end
159
+ break if args[:limit].to_i.positive? && array.count >= args[:limit].to_i
160
+ break if body.count < 100
161
+
162
+ page += 1
163
+ end
164
+ return array if args[:limit].to_i.zero?
165
+
166
+ array.first(args[:limit].to_i)
167
+ end
168
+
169
+ private
170
+
171
+ ##
172
+ # @private
173
+ def create_record
174
+ raise 'You have to provide a project_id' if self.project_id.nil?
175
+ raise 'You have to provide actions' if self.actions.nil?
176
+ raise 'You have to provide actions as an array' unless self.actions.is_a? Array
177
+ raise 'You have to provide a branch' if self.branch.nil?
178
+ raise 'You have to provide a commit_message' if self.commit_message.nil?
179
+ data = {
180
+ actions: self.actions,
181
+ branch: self.branch,
182
+ commit_message: self.commit_message
183
+ }
184
+ data[:author_email] = self.author_email unless self.author_email.nil?
185
+ data[:author_name] = self.author_name unless self.author_name.nil?
186
+ data[:force] = self.force unless self.force.nil?
187
+ data[:start_branch] = self.start_branch unless self.start_branch.nil?
188
+ data[:start_project] = self.start_project unless self.start_project.nil?
189
+ data[:start_sha] = self.start_sha unless self.start_sha.nil?
190
+ response = self.client.connection.post("projects/#{self.project_id}/repository/commits", data.to_json)
191
+ body = Oj.load(response.body)
192
+ raise "Failed to create commit => #{body}" unless response.status == 200
193
+ body['project_id'] = self.project_id
194
+ body
195
+ end
196
+ end
197
+ end
198
+ end
@@ -0,0 +1,86 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Defines the module SupportOps.
4
+ module SupportOps
5
+ # Defines the module GitLab
6
+ module GitLab
7
+ ##
8
+ # Defines the module Configuration within the module {SupportOps::GitLab}.
9
+ #
10
+ # @author Jason Colyer
11
+ # @since 1.0.0
12
+ module Configuration
13
+ ##
14
+ # Setup a Zendesk client configuration
15
+ #
16
+ # @author Jason Colyer
17
+ # @since 1.0.0
18
+ # @overload configure(key: value)
19
+ # @param job_token [String] See {Config#job_token}
20
+ # @param retry_backoff [Integer] See {Config#retry_backoff}
21
+ # @param retry_exceptions [Array] See {Config#retry_exceptions}
22
+ # @param retry_interval [Integer] See {Config#retry_interval}
23
+ # @param retry_max [Integer] See {Config#retry_max}
24
+ # @param retry_randomness [Integer] See {Config#retry_randomness}
25
+ # @param token [String] See {Config#token}
26
+ # @param url [String] See {Config#url}
27
+ # @example
28
+ # require 'support_ops_zendesk'
29
+ #
30
+ # SupportOps::GitLab::Configuration.configure do |config|
31
+ # config.url = 'https://gitlab.com/api/v4'
32
+ # config.token = 'abc123'
33
+ # end
34
+ def self.configure
35
+ yield config
36
+ end
37
+
38
+ def self.config
39
+ @config ||= Config.new
40
+ end
41
+
42
+ def self.reset!
43
+ @config = Config.new
44
+ end
45
+
46
+ ##
47
+ # Defined the class Config within the module {SupportOps::GitLab::Configuration}
48
+ #
49
+ # @author Jason Colyer
50
+ # @since 1.0.0
51
+ # @attr [String] job_token The job token to use for authentication
52
+ # @attr [Integer] retry_backoff multiplier applied to the retry_interval after each retry attempt, causing exponential backoff. Defaults to 2
53
+ # @attr [Array] retry_exceptions Specifies which types of exceptions or errors should trigger the retry mechanism.
54
+ # @attr [Integer] retry_interval The base time interval (typically in seconds or milliseconds) between retry attempts. Defaults to 1
55
+ # @attr [Integer] retry_max The maximum number of retry attempts that will be made when an operation fails. Defaults to 5
56
+ # @attr [Float] retry_randomness Adds a random element to the retry interval to prevent "thundering herd" problems where many systems retry simultaneously. Defaults to 0.5
57
+ # @attr [String] token The token to use for authentication
58
+ # @attr [String] url The API url to connect to, it should alwaus be in the format of 'https:\/\/YOUR_DOMAIN.com/api/v4' (note the lack of a trailing /)
59
+ class Config
60
+ attr_accessor :url, :job_token, :token, :retry_max, :retry_interval,
61
+ :retry_randomness, :retry_backoff, :retry_exceptions,
62
+
63
+ def initialize
64
+ @retry_backoff = 2
65
+ @retry_exceptions = Faraday::Retry::Middleware::DEFAULT_EXCEPTIONS + [Faraday::ConnectionFailed]
66
+ @retry_interval = 1
67
+ @retry_max = 5
68
+ @retry_randomness = 0.5
69
+ end
70
+
71
+ def client
72
+ @client ||= Client.new(
73
+ job_token: job_token,
74
+ retry_max: retry_max,
75
+ retry_interval: retry_interval,
76
+ retry_randomness: retry_randomness,
77
+ retry_backoff: retry_backoff,
78
+ retry_exceptions: retry_exceptions,
79
+ url: url,
80
+ token: token
81
+ )
82
+ end
83
+ end
84
+ end
85
+ end
86
+ end
@@ -0,0 +1,325 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Defines the module SupportOps.
4
+ module SupportOps
5
+ # Defines the module GitLab
6
+ module GitLab
7
+ ##
8
+ # Defines the class Epics within the module {SupportOps::GitLab}.
9
+ #
10
+ # @author Jason Colyer
11
+ # @since 1.0.0
12
+ # @attr [Array] add_labels Comma-separated label names to add to an issue
13
+ # @attr [Hash] author Information about the epic author
14
+ # @attr [String] closed_at When the epic was closed
15
+ # @attr [String] color The color of the epic
16
+ # @attr [Boolean] confidential Whether the epic should be confidential
17
+ # @attr [String] created_at When the epic was created
18
+ # @attr [String] description The description of the epic
19
+ # @attr [Integer] downvotes The number of downvotes on an epic
20
+ # @attr [String] due_date When the epic is due
21
+ # @attr [String] due_date_fixed The fixed due date of an epic
22
+ # @attr [String] due_date_from_inherited_source When the epic is due (inherited from the source of the epic)
23
+ # @attr [Boolean] due_date_is_fixed Whether due date should be sourced from due_date_fixed or from milestones
24
+ # @attr [Integer] group_id The ID of the epic's group
25
+ # @attr [Integer] id the ID of the epic
26
+ # @attr [Integer] iid The internal ID of the epic
27
+ # @attr [Boolean] imported If the epic was imported
28
+ # @attr [String] imported_from Where the epic was imported from
29
+ # @attr [Array] labels The comma-separated list of labels
30
+ # @attr [Hash] _links Various links related to the epic
31
+ # @attr [Integer] parent_id The ID of a parent epic
32
+ # @attr [Integer] parent_iid The internal ID of a parent epic
33
+ # @attr [String] reference The reference tag for the epic
34
+ # @attr [Hash] references Reference tags for the epic
35
+ # @attr [Array] remove_labels Comma-separated label names to remove from an issue
36
+ # @attr [String] start_date The start date of the epic
37
+ # @attr [String] start_date_fixed The fixed start date of an epic
38
+ # @attr [String] start_date_from_inherited_source The start date of the epic (inherited from the source of the epic)
39
+ # @attr [Boolean] start_date_is_fixed Whether start date should be sourced from start_date_fixed or from milestones
40
+ # @attr [String] state The current state of the epic
41
+ # @attr [String] state_event State event for an epic; Set 'close' to close the epic and 'reopen' to reopen it
42
+ # @attr [Boolean] subscribed If the authenticated user is subscribed to the epic
43
+ # @attr [String] title The title of the epic
44
+ # @attr [String] updated_at When the epic was updated
45
+ # @attr [Integer] upvotes The number of upvotes on an epic
46
+ # @attr [String] web_url The URL of the epic
47
+ # @todo Single epic > https://docs.gitlab.com/api/epics/#single-epic
48
+ # @todo Create a to-do item > https://docs.gitlab.com/api/epics/#create-a-to-do-item
49
+ class Epics < SupportOps::GitLab::Base
50
+ # @!parse
51
+ # # Creates/updates an epic
52
+ # #
53
+ # # @author Jason Colyer
54
+ # # @since 1.0.0
55
+ # # @return [Object] Instance of {SupportOps::GitLab::Epics}
56
+ # # @note This is inherited from {SupportOps::GitLab::Base#save!}
57
+ # # @see
58
+ # # https://docs.gitlab.com/api/epics/#new-epic
59
+ # # GitLab API > Epics > New epic
60
+ # # @see
61
+ # # https://docs.gitlab.com/api/epics/#update-epic
62
+ # # GitLab API > Epics > Update epic
63
+ # # @example
64
+ # # require 'support_ops_gitlab'
65
+ # #
66
+ # # SupportOps::GitLab::Configuration.configure do |config|
67
+ # # config.token = ENV.fetch('GL_TOKEN')
68
+ # # config.url = 'https://gitlab.com/api/v4'
69
+ # # end
70
+ # #
71
+ # # new_epic = SupportOps::GitLab::Epics.new
72
+ # # new_epic.title = 'Epic'
73
+ # # new_epic.description = 'Epic description'
74
+ # # new_epic.parent_id = 29
75
+ # # new_epic.group_id = 1
76
+ # #
77
+ # # new_epic.save!
78
+ # #
79
+ # # pp new_epic.id
80
+ # # # => 33
81
+ # # @example
82
+ # # require 'support_ops_gitlab'
83
+ # #
84
+ # # SupportOps::GitLab::Configuration.configure do |config|
85
+ # # config.token = ENV.fetch('GL_TOKEN')
86
+ # # config.url = 'https://gitlab.com/api/v4'
87
+ # # end
88
+ # #
89
+ # # epics = SupportOps::GitLab::Epics.list(group_id: 1)
90
+ # # existing_epic = epics.detect { |e| e.id == 33 }
91
+ # # existing_epic.title = 'Epic v2'
92
+ # #
93
+ # # existing_epic.save!
94
+ # #
95
+ # # pp existing_epic.title
96
+ # # # => "Epic v2"
97
+ # def save!; end
98
+ # @!parse
99
+ # # Deletes an epic
100
+ # #
101
+ # # @author Jason Colyer
102
+ # # @since 1.0.0
103
+ # # @return [Boolean]
104
+ # # @note This is inherited from {SupportOps::GitLab::Base#delete!}
105
+ # # @see
106
+ # # https://docs.gitlab.com/api/epics/#delete-epic
107
+ # # GitLab API > Epics > Delete epic
108
+ # # @example
109
+ # # require 'support_ops_gitlab'
110
+ # #
111
+ # # SupportOps::GitLab::Configuration.configure do |config|
112
+ # # config.token = ENV.fetch('GL_TOKEN')
113
+ # # config.url = 'https://gitlab.com/api/v4'
114
+ # # end
115
+ # #
116
+ # # epics = SupportOps::GitLab::Epics.list(group_id: 1)
117
+ # # existing_epic = epics.detect { |e| e.id == 33 }
118
+ # # existing_epic.delete!
119
+ # def delete!; end
120
+ # @!parse
121
+ # # List issues on an epic
122
+ # #
123
+ # # @author Jason Colyer
124
+ # # @since 1.0.0
125
+ # # @return [Boolean]
126
+ # # @note This is inherited from {SupportOps::GitLab::Base#issues}
127
+ # # @see
128
+ # # https://docs.gitlab.com/api/epic_issues/#list-issues-for-an-epic
129
+ # # GitLab API > Epics > List issues for an epic
130
+ # # @example
131
+ # # require 'support_ops_gitlab'
132
+ # #
133
+ # # SupportOps::GitLab::Configuration.configure do |config|
134
+ # # config.token = ENV.fetch('GL_TOKEN')
135
+ # # config.url = 'https://gitlab.com/api/v4'
136
+ # # end
137
+ # #
138
+ # # epics = SupportOps::GitLab::Epics.list(group_id: 1)
139
+ # # existing_epic = epics.detect { |e| e.id == 33 }
140
+ # # issues = existing_epic.issues
141
+ # # pp issues.count
142
+ # # # => 6
143
+ # def issues; end
144
+ # @!parse
145
+ # # List notes on an epic
146
+ # #
147
+ # # @author Jason Colyer
148
+ # # @since 1.0.0
149
+ # # @return [Boolean]
150
+ # # @note This is inherited from {SupportOps::GitLab::Base#notes}
151
+ # # @see
152
+ # # https://docs.gitlab.com/api/notes/#list-all-epic-notes
153
+ # # GitLab API > Notes (comments) > List all epic notes
154
+ # # @example
155
+ # # require 'support_ops_gitlab'
156
+ # #
157
+ # # SupportOps::GitLab::Configuration.configure do |config|
158
+ # # config.token = ENV.fetch('GL_TOKEN')
159
+ # # config.url = 'https://gitlab.com/api/v4'
160
+ # # end
161
+ # #
162
+ # # epics = SupportOps::GitLab::Epics.list(group_id: 1)
163
+ # # existing_epic = epics.detect { |e| e.id == 33 }
164
+ # # notes = existing_epic.notes
165
+ # # pp notes.count
166
+ # # # => 3
167
+ # def notes; end
168
+ define_attributes :add_labels, :author, :closed_at, :color, :confidential,
169
+ :created_at, :description, :downvotes, :due_date,
170
+ :due_date_fixed, :due_date_from_inherited_source,
171
+ :due_date_is_fixed,
172
+ :group_id, :id, :iid, :imported,
173
+ :imported_from, :labels, :_links, :parent_id,
174
+ :parent_iid, :reference, :references, :remove_labels,
175
+ :start_date, :start_date_fixed,
176
+ :start_date_from_inherited_source,
177
+ :start_date_is_fixed,
178
+ :state, :state_event, :subscribed, :title, :updated_at,
179
+ :upvotes, :web_url
180
+ readonly_attributes :author, :closed_at, :created_at, :downvotes,
181
+ :due_date, :due_date_from_inherited_source, :group_id,
182
+ :id, :iid, :imported, :imported_from, :_links,
183
+ :parent_iid, :reference, :references, :start_date,
184
+ :start_date_from_inherited_source, :state,
185
+ :subscribed, :updated_at, :upvotes, :web_url
186
+
187
+ ##
188
+ # Lists all epics keys for a group
189
+ #
190
+ # @author Jason Colyer
191
+ # @since 1.0.0
192
+ # @overload list(key: value)
193
+ # @param group_id [Integer required] The group ID to get the epics from
194
+ # @param author_id [Integer optional] Return epics created by the given user id
195
+ # @param author_username [String optional] Return epics created by the user with the given username
196
+ # @param labels [String optional] Return epics matching a comma-separated list of labels names
197
+ # @param order_by [String optional] Return epics ordered by created_at, updated_at, or title fields
198
+ # @param sort [String optional] Return epics sorted in asc or desc order
199
+ # @param search [String optional] Search epics against their title and description
200
+ # @param state [String optional] Search epics against their state, possible filters: opened, closed, and all
201
+ # @param created_after [String optional] Return epics created on or after the given time; expected in ISO 8601 format (2019-03-15T08:00:00Z)
202
+ # @param created_before [String optional] Return epics created on or before the given time; expected in ISO 8601 format (2019-03-15T08:00:00Z)
203
+ # @param updated_after [String optional] Return epics updated on or after the given time; expected in ISO 8601 format (2019-03-15T08:00:00Z)
204
+ # @param updated_before [String optional] Return epics updated on or before the given time; expected in ISO 8601 format (2019-03-15T08:00:00Z)
205
+ # @param include_ancestor_groups [xxx optional] Include epics from the requested group’s ancestors
206
+ # @param include_descendant_groups [xxx optional] Include epics from the requested group’s descendants
207
+ # @param my_reaction_emoji [String optional] Return epics reacted by the authenticated user by the given emoj
208
+ # @return [Array]
209
+ # @see
210
+ # https://docs.gitlab.com/api/epics/#list-epics-for-a-group
211
+ # GitLab API > Epics > List epics for a group
212
+ # @see SupportOps::GitLab::Configuration Setting up a client
213
+ # @example
214
+ # require 'support_ops_gitlab'
215
+ #
216
+ # SupportOps::GitLab::Configuration.configure do |config|
217
+ # config.url = 'https://gitlab.example.com/api/v4'
218
+ # config.token = 'abc123'
219
+ # end
220
+ #
221
+ # epics = SupportOps::GitLab::Epics.list(group_id: 123456)
222
+ # pp epics.count
223
+ # # => 30
224
+ # pp epics.last.due_date
225
+ # # => "2018-07-31"
226
+ def self.list(**args)
227
+ args[:group_id] = nil unless args[:group_id]
228
+ raise 'You have to provide a group_id' if args[:group_id].nil?
229
+ args[:author_id] = nil unless args[:author_id]
230
+ args[:author_username] = nil unless args[:author_username]
231
+ args[:labels] = nil unless args[:labels]
232
+ args[:order_by] = nil unless args[:order_by]
233
+ args[:sort] = nil unless args[:sort]
234
+ args[:search] = nil unless args[:search]
235
+ args[:state] = nil unless args[:state]
236
+ args[:created_after] = nil unless args[:created_after]
237
+ args[:created_before] = nil unless args[:created_before]
238
+ args[:updated_after] = nil unless args[:updated_after]
239
+ args[:updated_before] = nil unless args[:updated_before]
240
+ args[:include_ancestor_groups] = nil unless args[:include_ancestor_groups]
241
+ args[:include_descendant_groups] = nil unless args[:include_descendant_groups]
242
+ args[:my_reaction_emoji] = nil unless args[:my_reaction_emoji]
243
+ params = ''
244
+ params += "active=#{args[:active]}&" unless args[:active].nil?
245
+ params += "author_id=#{args[:author_id]}&" unless args[:author_id].nil?
246
+ params += "author_username=#{args[:author_username]}&" unless args[:author_username].nil?
247
+ params += "labels=#{args[:labels]}&" unless args[:labels].nil?
248
+ params += "order_by=#{args[:order_by]}&" unless args[:order_by].nil?
249
+ params += "sort=#{args[:sort]}&" unless args[:sort].nil?
250
+ params += "search=#{args[:search]}&" unless args[:search].nil?
251
+ params += "state=#{args[:state]}&" unless args[:state].nil?
252
+ params += "created_after=#{args[:created_after]}&" unless args[:created_after].nil?
253
+ params += "created_before=#{args[:created_before]}&" unless args[:created_before].nil?
254
+ params += "updated_after=#{args[:updated_after]}&" unless args[:updated_after].nil?
255
+ params += "updated_before=#{args[:updated_before]}&" unless args[:updated_before].nil?
256
+ params += "include_ancestor_groups=#{args[:include_ancestor_groups]}&" unless args[:include_ancestor_groups].nil?
257
+ params += "include_descendant_groups=#{args[:include_descendant_groups]}&" unless args[:include_descendant_groups].nil?
258
+ params += "my_reaction_emoji=#{args[:my_reaction_emoji]}&" unless args[:my_reaction_emoji].nil?
259
+ array = []
260
+ page = 1
261
+ loop do
262
+ response = client.connection.get("groups/#{args[:group_id]}/epics?#{params}&page=#{page}&per_page=100")
263
+ body = Oj.load(response.body)
264
+ array += body.map { |e| Epics.new(e) }
265
+ break if body.count < 100
266
+
267
+ page += 1
268
+ end
269
+ array
270
+ end
271
+
272
+ private
273
+
274
+ ##
275
+ # @private
276
+ def create_record
277
+ response = self.client.connection.post("groups/#{self.group_id}/epics", attributes_for_save.to_json)
278
+ body = Oj.load(response.body)
279
+ raise "Failed to create epic => #{body}" if response.status != 201
280
+ body
281
+ end
282
+
283
+ ##
284
+ # @private
285
+ def update_record
286
+ raise "Failed to update epic => You didn't change anything in the object" if attributes_for_save.keys == [:id]
287
+ response = self.client.connection.put("groups/#{self.group_id}/epics/#{self.iid}", attributes_for_save.to_json)
288
+ body = Oj.load(response.body)
289
+ raise "Failed to update epic #{self.id} => #{body}" if response.status != 200
290
+ body
291
+ end
292
+
293
+ ##
294
+ # @private
295
+ def delete_record
296
+ response = self.client.connection.delete("groups/#{self.group_id}/epics/#{self.iid}")
297
+ body = Oj.load(response.body)
298
+ raise "Failed to delete epic #{self.id} => #{body}" unless response.status == 204
299
+ true
300
+ end
301
+
302
+ ##
303
+ # @private
304
+ def issues_record
305
+ array = []
306
+ page = 1
307
+ loop do
308
+ response = client.connection.get("groups/#{self.group_id}/epics/#{self.id}/issues?page=#{page}&per_page=100")
309
+ body = Oj.load(response.body)
310
+ array += body.map { |i| Issues.new(i) }
311
+ break if body.count < 100
312
+
313
+ page += 1
314
+ end
315
+ array
316
+ end
317
+
318
+ ##
319
+ # @private
320
+ def notes_record
321
+ Notes.list(type: 'Epic', type_id: self.id, group_id: self.group_id)
322
+ end
323
+ end
324
+ end
325
+ end