gitlab 4.8.0 → 4.13.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 (50) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +13 -7
  3. data/lib/gitlab/cli.rb +0 -3
  4. data/lib/gitlab/cli_helpers.rb +11 -10
  5. data/lib/gitlab/client.rb +15 -0
  6. data/lib/gitlab/client/application_settings.rb +172 -0
  7. data/lib/gitlab/client/avatar.rb +21 -0
  8. data/lib/gitlab/client/boards.rb +56 -0
  9. data/lib/gitlab/client/build_variables.rb +14 -10
  10. data/lib/gitlab/client/commits.rb +18 -2
  11. data/lib/gitlab/client/container_registry.rb +85 -0
  12. data/lib/gitlab/client/epics.rb +73 -0
  13. data/lib/gitlab/client/features.rb +48 -0
  14. data/lib/gitlab/client/group_boards.rb +141 -0
  15. data/lib/gitlab/client/group_labels.rb +88 -0
  16. data/lib/gitlab/client/groups.rb +66 -2
  17. data/lib/gitlab/client/issue_links.rb +48 -0
  18. data/lib/gitlab/client/labels.rb +1 -1
  19. data/lib/gitlab/client/lint.rb +19 -0
  20. data/lib/gitlab/client/markdown.rb +23 -0
  21. data/lib/gitlab/client/merge_request_approvals.rb +9 -8
  22. data/lib/gitlab/client/merge_requests.rb +12 -0
  23. data/lib/gitlab/client/notes.rb +1 -1
  24. data/lib/gitlab/client/pipelines.rb +12 -0
  25. data/lib/gitlab/client/project_clusters.rb +83 -0
  26. data/lib/gitlab/client/project_release_links.rb +76 -0
  27. data/lib/gitlab/client/project_releases.rb +79 -0
  28. data/lib/gitlab/client/projects.rb +27 -6
  29. data/lib/gitlab/client/repositories.rb +5 -3
  30. data/lib/gitlab/client/repository_files.rb +16 -0
  31. data/lib/gitlab/client/resource_label_events.rb +82 -0
  32. data/lib/gitlab/client/runners.rb +49 -2
  33. data/lib/gitlab/client/search.rb +66 -0
  34. data/lib/gitlab/client/users.rb +7 -9
  35. data/lib/gitlab/configuration.rb +1 -1
  36. data/lib/gitlab/error.rb +46 -1
  37. data/lib/gitlab/paginated_response.rb +19 -0
  38. data/lib/gitlab/request.rb +15 -25
  39. data/lib/gitlab/shell_history.rb +4 -8
  40. data/lib/gitlab/version.rb +1 -1
  41. metadata +33 -15
  42. data/.github/stale.yml +0 -18
  43. data/.gitignore +0 -22
  44. data/.rubocop_todo.yml +0 -46
  45. data/CONTRIBUTING.md +0 -195
  46. data/Gemfile +0 -6
  47. data/Rakefile +0 -15
  48. data/bin/console +0 -11
  49. data/bin/setup +0 -6
  50. data/gitlab.gemspec +0 -36
@@ -67,7 +67,7 @@ class Gitlab::Client
67
67
  # @option options [Boolean] :issues_enabled The issues integration for a project (0 = false, 1 = true).
68
68
  # @option options [Boolean] :snippets_enabled The snippets integration for a project (0 = false, 1 = true).
69
69
  # @option options [Boolean] :merge_requests_enabled The merge requests functionality for a project (0 = false, 1 = true).
70
- # @option options [Boolean] :public The setting for making a project public (0 = false, 1 = true).
70
+ # @option options [String] :visibility The setting for making a project public ('private', 'internal', 'public').
71
71
  # @option options [Integer] :user_id The user/owner id of a project.
72
72
  # @return [Gitlab::ObjectifiedHash] Information about created project.
73
73
  def create_project(name, options = {})
@@ -529,14 +529,13 @@ class Gitlab::Client
529
529
  # @see https://docs.gitlab.com/ee/api/projects.html#upload-a-file
530
530
  #
531
531
  # @example
532
- # Gitlab.upload_file(1, File.open(File::NULL, 'r'))
533
- # File.open('myfile') { |file| Gitlab.upload_file(1, file) }
532
+ # Gitlab.upload_file(1, '/full/path/to/avatar.jpg')
534
533
  #
535
534
  # @param [Integer, String] id The ID or path of a project.
536
- # @param [File] The file you are interested to upload.
535
+ # @param [String] file_fullpath The fullpath of the file you are interested to upload.
537
536
  # @return [Gitlab::ObjectifiedHash]
538
- def upload_file(id, file)
539
- post("/projects/#{url_encode id}/uploads", body: { file: file })
537
+ def upload_file(id, file_fullpath)
538
+ post("/projects/#{url_encode id}/uploads", body: { file: File.open(file_fullpath, 'r') })
540
539
  end
541
540
 
542
541
  # Get all project templates of a particular type
@@ -570,5 +569,27 @@ class Gitlab::Client
570
569
  def project_template(project, type, key, options = {})
571
570
  get("/projects/#{url_encode project}/templates/#{type}/#{key}", query: options)
572
571
  end
572
+
573
+ # Archives a project.
574
+ #
575
+ # @example
576
+ # Gitlab.archive_project(4)
577
+ #
578
+ # @param [Integer, String] id The ID or path of a project.
579
+ # @return [Gitlab::ObjectifiedHash] Information about archived project.
580
+ def archive_project(id)
581
+ post("/projects/#{url_encode id}/archive")
582
+ end
583
+
584
+ # Unarchives a project.
585
+ #
586
+ # @example
587
+ # Gitlab.unarchive_project(4)
588
+ #
589
+ # @param [Integer, String] id The ID or path of a project.
590
+ # @return [Gitlab::ObjectifiedHash] Information about unarchived project.
591
+ def unarchive_project(id)
592
+ post("/projects/#{url_encode id}/unarchive")
593
+ end
573
594
  end
574
595
  end
@@ -13,7 +13,8 @@ class Gitlab::Client
13
13
  # @param [Integer, String] project The ID or name of a project.
14
14
  # @param [Hash] options A customizable set of options.
15
15
  # @option options [String] :path The path inside repository.
16
- # @option options [String] :ref_name The name of a repository branch or tag.
16
+ # @option options [String] :ref The name of a repository branch or tag.
17
+ # @option options [Integer] :per_page Number of results to show per page (default = 20)
17
18
  # @return [Gitlab::ObjectifiedHash]
18
19
  def tree(project, options = {})
19
20
  get("/projects/#{url_encode project}/repository/tree", query: options)
@@ -28,9 +29,10 @@ class Gitlab::Client
28
29
  #
29
30
  # @param [Integer, String] project The ID or name of a project.
30
31
  # @param [String] ref The commit sha, branch, or tag to download.
32
+ # @param [String] format The archive format. Options are: tar.gz (default), tar.bz2, tbz, tbz2, tb2, bz2, tar, and zip
31
33
  # @return [Gitlab::FileResponse]
32
- def repo_archive(project, ref = 'master')
33
- get("/projects/#{url_encode project}/repository/archive",
34
+ def repo_archive(project, ref = 'master', format = 'tar.gz')
35
+ get("/projects/#{url_encode project}/repository/archive.#{format}",
34
36
  format: nil,
35
37
  headers: { Accept: 'application/octet-stream' },
36
38
  query: { sha: ref },
@@ -25,6 +25,22 @@ class Gitlab::Client
25
25
  end
26
26
  alias repo_file_contents file_contents
27
27
 
28
+ # Get file blame from repository
29
+ #
30
+ # @example
31
+ # Gitlab.get_file_blame(42, "README.md", "master")
32
+ #
33
+ # @param [Integer, String] project The ID or name of a project.
34
+ # @param [String] file_path The full path of the file.
35
+ # @param [String] ref The name of branch, tag or commit.
36
+ # @return [Gitlab::ObjectifiedHash]
37
+ #
38
+ def get_file_blame(project, file_path, ref)
39
+ get("/projects/#{url_encode project}/repository/files/#{url_encode file_path}/blame", query: {
40
+ ref: ref
41
+ })
42
+ end
43
+
28
44
  # Gets a repository file.
29
45
  #
30
46
  # @example
@@ -0,0 +1,82 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Gitlab::Client
4
+ # Defines methods related to resource label events.
5
+ # @see https://docs.gitlab.com/ee/api/resource_label_events.html
6
+ module ResourceLabelEvents
7
+ # Gets a list of all label events for a single issue.
8
+ #
9
+ # @example
10
+ # Gitlab.issue_label_events(5, 42)
11
+ #
12
+ # @param [Integer, String] project The ID or name of a project.
13
+ # @param [Integer] issue_iid The IID of an issue.
14
+ # @return [Array<Gitlab::ObjectifiedHash>]
15
+ def issue_label_events(project, issue_iid)
16
+ get("/projects/#{url_encode project}/issues/#{issue_iid}/resource_label_events")
17
+ end
18
+
19
+ # Returns a single label event for a specific project issue
20
+ #
21
+ # @example
22
+ # Gitlab.issue_label_event(5, 42, 1)
23
+ #
24
+ # @param [Integer, String] project The ID or name of a project.
25
+ # @param [Integer] issue_iid The IID of an issue.
26
+ # @param [Integer] id The ID of a label event.
27
+ # @return Gitlab::ObjectifiedHash
28
+ def issue_label_event(project, issue_iid, id)
29
+ get("/projects/#{url_encode project}/issues/#{issue_iid}/resource_label_events/#{id}")
30
+ end
31
+
32
+ # Gets a list of all label events for a single epic.
33
+ #
34
+ # @example
35
+ # Gitlab.epic_label_events(5, 42)
36
+ #
37
+ # @param [Integer, String] group The ID or name of a group.
38
+ # @param [Integer] epic_id The ID of an epic.
39
+ # @return [Array<Gitlab::ObjectifiedHash>]
40
+ def epic_label_events(group, epic_id)
41
+ get("/groups/#{url_encode group}/epics/#{epic_id}/resource_label_events")
42
+ end
43
+
44
+ # Returns a single label event for a specific group epic
45
+ #
46
+ # @example
47
+ # Gitlab.epic_label_event(5, 42, 1)
48
+ #
49
+ # @param [Integer, String] group The ID or name of a group.
50
+ # @param [Integer] epic_id The ID of an epic.
51
+ # @param [Integer] id The ID of a label event.
52
+ # @return Gitlab::ObjectifiedHash
53
+ def epic_label_event(group, epic_id, id)
54
+ get("/groups/#{url_encode group}/epics/#{epic_id}/resource_label_events/#{id}")
55
+ end
56
+
57
+ # Gets a list of all label events for a single merge request.
58
+ #
59
+ # @example
60
+ # Gitlab.merge_request_label_events(5, 42)
61
+ #
62
+ # @param [Integer, String] project The ID or name of a project.
63
+ # @param [Integer] merge_request_iid The IID of a merge request.
64
+ # @return [Array<Gitlab::ObjectifiedHash>]
65
+ def merge_request_label_events(project, merge_request_iid)
66
+ get("/projects/#{url_encode project}/merge_requests/#{merge_request_iid}/resource_label_events")
67
+ end
68
+
69
+ # Returns a single label event for a specific project merge request
70
+ #
71
+ # @example
72
+ # Gitlab.merge_request_label_event(5, 42, 1)
73
+ #
74
+ # @param [Integer, String] project The ID or name of a project.
75
+ # @param [Integer] merge_request_iid The IID of an merge request.
76
+ # @param [Integer] id The ID of a label event.
77
+ # @return Gitlab::ObjectifiedHash
78
+ def merge_request_label_event(project, merge_request_iid, id)
79
+ get("/projects/#{url_encode project}/merge_requests/#{merge_request_iid}/resource_label_events/#{id}")
80
+ end
81
+ end
82
+ end
@@ -79,9 +79,11 @@ class Gitlab::Client
79
79
  # Gitlab.runner_jobs(1)
80
80
  #
81
81
  # @param [Integer] id The ID of a runner.
82
+ # @param [Hash] options A customizable set of options.
83
+ # @option options [String] :status Status of the job; one of: running, success, failed, canceled
82
84
  # @return [Array<Gitlab::ObjectifiedHash>]
83
- def runner_jobs(runner_id)
84
- get("/runners/#{url_encode runner_id}/jobs")
85
+ def runner_jobs(runner_id, options = {})
86
+ get("/runners/#{url_encode runner_id}/jobs", query: options)
85
87
  end
86
88
 
87
89
  # List all runners (specific and shared) available in the project. Shared runners are listed if at least one shared runner is defined and shared runners usage is enabled in the project's settings.
@@ -122,5 +124,50 @@ class Gitlab::Client
122
124
  def project_disable_runner(id, runner_id)
123
125
  delete("/projects/#{url_encode id}/runners/#{runner_id}")
124
126
  end
127
+
128
+ # Register a new Runner for the instance.
129
+ #
130
+ # @example
131
+ # Gitlab.register_runner('9142c16ea169eaaea3d752313a434a6e')
132
+ # Gitlab.register_runner('9142c16ea169eaaea3d752313a434a6e', description: 'Some Description', active: true, locked: false)
133
+ #
134
+ # @param [String] token Registration token.
135
+ # @param [Hash] options A customizable set of options.
136
+ # @option options [String] :description Runner description.
137
+ # @option options [Hash] :info Runner metadata.
138
+ # @option options [Boolean] :active Whether the Runner is active.
139
+ # @option options [Boolean] :locked Whether the Runner should be locked for current project.
140
+ # @option options [Boolean] :run_untagged Whether the Runner should handle untagged jobs.
141
+ # @option options [Array<String>] :tag_list List of Runner tags.
142
+ # @option options [Integer] :maximum_timeout Maximum timeout set when this Runner will handle the job.
143
+ # @return <Gitlab::ObjectifiedHash> Response against runner registration
144
+ def register_runner(token, options = {})
145
+ body = { token: token }.merge(options)
146
+ post('/runners', body: body)
147
+ end
148
+
149
+ # Deletes a registed Runner.
150
+ #
151
+ # @example
152
+ # Gitlab.delete_registered_runner('9142c16ea169eaaea3d752313a434a6e')
153
+ #
154
+ # @param [String] token Runner authentication token.
155
+ # @return [nil] This API call returns an empty response body.
156
+ def delete_registered_runner(token)
157
+ body = { token: token }
158
+ delete('/runners', body: body)
159
+ end
160
+
161
+ # Validates authentication credentials for a registered Runner.
162
+ #
163
+ # @example
164
+ # Gitlab.verify_auth_registered_runner('9142c16ea169eaaea3d752313a434a6e')
165
+ #
166
+ # @param [String] token Runner authentication token.
167
+ # @return [nil] This API call returns an empty response body.
168
+ def verify_auth_registered_runner(token)
169
+ body = { token: token }
170
+ post('/runners/verify', body: body)
171
+ end
125
172
  end
126
173
  end
@@ -0,0 +1,66 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Gitlab::Client
4
+ # Defines methods related to global searches, searching in projects and searching in groups.
5
+ # @see https://docs.gitlab.com/ce/api/search.html
6
+ module Search
7
+ # Search globally across the GitLab instance.
8
+ #
9
+ # @example
10
+ # Gitlab.search_globally('projects', 'gitlab')
11
+ # Gitlab.search_globally('issues', 'gitlab')
12
+ # Gitlab.search_globally('merge_requests', 'gitlab')
13
+ # Gitlab.search_globally('milestones', 'gitlab')
14
+ # Gitlab.search_globally('snippet_titles', 'gitlab')
15
+ # Gitlab.search_globally('snippet_blobs', 'gitlab')
16
+ #
17
+ # @param [String] scope The scope to search in. Currently these scopes are supported: projects, issues, merge_requests, milestones, snippet_titles, snippet_blobs.
18
+ # @param [String] search The search query.
19
+ # @return [Array<Gitlab::ObjectifiedHash>] Returns a list of responses depending on the requested scope.
20
+ def search_globally(scope, search)
21
+ options = { scope: scope, search: search }
22
+ get('/search', query: options)
23
+ end
24
+
25
+ # Search within the specified group.
26
+ #
27
+ # @example
28
+ # Gitlab.search_in_group(1, 'projects', 'gitlab')
29
+ # Gitlab.search_in_group(1, 'issues', 'gitlab')
30
+ # Gitlab.search_in_group(1, 'merge_requests', 'gitlab')
31
+ # Gitlab.search_in_group(1, 'milestones', 'gitlab')
32
+ #
33
+ # @param [Integer, String] group The ID or name of a group.
34
+ # @param [String] scope The scope to search in. Currently these scopes are supported: projects, issues, merge_requests, milestones.
35
+ # @param [String] search The search query.
36
+ # @return [Array<Gitlab::ObjectifiedHash>] Returns a list of responses depending on the requested scope.
37
+ def search_in_group(group, scope, search)
38
+ options = { scope: scope, search: search }
39
+ get("/groups/#{url_encode group}/search", query: options)
40
+ end
41
+
42
+ # Search within the specified project.
43
+ #
44
+ # @example
45
+ # Gitlab.search_in_project(1, 'issues', 'gitlab')
46
+ # Gitlab.search_in_project(1, 'merge_requests', 'gitlab')
47
+ # Gitlab.search_in_project(1, 'milestones', 'gitlab')
48
+ # Gitlab.search_in_project(1, 'notes', 'gitlab')
49
+ # Gitlab.search_in_project(1, 'wiki_blobs', 'gitlab')
50
+ # Gitlab.search_in_project(1, 'commits', 'gitlab')
51
+ # Gitlab.search_in_project(1, 'blobs', 'gitlab')
52
+ #
53
+ # @param [Integer, String] project The ID or name of a project.
54
+ # @param [String] scope The scope to search in. Currently these scopes are supported: issues, merge_requests, milestones, notes, wiki_blobs, commits, blobs.
55
+ # @param [String] search The search query.
56
+ # @return [Array<Gitlab::ObjectifiedHash>] Returns a list of responses depending on the requested scope.
57
+ def search_in_project(project, scope, search, ref = nil)
58
+ options = { scope: scope, search: search }
59
+
60
+ # Add ref filter if provided - backward compatible with main project
61
+ options[:ref] = ref unless ref.nil?
62
+
63
+ get("/projects/#{url_encode project}/search", query: options)
64
+ end
65
+ end
66
+ end
@@ -37,11 +37,11 @@ class Gitlab::Client
37
37
  # @example
38
38
  # Gitlab.create_user('joe@foo.org', 'secret', 'joe', { name: 'Joe Smith' })
39
39
  # or
40
- # Gitlab.create_user('joe@foo.org', 'secret')
40
+ # Gitlab.create_user('joe@foo.org', 'secret', 'joe')
41
41
  #
42
- # @param [String] email The email of a user.
43
- # @param [String] password The password of a user.
44
- # @param [String] username The username of a user.
42
+ # @param [String] email(required) The email of a user.
43
+ # @param [String] password(required) The password of a user.
44
+ # @param [String] username(required) The username of a user.
45
45
  # @param [Hash] options A customizable set of options.
46
46
  # @option options [String] :name The name of a user. Defaults to email.
47
47
  # @option options [String] :skype The skype of a user.
@@ -51,11 +51,9 @@ class Gitlab::Client
51
51
  # @return [Gitlab::ObjectifiedHash] Information about created user.
52
52
  def create_user(*args)
53
53
  options = args.last.is_a?(Hash) ? args.pop : {}
54
- body = if args[2]
55
- { email: args[0], password: args[1], username: args[2] }
56
- else
57
- { email: args[0], password: args[1], name: args[0] }
58
- end
54
+ raise ArgumentError, 'Missing required parameters' unless args[2]
55
+
56
+ body = { email: args[0], password: args[1], username: args[2], name: args[0] }
59
57
  body.merge!(options)
60
58
  post('/users', body: body)
61
59
  end
@@ -35,7 +35,7 @@ module Gitlab
35
35
 
36
36
  # Resets all configuration options to the defaults.
37
37
  def reset
38
- self.endpoint = ENV['GITLAB_API_ENDPOINT']
38
+ self.endpoint = ENV['GITLAB_API_ENDPOINT'] || ENV['CI_API_V4_URL']
39
39
  self.private_token = ENV['GITLAB_API_PRIVATE_TOKEN'] || ENV['GITLAB_API_AUTH_TOKEN']
40
40
  self.httparty = get_httparty_config(ENV['GITLAB_API_HTTPARTY_OPTIONS'])
41
41
  self.sudo = nil
@@ -40,7 +40,7 @@ module Gitlab
40
40
  #
41
41
  # @return [String]
42
42
  def build_error_message
43
- parsed_response = @response.parsed_response
43
+ parsed_response = classified_response
44
44
  message = check_error_keys(parsed_response)
45
45
  "Server responded with code #{@response.code}, message: " \
46
46
  "#{handle_message(message)}. " \
@@ -54,6 +54,17 @@ module Gitlab
54
54
  key ? resp.send(key) : resp
55
55
  end
56
56
 
57
+ # Parse the body based on the classification of the body content type
58
+ #
59
+ # @return parsed response
60
+ def classified_response
61
+ if @response.respond_to?('headers')
62
+ @response.headers['content-type'] == 'text/plain' ? { message: @response.to_s } : @response.parsed_response
63
+ else
64
+ @response.parsed_response
65
+ end
66
+ end
67
+
57
68
  # Handle error response message in case of nested hashes
58
69
  def handle_message(message)
59
70
  case message
@@ -67,6 +78,18 @@ module Gitlab
67
78
  message
68
79
  end
69
80
  end
81
+
82
+ def method_missing(method, *args, &block)
83
+ if @response.parsed_response.key?(method)
84
+ @response.parsed_response[method]
85
+ else
86
+ super
87
+ end
88
+ end
89
+
90
+ def respond_to_missing?(method, include_private = false)
91
+ super || @response.parsed_response.key?(method, include_private)
92
+ end
70
93
  end
71
94
 
72
95
  # Raised when API endpoint returns the HTTP status code 400.
@@ -84,12 +107,18 @@ module Gitlab
84
107
  # Raised when API endpoint returns the HTTP status code 405.
85
108
  class MethodNotAllowed < ResponseError; end
86
109
 
110
+ # Raised when API endpoint returns the HTTP status code 406.
111
+ class NotAcceptable < ResponseError; end
112
+
87
113
  # Raised when API endpoint returns the HTTP status code 409.
88
114
  class Conflict < ResponseError; end
89
115
 
90
116
  # Raised when API endpoint returns the HTTP status code 422.
91
117
  class Unprocessable < ResponseError; end
92
118
 
119
+ # Raised when API endpoint returns the HTTP status code 429.
120
+ class TooManyRequests < ResponseError; end
121
+
93
122
  # Raised when API endpoint returns the HTTP status code 500.
94
123
  class InternalServerError < ResponseError; end
95
124
 
@@ -98,5 +127,21 @@ module Gitlab
98
127
 
99
128
  # Raised when API endpoint returns the HTTP status code 503.
100
129
  class ServiceUnavailable < ResponseError; end
130
+
131
+ # HTTP status codes mapped to error classes.
132
+ STATUS_MAPPINGS = {
133
+ 400 => BadRequest,
134
+ 401 => Unauthorized,
135
+ 403 => Forbidden,
136
+ 404 => NotFound,
137
+ 405 => MethodNotAllowed,
138
+ 406 => NotAcceptable,
139
+ 409 => Conflict,
140
+ 422 => Unprocessable,
141
+ 429 => TooManyRequests,
142
+ 500 => InternalServerError,
143
+ 502 => BadGateway,
144
+ 503 => ServiceUnavailable
145
+ }.freeze
101
146
  end
102
147
  end
@@ -56,6 +56,25 @@ module Gitlab
56
56
  response
57
57
  end
58
58
 
59
+ def paginate_with_limit(limit)
60
+ response = block_given? ? nil : []
61
+ count = 0
62
+ each_page do |page|
63
+ if block_given?
64
+ page.each do |item|
65
+ yield item
66
+ count += 1
67
+ break if count >= limit
68
+ end
69
+ else
70
+ response += page[0, limit - count]
71
+ count = response.length
72
+ end
73
+ break if count >= limit
74
+ end
75
+ response
76
+ end
77
+
59
78
  def last_page?
60
79
  !(@links.nil? || @links.last.nil?)
61
80
  end