New upstream version 4.17.0
Sébastien Delafond
2 years ago
26 | 26 | |
27 | 27 | Lint/NonDeterministicRequireOrder: |
28 | 28 | Enabled: false |
29 | ||
30 | Style/HashEachMethods: | |
31 | Enabled: true | |
32 | ||
33 | Style/HashTransformKeys: | |
34 | Enabled: true | |
35 | ||
36 | Style/HashTransformValues: | |
37 | Enabled: true |
0 | 0 | # This configuration was generated by |
1 | 1 | # `rubocop --auto-gen-config` |
2 | # on 2020-06-28 04:00:53 UTC using RuboCop version 0.86.0. | |
2 | # on 2020-11-28 09:16:25 UTC using RuboCop version 1.4.2. | |
3 | 3 | # The point is for the user to remove these configuration records |
4 | 4 | # one by one as the offenses are removed from the code base. |
5 | 5 | # Note that changes in the inspected code, or installation of new |
8 | 8 | # Offense count: 4 |
9 | 9 | # Configuration parameters: IgnoredMethods. |
10 | 10 | Metrics/AbcSize: |
11 | Max: 34 | |
11 | Max: 35 | |
12 | 12 | |
13 | 13 | # Offense count: 3 |
14 | 14 | # Configuration parameters: IgnoredMethods. |
15 | 15 | Metrics/CyclomaticComplexity: |
16 | 16 | Max: 13 |
17 | 17 | |
18 | # Offense count: 8 | |
19 | # Configuration parameters: CountComments, ExcludedMethods. | |
18 | # Offense count: 10 | |
19 | # Configuration parameters: CountComments, CountAsOne, ExcludedMethods. | |
20 | 20 | Metrics/MethodLength: |
21 | 21 | Max: 34 |
22 | 22 | |
23 | 23 | # Offense count: 2 |
24 | # Configuration parameters: CountComments. | |
24 | # Configuration parameters: CountComments, CountAsOne. | |
25 | 25 | Metrics/ModuleLength: |
26 | 26 | Max: 156 |
27 | 27 | |
30 | 30 | Metrics/ParameterLists: |
31 | 31 | Max: 6 |
32 | 32 | |
33 | # Offense count: 1 | |
33 | # Offense count: 2 | |
34 | 34 | # Configuration parameters: IgnoredMethods. |
35 | 35 | Metrics/PerceivedComplexity: |
36 | Max: 10 | |
36 | Max: 11 | |
37 | 37 | |
38 | 38 | # Offense count: 1 |
39 | 39 | # Cop supports --auto-correct. |
168 | 168 | rake |
169 | 169 | ``` |
170 | 170 | |
171 | 6. Push your topic branch up to your fork: | |
171 | 6. Make sure you comply with rubocop style guide. You can run the linter using | |
172 | ||
173 | ```sh | |
174 | rake rubocop | |
175 | ``` | |
176 | ||
177 | 7. Push your topic branch up to your fork: | |
172 | 178 | |
173 | 179 | ```sh |
174 | 180 | git push origin <topic-branch-name> |
175 | 181 | ``` |
176 | 182 | |
177 | 7. [Open a Pull Request](https://help.github.com/articles/using-pull-requests/) | |
183 | 8. [Open a Pull Request](https://help.github.com/articles/using-pull-requests/) | |
178 | 184 | with a clear title and description. |
179 | 185 | |
180 | 8. If you haven't updated your pull request for a while, you should consider | |
186 | 9. If you haven't updated your pull request for a while, you should consider | |
181 | 187 | rebasing on master and resolving any conflicts. |
182 | 188 | |
183 | 189 | **IMPORTANT**: _Never ever_ merge upstream `master` into your branches. You |
26 | 26 | # gem 'gitlab', github: 'NARKOZ/gitlab' |
27 | 27 | ``` |
28 | 28 | |
29 | Mac OS users can install using Homebrew: | |
29 | Mac OS users can install using Homebrew (may not be the latest version): | |
30 | 30 | |
31 | 31 | ```sh |
32 | 32 | brew install gitlab-gem |
21 | 21 | |
22 | 22 | gem.required_ruby_version = '>= 2.5' |
23 | 23 | |
24 | gem.add_runtime_dependency 'httparty', '~> 0.14', '>= 0.14.0' | |
24 | gem.add_runtime_dependency 'httparty', '~> 0.18' | |
25 | 25 | gem.add_runtime_dependency 'terminal-table', '~> 1.5', '>= 1.5.1' |
26 | 26 | |
27 | 27 | gem.add_development_dependency 'rake' |
9 | 9 | |
10 | 10 | # Creates a new API. |
11 | 11 | # @raise [Error:MissingCredentials] |
12 | # rubocop:disable Lint/MissingSuper | |
12 | 13 | def initialize(options = {}) |
13 | 14 | options = Gitlab.options.merge(options) |
14 | 15 | (Configuration::VALID_OPTIONS_KEYS + [:auth_token]).each do |key| |
17 | 18 | request_defaults(sudo) |
18 | 19 | self.class.headers 'User-Agent' => user_agent |
19 | 20 | end |
21 | # rubocop:enable Lint/MissingSuper | |
20 | 22 | end |
21 | 23 | end |
16 | 16 | # @param [Array] args The command and it's optional arguments. |
17 | 17 | def self.start(args) |
18 | 18 | command = begin |
19 | args.shift.strip | |
20 | rescue StandardError | |
21 | 'help' | |
22 | end | |
19 | args.shift.strip | |
20 | rescue StandardError | |
21 | 'help' | |
22 | end | |
23 | 23 | run(command, args) |
24 | 24 | end |
25 | 25 |
110 | 110 | else |
111 | 111 | hash_result = case data |
112 | 112 | when Gitlab::ObjectifiedHash, Gitlab::FileResponse |
113 | record_hash([data], cmd, args, true) | |
113 | record_hash([data], cmd, args, single_value: true) | |
114 | 114 | when Gitlab::PaginatedResponse |
115 | 115 | record_hash(data, cmd, args) |
116 | 116 | else |
161 | 161 | # @param [Array] args Options passed to the API call |
162 | 162 | # @param [bool] single_value If set to true, a single result should be returned |
163 | 163 | # @return [Hash] Result hash |
164 | def record_hash(data, cmd, args, single_value = false) | |
164 | def record_hash(data, cmd, args, single_value: false) | |
165 | 165 | if data.empty? |
166 | 166 | result = nil |
167 | 167 | else |
58 | 58 | # @param [Integer, String] project The ID or name of a project. |
59 | 59 | # @param [String] sha The commit hash or name of a repository branch or tag |
60 | 60 | # @param [String] branch The name of the branch |
61 | # @return [Gitlab::ObjectifiedHash] | |
62 | def cherry_pick_commit(project, sha, branch) | |
63 | post("/projects/#{url_encode project}/repository/commits/#{sha}/cherry_pick", body: { branch: branch }) | |
61 | # @param [Hash] options A customizable set of options. | |
62 | # @option options [Boolean] :dry_run Don't commit any changes | |
63 | # @return [Gitlab::ObjectifiedHash] | |
64 | def cherry_pick_commit(project, sha, branch, options = {}) | |
65 | options[:branch] = branch | |
66 | ||
67 | post("/projects/#{url_encode project}/repository/commits/#{sha}/cherry_pick", body: options) | |
68 | end | |
69 | ||
70 | # Reverts a commit in a given branch. | |
71 | # | |
72 | # @example | |
73 | # Gitlab.revert_commit(42, '6104942438c14ec7bd21c6cd5bd995272b3faff6', 'master') | |
74 | # | |
75 | # @param [Integer, String] project The ID or name of a project. | |
76 | # @param [String] sha The commit hash or name of a repository branch or tag | |
77 | # @param [String] branch The name of the branch | |
78 | # @param [Hash] options A customizable set of options. | |
79 | # @option options [Boolean] :dry_run Don't commit any changes | |
80 | # @return [Gitlab::ObjectifiedHash] | |
81 | def revert_commit(project, sha, branch, options = {}) | |
82 | options[:branch] = branch | |
83 | ||
84 | post("/projects/#{url_encode project}/repository/commits/#{sha}/revert", body: options) | |
64 | 85 | end |
65 | 86 | |
66 | 87 | # Get the diff of a commit in a project. |
144 | 165 | # @option options [String] :name Filter by status name, eg. jenkins |
145 | 166 | # @option options [String] :target_url The target URL to associate with this status |
146 | 167 | def update_commit_status(project, sha, state, options = {}) |
147 | post("/projects/#{url_encode project}/statuses/#{sha}", query: options.merge(state: state)) | |
168 | post("/projects/#{url_encode project}/statuses/#{sha}", body: options.merge(state: state)) | |
148 | 169 | end |
149 | 170 | alias repo_update_commit_status update_commit_status |
150 | 171 |
78 | 78 | # @option options [String] :older_than(required) Tags to delete that are older than the given time, written in human readable form 1h, 1d, 1month. |
79 | 79 | # @return [void] This API call returns an empty response body. |
80 | 80 | def bulk_delete_registry_repository_tags(project, repository_id, options = {}) |
81 | delete("/projects/#{url_encode project}/registry/repositories/#{repository_id}/tags", query: options) | |
81 | delete("/projects/#{url_encode project}/registry/repositories/#{repository_id}/tags", body: options) | |
82 | 82 | end |
83 | 83 | end |
84 | 84 | end |
0 | # frozen_string_literal: true | |
1 | ||
2 | class Gitlab::Client | |
3 | # Defines methods related to group badges. | |
4 | # @see https://docs.gitlab.com/ee/api/group_badges.html | |
5 | module GroupBadges | |
6 | # Gets a list of a groups badges. | |
7 | # | |
8 | # @example | |
9 | # Gitlab.group_badges(5) | |
10 | # Gitlab.group_badges(5, 'Coverage') | |
11 | # | |
12 | # @param [Integer, String] group(required) The ID or URL-encoded path of the group owned by the authenticated user. | |
13 | # @param [String] name(optional) Name of the badges to return (case-sensitive). | |
14 | # @return [Array<Gitlab::ObjectifiedHash>] List of all badges of a group | |
15 | def group_badges(group, name = nil) | |
16 | query = { name: name } if name | |
17 | get("/groups/#{url_encode group}/badges", query: query) | |
18 | end | |
19 | ||
20 | # Gets a badge of a group. | |
21 | # | |
22 | # @example | |
23 | # Gitlab.group_badge(5, 42) | |
24 | # | |
25 | # @param [Integer, String] group(required) The ID or URL-encoded path of the group owned by the authenticated user. | |
26 | # @param [Integer] badge_id(required) The badge ID. | |
27 | # @return [Gitlab::ObjectifiedHash] Information about the requested badge | |
28 | def group_badge(group, badge_id) | |
29 | get("/groups/#{url_encode group}/badges/#{badge_id}") | |
30 | end | |
31 | ||
32 | # Adds a badge to a group. | |
33 | # | |
34 | # @example | |
35 | # Gitlab.add_group_badge(5, { link_url: 'https://abc.com/gitlab/gitlab-ce/commits/master', image_url: 'https://shields.io/my/badge1' }) | |
36 | # | |
37 | # @param [Integer, String] group(required) The ID or URL-encoded path of the group owned by the authenticated user. | |
38 | # @param [Hash] options A customizable set of options. | |
39 | # @option options [String] :link_url(required) URL of the badge link | |
40 | # @option options [String] :image_url(required) URL of the badge image | |
41 | # @return [Gitlab::ObjectifiedHash] Information about the added group badge. | |
42 | def add_group_badge(group, options = {}) | |
43 | post("/groups/#{url_encode group}/badges", body: options) | |
44 | end | |
45 | ||
46 | # Updates a badge of a group. | |
47 | # | |
48 | # @example | |
49 | # Gitlab.edit_group_badge(5, 1, { link_url: 'https://abc.com/gitlab/gitlab-ce/commits/master', image_url: 'https://shields.io/my/badge1' }) | |
50 | # | |
51 | # @param [Integer, String] group(required) The ID or URL-encoded path of the group owned by the authenticated user. | |
52 | # @param [Integer] badge_id(required) The badge ID. | |
53 | # @param [Hash] options A customizable set of options. | |
54 | # @option options [String] :link_url(optional) URL of the badge link | |
55 | # @option options [String] :image_url(optional) URL of the badge image | |
56 | # @return [Gitlab::ObjectifiedHash] Information about the updated group badge. | |
57 | def edit_group_badge(group, badge_id, options = {}) | |
58 | put("/groups/#{url_encode group}/badges/#{badge_id}", body: options) | |
59 | end | |
60 | ||
61 | # Removes a badge from a group. | |
62 | # | |
63 | # @example | |
64 | # Gitlab.remove_group_badge(5, 42) | |
65 | # | |
66 | # @param [Integer, String] group(required) The ID or URL-encoded path of the group owned by the authenticated user. | |
67 | # @param [Integer] badge_id(required) The badge ID. | |
68 | # @return [nil] This API call returns an empty response body. | |
69 | def remove_group_badge(group, badge_id) | |
70 | delete("/groups/#{url_encode group}/badges/#{badge_id}") | |
71 | end | |
72 | ||
73 | # Preview a badge from a group. | |
74 | # | |
75 | # @example | |
76 | # Gitlab.preview_group_badge(3, 'https://abc.com/gitlab/gitlab-ce/commits/master', 'https://shields.io/my/badge1') | |
77 | # | |
78 | # @param [Integer, String] group(required) The ID or URL-encoded path of the group owned by the authenticated user. | |
79 | # @param [String] :link_url(required) URL of the badge link | |
80 | # @param [String] :image_url(required) URL of the badge image | |
81 | # @return [Gitlab::ObjectifiedHash] Returns how the link_url and image_url final URLs would be after resolving the placeholder interpolation. | |
82 | def preview_group_badge(group, link_url, image_url) | |
83 | query = { link_url: link_url, image_url: image_url } | |
84 | get("/groups/#{url_encode group}/badges/render", query: query) | |
85 | end | |
86 | end | |
87 | end |
57 | 57 | # @param [String] name The name of a label. |
58 | 58 | # @return [Gitlab::ObjectifiedHash] Information about deleted label. |
59 | 59 | def delete_group_label(group, name) |
60 | delete("/groups/#{url_encode group}/labels", body: { name: name }) | |
60 | delete("/groups/#{url_encode group}/labels/#{name}") | |
61 | 61 | end |
62 | 62 | |
63 | 63 | # Subscribes the user to a group label to receive notifications |
68 | 68 | # @return [Array<Gitlab::ObjectifiedHash>] |
69 | 69 | def group_members(id, options = {}) |
70 | 70 | get("/groups/#{url_encode id}/members", query: options) |
71 | end | |
72 | ||
73 | # Get a list of group members that are billable. | |
74 | # | |
75 | # @example | |
76 | # Gitlab.group_billable_members(1) | |
77 | # Gitlab.group_billable_members(1, { per_page: 40 }) | |
78 | # | |
79 | # @param [Integer] id The ID of a group. | |
80 | # @param [Hash] options A customizable set of options. | |
81 | # @option options [Integer] :page The page number. | |
82 | # @option options [Integer] :per_page The number of results per page. | |
83 | # @return [Array<Gitlab::ObjectifiedHash>] | |
84 | def group_billable_members(id, options = {}) | |
85 | get("/groups/#{url_encode id}/billable_members", query: options) | |
71 | 86 | end |
72 | 87 | |
73 | 88 | # Get details of a single group member. |
35 | 35 | get("/projects/#{url_encode project_id}/pipelines/#{pipeline_id}/jobs", query: options) |
36 | 36 | end |
37 | 37 | |
38 | # Gets a list of Bridge Jobs from a pipeline | |
39 | # | |
40 | # @example | |
41 | # Gitlab.pipeline_bridges(1, 2) | |
42 | # Gitlab.pipeline_bridges("project", 2) | |
43 | # | |
44 | # @param [Integer, String] The ID or name of a project. | |
45 | # @param [Integer] the id of the pipeline | |
46 | # @param [Hash] options A customizable set of options. | |
47 | # @option options [Array] :scope The scope of bridge jobs to show, one or array of: created, pending, running, failed, success, canceled, skipped, manual; showing all bridge jobs if none provided. | |
48 | # @return [Array<Gitlab::ObjectifiedHash>] | |
49 | def pipeline_bridges(project_id, pipeline_id, options = {}) | |
50 | get("/projects/#{url_encode project_id}/pipelines/#{pipeline_id}/bridges", query: options) | |
51 | end | |
52 | ||
38 | 53 | # Gets a single job |
39 | 54 | # |
40 | 55 | # @example |
69 | 84 | # Gitlab.job_artifacts_download(1, "master", "release") |
70 | 85 | # Gitlab.job_artifacts_download("project", "master", "release") |
71 | 86 | # |
72 | # @param [Integer, String] id, The ID or name of a project. | |
73 | # @param [String] ref, Ref Name | |
74 | # @param [String] job, jobname | |
75 | # @return [Array<Gitlab::ObjectifiedHash>] | |
87 | # @param [Integer, String] project_id The ID or name of a project. | |
88 | # @param [String] ref Ref Name | |
89 | # @param [String] job jobname | |
90 | # @return [Gitlab::FileResponse] | |
76 | 91 | def job_artifacts_download(project_id, ref_name, job_name) |
77 | get("/projects/#{url_encode project_id}/jobs/artifacts/#{ref_name}/download", query: { job: job_name }, | |
78 | format: nil, | |
79 | headers: { Accept: 'text/plain' }, | |
80 | parser: ::Gitlab::Request::Parser) | |
81 | end | |
92 | get("/projects/#{url_encode project_id}/jobs/artifacts/#{ref_name}/download", | |
93 | query: { job: job_name }, | |
94 | format: nil, | |
95 | headers: { Accept: 'application/octet-stream' }, | |
96 | parser: proc { |body, _| | |
97 | if body.encoding == Encoding::ASCII_8BIT # binary response | |
98 | ::Gitlab::FileResponse.new StringIO.new(body, 'rb+') | |
99 | else # error with json response | |
100 | ::Gitlab::Request.parse(body) | |
101 | end | |
102 | }) | |
103 | end | |
104 | ||
105 | # Download a single artifact file by job ID | |
106 | # | |
107 | # @example | |
108 | # Gitlab.download_job_artifact_file(1, 5, "some/release/file.pdf") | |
109 | # | |
110 | # @param [Integer, String] project_id(required) The ID or name of a project. | |
111 | # @param [String] job_id(required) The unique job identifier. | |
112 | # @param [String] artifact_path(required) Path to a file inside the artifacts archive. | |
113 | # @return [Gitlab::FileResponse] | |
114 | def download_job_artifact_file(project_id, job_id, artifact_path) | |
115 | get("/projects/#{url_encode project_id}/jobs/#{job_id}/artifacts/#{artifact_path}", | |
116 | format: nil, | |
117 | headers: { Accept: 'application/octet-stream' }, | |
118 | parser: proc { |body, _| | |
119 | if body.encoding == Encoding::ASCII_8BIT # binary response | |
120 | ::Gitlab::FileResponse.new StringIO.new(body, 'rb+') | |
121 | else # error with json response | |
122 | ::Gitlab::Request.parse(body) | |
123 | end | |
124 | }) | |
125 | end | |
126 | ||
127 | # Download a single artifact file from specific tag or branch | |
128 | # | |
129 | # @example | |
130 | # Gitlab.download_branch_artifact_file(1, "master", "some/release/file.pdf", 'pdf') | |
131 | # | |
132 | # @param [Integer, String] project_id(required) The ID or name of a project. | |
133 | # @param [String] ref_name(required) Branch or tag name in repository. HEAD or SHA references are not supported. | |
134 | # @param [String] artifact_path(required) Path to a file inside the artifacts archive. | |
135 | # @param [String] job(required) The name of the job. | |
136 | # @return [Gitlab::FileResponse] | |
137 | def download_branch_artifact_file(project_id, ref_name, artifact_path, job) | |
138 | get("/projects/#{url_encode project_id}/jobs/artifacts/#{ref_name}/raw/#{artifact_path}", | |
139 | query: { job: job }, | |
140 | format: nil, | |
141 | headers: { Accept: 'application/octet-stream' }, | |
142 | parser: proc { |body, _| | |
143 | if body.encoding == Encoding::ASCII_8BIT # binary response | |
144 | ::Gitlab::FileResponse.new StringIO.new(body, 'rb+') | |
145 | else # error with json response | |
146 | ::Gitlab::Request.parse(body) | |
147 | end | |
148 | }) | |
149 | end | |
150 | alias download_tag_artifact_file download_branch_artifact_file | |
82 | 151 | |
83 | 152 | # Get Job Trace |
84 | 153 | # |
57 | 57 | # @param [String] name The name of a label. |
58 | 58 | # @return [Gitlab::ObjectifiedHash] Information about deleted label. |
59 | 59 | def delete_label(project, name) |
60 | delete("/projects/#{url_encode project}/labels", body: { name: name }) | |
60 | delete("/projects/#{url_encode project}/labels/#{name}") | |
61 | 61 | end |
62 | 62 | |
63 | 63 | # Subscribes the user to a label to receive notifications |
43 | 43 | # @option options [Boolean] :active The activation of pipeline schedule. If false is set, the pipeline schedule will deactivated initially (default: true). |
44 | 44 | # @return [Array<Gitlab::ObjectifiedHash>] |
45 | 45 | def create_pipeline_schedule(project, options = {}) |
46 | post("/projects/#{url_encode project}/pipeline_schedules", query: options) | |
46 | post("/projects/#{url_encode project}/pipeline_schedules", body: options) | |
47 | 47 | end |
48 | 48 | |
49 | 49 | # Updates the pipeline schedule of a project. |
61 | 61 | # @option options [Boolean] :active The activation of pipeline schedule. If false is set, the pipeline schedule will deactivated initially (default: true). |
62 | 62 | # @return [Array<Gitlab::ObjectifiedHash>] The updated pipeline schedule. |
63 | 63 | def edit_pipeline_schedule(project, pipeline_schedule_id, options = {}) |
64 | put("/projects/#{url_encode project}/pipeline_schedules/#{pipeline_schedule_id}", query: options) | |
64 | put("/projects/#{url_encode project}/pipeline_schedules/#{pipeline_schedule_id}", body: options) | |
65 | 65 | end |
66 | 66 | |
67 | 67 | # Take ownership of a pipeline schedule. |
100 | 100 | # @option options [String] :value The value of a variable |
101 | 101 | # @return [Array<Gitlab::ObjectifiedHash>] The created pipeline schedule variable. |
102 | 102 | def create_pipeline_schedule_variable(project, pipeline_schedule_id, options = {}) |
103 | post("/projects/#{url_encode project}/pipeline_schedules/#{pipeline_schedule_id}/variables", query: options) | |
103 | post("/projects/#{url_encode project}/pipeline_schedules/#{pipeline_schedule_id}/variables", body: options) | |
104 | 104 | end |
105 | 105 | |
106 | 106 | # Updates the variable of a pipeline schedule. |
115 | 115 | # @option options [String] :value The value of a variable. |
116 | 116 | # @return [Array<Gitlab::ObjectifiedHash>] The updated pipeline schedule variable. |
117 | 117 | def edit_pipeline_schedule_variable(project, pipeline_schedule_id, key, options = {}) |
118 | put("/projects/#{url_encode project}/pipeline_schedules/#{pipeline_schedule_id}/variables/#{url_encode key}", query: options) | |
118 | put("/projects/#{url_encode project}/pipeline_schedules/#{pipeline_schedule_id}/variables/#{url_encode key}", body: options) | |
119 | 119 | end |
120 | 120 | |
121 | 121 | # Delete the variable of a pipeline schedule |
28 | 28 | # @return [Gitlab::ObjectifiedHash] |
29 | 29 | def pipeline(project, id) |
30 | 30 | get("/projects/#{url_encode project}/pipelines/#{id}") |
31 | end | |
32 | ||
33 | # Gets a single pipeline's test report. | |
34 | # | |
35 | # @example | |
36 | # Gitlab.pipeline_test_report(5, 36) | |
37 | # | |
38 | # @param [Integer, String] project The ID or name of a project. | |
39 | # @param [Integer] id The ID of a pipeline. | |
40 | # @return [Gitlab::ObjectifiedHash] | |
41 | def pipeline_test_report(project, id) | |
42 | get("/projects/#{url_encode project}/pipelines/#{id}/test_report") | |
31 | 43 | end |
32 | 44 | |
33 | 45 | # Create a pipeline. |
101 | 101 | get("/projects/#{url_encode project}/members", query: options) |
102 | 102 | end |
103 | 103 | |
104 | # Gets a list of all project team members including inherited members. | |
105 | # | |
106 | # @example | |
107 | # Gitlab.all_members(42) | |
108 | # Gitlab.all_members('gitlab') | |
109 | # | |
110 | # @param [Integer, String] project The ID or path of a project. | |
111 | # @param [Hash] options A customizable set of options. | |
112 | # @option options [String] :query The search query. | |
113 | # @option options [Integer] :page The page number. | |
114 | # @option options [Integer] :per_page The number of results per page. | |
115 | # @return [Array<Gitlab::ObjectifiedHash>] | |
116 | def all_members(project, options = {}) | |
117 | get("/projects/#{url_encode project}/members/all", query: options) | |
118 | end | |
119 | ||
104 | 120 | # Gets a project team member. |
105 | 121 | # |
106 | 122 | # @example |
518 | 534 | delete("/projects/#{url_encode id}/star") |
519 | 535 | end |
520 | 536 | |
537 | # Get a list of visible projects that the given user has starred. | |
538 | # @see https://docs.gitlab.com/ee/api/projects.html#list-projects-starred-by-a-user | |
539 | # | |
540 | # @example | |
541 | # Gitlab.user_starred_projects(1) | |
542 | # Gitlab.user_starred_projects(1, { order_by: 'last_activity_at' }) | |
543 | # Gitlab.user_starred_projects('username', { order_by: 'name', sort: 'asc' }) | |
544 | # | |
545 | # @param [Integer, String] user_id The ID or username of the user. | |
546 | # @param [Hash] options A customizable set of options. | |
547 | # @option options [String] :per_page Number of projects to return per page | |
548 | # @option options [String] :page The page to retrieve | |
549 | # @option options [String] :order_by Return projects ordered by id, name, path, created_at, updated_at, or last_activity_at fields. | |
550 | # @option options [String] :sort Return projects sorted in asc or desc order. | |
551 | # @return [Array<Gitlab::ObjectifiedHash>] | |
552 | def user_starred_projects(user_id, options = {}) | |
553 | get("/users/#{url_encode user_id}/starred_projects", query: options) | |
554 | end | |
555 | ||
521 | 556 | # Get a list of visible projects for the given user. |
522 | 557 | # @see https://docs.gitlab.com/ee/api/projects.html#list-user-projects |
523 | 558 | # |
0 | # frozen_string_literal: true | |
1 | ||
2 | class Gitlab::Client | |
3 | # Defines methods related to resource state events. | |
4 | # @see https://docs.gitlab.com/ee/api/resource_state_events.html | |
5 | module ResourceStateEvents | |
6 | # Gets a list of all state events for a single issue. | |
7 | # | |
8 | # @example | |
9 | # Gitlab.issue_state_events(5, 42) | |
10 | # | |
11 | # @param [Integer, String] project The ID or name of a project. | |
12 | # @param [Integer] issue_iid The IID of an issue. | |
13 | # @return [Array<Gitlab::ObjectifiedHash>] | |
14 | def issue_state_events(project, issue_iid) | |
15 | get("/projects/#{url_encode project}/issues/#{issue_iid}/resource_state_events") | |
16 | end | |
17 | ||
18 | # Returns a single state event for a specific project issue | |
19 | # | |
20 | # @example | |
21 | # Gitlab.issue_state_event(5, 42, 1) | |
22 | # | |
23 | # @param [Integer, String] project The ID or name of a project. | |
24 | # @param [Integer] issue_iid The IID of an issue. | |
25 | # @param [Integer] id The ID of a resource event. | |
26 | # @return Gitlab::ObjectifiedHash | |
27 | def issue_state_event(project, issue_iid, id) | |
28 | get("/projects/#{url_encode project}/issues/#{issue_iid}/resource_state_events/#{id}") | |
29 | end | |
30 | ||
31 | # Gets a list of all state events for a single merge request. | |
32 | # | |
33 | # @example | |
34 | # Gitlab.merge_request_state_events(5, 42) | |
35 | # | |
36 | # @param [Integer, String] project The ID or name of a project. | |
37 | # @param [Integer] merge_request_iid The IID of a merge request. | |
38 | # @return [Array<Gitlab::ObjectifiedHash>] | |
39 | def merge_request_state_events(project, merge_request_iid) | |
40 | get("/projects/#{url_encode project}/merge_requests/#{merge_request_iid}/resource_state_events") | |
41 | end | |
42 | ||
43 | # Returns a single state event for a specific project merge request | |
44 | # | |
45 | # @example | |
46 | # Gitlab.merge_request_state_event(5, 42, 1) | |
47 | # | |
48 | # @param [Integer, String] project The ID or name of a project. | |
49 | # @param [Integer] merge_request_iid The IID of an merge request. | |
50 | # @param [Integer] id The ID of a state event. | |
51 | # @return Gitlab::ObjectifiedHash | |
52 | def merge_request_state_event(project, merge_request_iid, id) | |
53 | get("/projects/#{url_encode project}/merge_requests/#{merge_request_iid}/resource_state_events/#{id}") | |
54 | end | |
55 | end | |
56 | end |
8 | 8 | # |
9 | 9 | # @example |
10 | 10 | # Gitlab.runners |
11 | # Gitlab.runners(:active) | |
12 | # Gitlab.runners(:paused) | |
13 | # | |
14 | # @param [Hash] options A customizable set of options. | |
15 | # @option options [String] :scope The scope of specific runners to show, one of: active, paused, online; showing all runners if none provided | |
11 | # Gitlab.runners(type: 'instance_type', status: 'active') | |
12 | # Gitlab.runners(tag_list: 'tag1,tag2') | |
13 | # | |
14 | # @param [Hash] options A customizable set of options. | |
15 | # @option options [String] :type(optional) The type of runners to show, one of: instance_type, group_type, project_type | |
16 | # @option options [String] :status(optional) The status of runners to show, one of: active, paused, online, offline | |
17 | # @option options [String] :tag_list(optional) List of the runners tags (separated by comma) | |
16 | 18 | # @return [Array<Gitlab::ObjectifiedHash>] |
17 | 19 | def runners(options = {}) |
18 | 20 | get('/runners', query: options) |
23 | 25 | # |
24 | 26 | # @example |
25 | 27 | # Gitlab.all_runners |
26 | # | |
27 | # @param [Hash] options A customizable set of options. | |
28 | # @option options [String] :scope The scope of runners to show, one of: specific, shared, active, paused, online; showing all runners if none provided | |
28 | # Gitlab.all_runners(type: 'instance_type', status: 'active') | |
29 | # Gitlab.all_runners(tag_list: 'tag1,tag2') | |
30 | # | |
31 | # @param [Hash] options A customizable set of options. | |
32 | # @option options [String] :type(optional) The type of runners to show, one of: instance_type, group_type, project_type | |
33 | # @option options [String] :status(optional) The status of runners to show, one of: active, paused, online, offline | |
34 | # @option options [String] :tag_list(optional) List of the runners tags (separated by comma) | |
29 | 35 | # @return [Array<Gitlab::ObjectifiedHash>] |
30 | 36 | def all_runners(options = {}) |
31 | 37 | get('/runners/all', query: options) |
49 | 55 | # @example |
50 | 56 | # Gitlab.update_runner(42, { description: 'Awesome runner' }) |
51 | 57 | # Gitlab.update_runner(42, { active: false }) |
52 | # Gitlab.update_runner(42, { tag_list: [ 'awesome', 'runner' ] }) | |
53 | 58 | # |
54 | 59 | # @param [Integer, String] id The ID of a runner |
55 | 60 | # @param [Hash] options A customizable set of options. |
56 | # @option options [String] :active The state of a runner; can be set to true or false. | |
57 | # @option options [String] :tag_list The list of tags for a runner; put array of tags, that should be finally assigned to a runner | |
61 | # @option options [String] :description(optional) The description of a runner | |
62 | # @option options [Boolean] :active(optional) The state of a runner; can be set to true or false | |
63 | # @option options [String] :tag_list(optional) The list of tags for a runner; put array of tags, that should be finally assigned to a runner(separated by comma) | |
64 | # @option options [Boolean] :run_untagged(optional) Flag indicating the runner can execute untagged jobs | |
65 | # @option options [Boolean] :locked(optional) Flag indicating the runner is locked | |
66 | # @option options [String] :access_level(optional) The access_level of the runner; not_protected or ref_protected | |
67 | # @option options [Integer] :maximum_timeout(optional) Maximum timeout set when this runner will handle the job | |
58 | 68 | # @return <Gitlab::ObjectifiedHash> |
59 | 69 | def update_runner(id, options = {}) |
60 | put("/runners/#{id}", query: options) | |
70 | put("/runners/#{id}", body: options) | |
61 | 71 | end |
62 | 72 | |
63 | 73 | # Remove a runner. |
67 | 77 | # Gitlab.delete_runner(42) |
68 | 78 | # |
69 | 79 | # @param [Integer, String] id The ID of a runner |
70 | # @return <Gitlab::ObjectifiedHash> | |
80 | # @return [nil] This API call returns an empty response body. | |
71 | 81 | def delete_runner(id) |
72 | 82 | delete("/runners/#{id}") |
73 | 83 | end |
74 | 84 | |
75 | # Gets a list of Jobs for a Runner | |
85 | # List jobs that are being processed or were processed by specified runner. | |
76 | 86 | # |
77 | 87 | # @example |
78 | 88 | # Gitlab.runner_jobs(1) |
89 | # Gitlab.runner_jobs(1, status: 'success') | |
90 | # Gitlab.runner_jobs(1, sort: 'desc') | |
79 | 91 | # |
80 | 92 | # @param [Integer] id The ID of a runner. |
81 | 93 | # @param [Hash] options A customizable set of options. |
82 | # @option options [String] :status Status of the job; one of: running, success, failed, canceled | |
94 | # @option options [String] :status(optional) Status of the job; one of: running, success, failed, canceled | |
95 | # @option options [String] :order_by(optional) Order jobs by id. | |
96 | # @option options [String] :sort(optional) Sort jobs in asc or desc order (default: desc) | |
83 | 97 | # @return [Array<Gitlab::ObjectifiedHash>] |
84 | 98 | def runner_jobs(runner_id, options = {}) |
85 | 99 | get("/runners/#{url_encode runner_id}/jobs", query: options) |
90 | 104 | # |
91 | 105 | # @example |
92 | 106 | # Gitlab.project_runners(42) |
93 | # | |
94 | # @param [Integer, String] id The ID or name of a project. | |
95 | # @return [Array<Gitlab::ObjectifiedHash>] | |
96 | def project_runners(project_id) | |
97 | get("/projects/#{url_encode project_id}/runners") | |
107 | # Gitlab.project_runners(42, type: 'instance_type', status: 'active') | |
108 | # Gitlab.project_runners(42, tag_list: 'tag1,tag2') | |
109 | # | |
110 | # @param [Integer, String] id The ID or name of a project. | |
111 | # @param [Hash] options A customizable set of options. | |
112 | # @option options [String] :type(optional) The type of runners to show, one of: instance_type, group_type, project_type | |
113 | # @option options [String] :status(optional) The status of runners to show, one of: active, paused, online, offline | |
114 | # @option options [String] :tag_list(optional) List of the runners tags (separated by comma) | |
115 | # @return [Array<Gitlab::ObjectifiedHash>] | |
116 | def project_runners(project_id, options = {}) | |
117 | get("/projects/#{url_encode project_id}/runners", query: options) | |
98 | 118 | end |
99 | 119 | |
100 | 120 | # Enable an available specific runner in the project. |
124 | 144 | delete("/projects/#{url_encode id}/runners/#{runner_id}") |
125 | 145 | end |
126 | 146 | |
147 | # List all runners (specific and shared) available in the group as well its ancestor groups. Shared runners are listed if at least one shared runner is defined. | |
148 | # @see https://docs.gitlab.com/ee/api/runners.html#list-groups-runners | |
149 | # | |
150 | # @example | |
151 | # Gitlab.group_runners(9) | |
152 | # Gitlab.group_runners(9, type: 'instance_type', status: 'active') | |
153 | # Gitlab.group_runners(9, tag_list: 'tag1,tag2') | |
154 | # | |
155 | # @param [Integer, String] id The ID or name of a project. | |
156 | # @param [Hash] options A customizable set of options. | |
157 | # @option options [String] :type(optional) The type of runners to show, one of: instance_type, group_type, project_type | |
158 | # @option options [String] :status(optional) The status of runners to show, one of: active, paused, online, offline | |
159 | # @option options [String] :tag_list(optional) List of the runners tags (separated by comma) | |
160 | # @return [Array<Gitlab::ObjectifiedHash>] | |
161 | def group_runners(group, options = {}) | |
162 | get("/groups/#{url_encode group}/runners", query: options) | |
163 | end | |
164 | ||
127 | 165 | # Register a new Runner for the instance. |
128 | 166 | # |
129 | 167 | # @example |
130 | 168 | # Gitlab.register_runner('9142c16ea169eaaea3d752313a434a6e') |
131 | 169 | # Gitlab.register_runner('9142c16ea169eaaea3d752313a434a6e', description: 'Some Description', active: true, locked: false) |
132 | 170 | # |
133 | # @param [String] token Registration token. | |
134 | # @param [Hash] options A customizable set of options. | |
135 | # @option options [String] :description Runner description. | |
136 | # @option options [Hash] :info Runner metadata. | |
137 | # @option options [Boolean] :active Whether the Runner is active. | |
138 | # @option options [Boolean] :locked Whether the Runner should be locked for current project. | |
139 | # @option options [Boolean] :run_untagged Whether the Runner should handle untagged jobs. | |
140 | # @option options [Array<String>] :tag_list List of Runner tags. | |
141 | # @option options [Integer] :maximum_timeout Maximum timeout set when this Runner will handle the job. | |
171 | # @param [String] token(required) Registration token. | |
172 | # @param [Hash] options A customizable set of options. | |
173 | # @option options [String] :description(optional) Runner description. | |
174 | # @option options [Hash] :info(optional) Runner metadata. | |
175 | # @option options [Boolean] :active(optional) Whether the Runner is active. | |
176 | # @option options [Boolean] :locked(optional) Whether the Runner should be locked for current project. | |
177 | # @option options [Boolean] :run_untagged(optional) Whether the Runner should handle untagged jobs. | |
178 | # @option options [Array<String>] :tag_list(optional) List of Runner tags. | |
179 | # @option options [Integer] :maximum_timeout(optional) Maximum timeout set when this Runner will handle the job. | |
142 | 180 | # @return <Gitlab::ObjectifiedHash> Response against runner registration |
143 | 181 | def register_runner(token, options = {}) |
144 | 182 | body = { token: token }.merge(options) |
22 | 22 | include Epics |
23 | 23 | include Events |
24 | 24 | include Features |
25 | include GroupBadges | |
25 | 26 | include GroupBoards |
26 | 27 | include GroupLabels |
27 | 28 | include GroupMilestones |
51 | 52 | include RepositoryFiles |
52 | 53 | include RepositorySubmodules |
53 | 54 | include ResourceLabelEvents |
55 | include ResourceStateEvents | |
54 | 56 | include Runners |
55 | 57 | include Search |
56 | 58 | include Services |
79 | 81 | # |
80 | 82 | # @return [String] |
81 | 83 | def url_encode(url) |
82 | url.to_s.b.gsub(/[^a-zA-Z0-9_\-.~]/n) { |m| sprintf('%%%02X', m.unpack1('C')) } # rubocop:disable Style/FormatString, Style/FormatStringToken | |
84 | url.to_s.b.gsub(/[^a-zA-Z0-9_\-.~]/n) { |m| sprintf('%%%02X', m.unpack1('C')) } # rubocop:disable Style/FormatString | |
83 | 85 | end |
84 | 86 | |
85 | 87 | private |
31 | 31 | # @return [String] |
32 | 32 | def response_message |
33 | 33 | @response.parsed_response.message |
34 | end | |
35 | ||
36 | # Additional error context returned by some API endpoints | |
37 | # | |
38 | # @return [String] | |
39 | def error_code | |
40 | if @response.respond_to?(:error_code) | |
41 | @response.error_code | |
42 | else | |
43 | '' | |
44 | end | |
34 | 45 | end |
35 | 46 | |
36 | 47 | private |
73 | 73 | # Returns full namespace of a command (e.g. Gitlab::Client::Branches.cmd) |
74 | 74 | def namespace(cmd) |
75 | 75 | method_owners.select { |method| method[:name] == cmd } |
76 | .map { |method| method[:owner] + '.' + method[:name] } | |
76 | .map { |method| "#{method[:owner]}.#{method[:name]}" } | |
77 | 77 | .shift |
78 | 78 | end |
79 | 79 | |
80 | 80 | # Massage output from 'ri'. |
81 | 81 | def change_help_output!(cmd, output_str) |
82 | 82 | output_str = +output_str |
83 | output_str.gsub!(/#{cmd}\((.*?)\)/m, cmd + ' \1') | |
83 | output_str.gsub!(/#{cmd}\((.*?)\)/m, "#{cmd} \1") | |
84 | 84 | output_str.gsub!(/,\s*/, ' ') |
85 | 85 | |
86 | 86 | # Ensure @option descriptions are on a single line |
42 | 42 | end |
43 | 43 | |
44 | 44 | def lazy_paginate |
45 | to_enum(:each_page).lazy.flat_map(&:to_ary) | |
45 | to_enum(:each_page).lazy.flat_map(&:to_ary) # rubocop:disable Lint/ToEnumArguments | |
46 | 46 | end |
47 | 47 | |
48 | 48 | def auto_paginate(&block) |
49 | return lazy_paginate.to_a unless block_given? | |
49 | return lazy_paginate.to_a unless block | |
50 | 50 | |
51 | 51 | lazy_paginate.each(&block) |
52 | 52 | end |
53 | 53 | |
54 | 54 | def paginate_with_limit(limit, &block) |
55 | return lazy_paginate.take(limit).to_a unless block_given? | |
55 | return lazy_paginate.take(limit).to_a unless block | |
56 | 56 | |
57 | 57 | lazy_paginate.take(limit).each(&block) |
58 | 58 | end |
23 | 23 | elsif body |
24 | 24 | true |
25 | 25 | elsif !body |
26 | false | |
27 | elsif body.nil? | |
28 | 26 | false |
29 | 27 | else |
30 | 28 | raise Error::Parsing, "Couldn't parse a response body" |
41 | 41 | File.expand_path(@file_path) |
42 | 42 | end |
43 | 43 | |
44 | def read_from_file | |
44 | def read_from_file(&block) | |
45 | 45 | path = history_file_path |
46 | 46 | |
47 | File.foreach(path) { |line| yield(line) } if File.exist?(path) | |
47 | File.foreach(path, &block) if File.exist?(path) | |
48 | 48 | rescue StandardError => e |
49 | 49 | warn "History file not loaded: #{e.message}" |
50 | 50 | end |
0 | 0 | # frozen_string_literal: true |
1 | 1 | |
2 | 2 | module Gitlab |
3 | VERSION = '4.16.1' | |
3 | VERSION = '4.17.0' | |
4 | 4 | end |
0 | {"message":"Sorry, we cannot cherry-pick this commit automatically. This commit may already have been cherry-picked, or a more recent commit may have updated some of its content.","error_code":"conflict"} |
0 | {"id":1,"link_url":"http://example.com/ci_status.svg?project=%{project_path}&ref=%{default_branch}","image_url":"https://shields.io/my/badge","rendered_link_url":"http://example.com/ci_status.svg?project=example-org/example-project&ref=master","rendered_image_url":"https://shields.io/my/badge","kind":"project"}⏎ |
0 | [{"id":1,"link_url":"http://example.com/ci_status.svg?project=%{project_path}&ref=%{default_branch}","image_url":"https://shields.io/my/badge","rendered_link_url":"http://example.com/ci_status.svg?project=example-org/example-project&ref=master","rendered_image_url":"https://shields.io/my/badge","kind":"project"},{"id":2,"link_url":"http://example.com/ci_status.svg?project=%{project_path}&ref=%{default_branch}","image_url":"https://shields.io/my/badge","rendered_link_url":"http://example.com/ci_status.svg?project=example-org/example-project&ref=master","rendered_image_url":"https://shields.io/my/badge","kind":"group"}]⏎ |
0 | [{"id":1,"username":"eraymond","email":"eraymond@local.host","name":"Edward Raymond","state":"active","created_at":"2013-08-30T16:16:22Z","access_level":50},{"id":1,"username":"jsmith","email":"jsmith@local.host","name":"John Smith","state":"active","created_at":"2013-08-30T16:16:22Z","access_level":50}] |
0 | [ | |
1 | { | |
2 | "id": 3, | |
3 | "description": "Shared", | |
4 | "ip_address": "127.0.0.1", | |
5 | "active": true, | |
6 | "is_shared": true, | |
7 | "name": "gitlab-runner", | |
8 | "online": null, | |
9 | "status": "not_connected" | |
10 | }, | |
11 | { | |
12 | "id": 6, | |
13 | "description": "Test", | |
14 | "ip_address": "127.0.0.1", | |
15 | "active": true, | |
16 | "is_shared": true, | |
17 | "name": "gitlab-runner", | |
18 | "online": false, | |
19 | "status": "offline" | |
20 | }, | |
21 | { | |
22 | "id": 8, | |
23 | "description": "Test 2", | |
24 | "ip_address": "127.0.0.1", | |
25 | "active": true, | |
26 | "is_shared": false, | |
27 | "name": "gitlab-runner", | |
28 | "online": null, | |
29 | "status": "not_connected" | |
30 | } | |
31 | ] |
0 | { | |
1 | "id": 143, | |
2 | "user": { | |
3 | "id": 1, | |
4 | "name": "Administrator", | |
5 | "username": "root", | |
6 | "state": "active", | |
7 | "avatar_url": "https://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon", | |
8 | "web_url": "http://gitlab.example.com/root" | |
9 | }, | |
10 | "created_at": "2018-08-21T14:38:20.077Z", | |
11 | "resource_type": "Issue", | |
12 | "resource_id": 11, | |
13 | "state": "closed" | |
14 | }⏎ |
0 | [ | |
1 | { | |
2 | "id": 142, | |
3 | "user": { | |
4 | "id": 1, | |
5 | "name": "Administrator", | |
6 | "username": "root", | |
7 | "state": "active", | |
8 | "avatar_url": "https://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon", | |
9 | "web_url": "http://gitlab.example.com/root" | |
10 | }, | |
11 | "created_at": "2018-08-20T13:38:20.077Z", | |
12 | "resource_type": "Issue", | |
13 | "resource_id": 11, | |
14 | "state": "opened" | |
15 | }, | |
16 | { | |
17 | "id": 143, | |
18 | "user": { | |
19 | "id": 1, | |
20 | "name": "Administrator", | |
21 | "username": "root", | |
22 | "state": "active", | |
23 | "avatar_url": "https://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon", | |
24 | "web_url": "http://gitlab.example.com/root" | |
25 | }, | |
26 | "created_at": "2018-08-21T14:38:20.077Z", | |
27 | "resource_type": "Issue", | |
28 | "resource_id": 11, | |
29 | "state": "closed" | |
30 | } | |
31 | ]⏎ |
Binary diff not shown
0 | { | |
1 | "id": 120, | |
2 | "user": { | |
3 | "id": 1, | |
4 | "name": "Administrator", | |
5 | "username": "root", | |
6 | "state": "active", | |
7 | "avatar_url": "https://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon", | |
8 | "web_url": "http://gitlab.example.com/root" | |
9 | }, | |
10 | "created_at": "2018-08-21T14:38:20.077Z", | |
11 | "resource_type": "MergeRequest", | |
12 | "resource_id": 11, | |
13 | "state": "closed" | |
14 | }⏎ |
0 | [ | |
1 | { | |
2 | "id": 142, | |
3 | "user": { | |
4 | "id": 1, | |
5 | "name": "Administrator", | |
6 | "username": "root", | |
7 | "state": "active", | |
8 | "avatar_url": "https://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon", | |
9 | "web_url": "http://gitlab.example.com/root" | |
10 | }, | |
11 | "created_at": "2018-08-20T13:38:20.077Z", | |
12 | "resource_type": "MergeRequest", | |
13 | "resource_id": 11, | |
14 | "state": "opened" | |
15 | }, | |
16 | { | |
17 | "id": 143, | |
18 | "user": { | |
19 | "id": 1, | |
20 | "name": "Administrator", | |
21 | "username": "root", | |
22 | "state": "active", | |
23 | "avatar_url": "https://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon", | |
24 | "web_url": "http://gitlab.example.com/root" | |
25 | }, | |
26 | "created_at": "2018-08-21T14:38:20.077Z", | |
27 | "resource_type": "MergeRequest", | |
28 | "resource_id": 11, | |
29 | "state": "closed" | |
30 | } | |
31 | ]⏎ |
0 | [{"commit":{"author_email":"admin@example.com","author_name":"Administrator","created_at":"2015-12-24T16:51:14.000+01:00","id":"0ff3ae198f8601a285adcf5c0fff204ee6fba5fd","message":"Test the CI integration.","short_id":"0ff3ae19","title":"Test the CI integration."},"coverage":null,"allow_failure":false,"created_at":"2015-12-24T15:51:21.802Z","started_at":"2015-12-24T17:54:27.722Z","finished_at":"2015-12-24T17:58:27.895Z","duration":240,"id":7,"name":"teaspoon","pipeline":{"id":6,"ref":"master","sha":"0ff3ae198f8601a285adcf5c0fff204ee6fba5fd","status":"pending","created_at":"2015-12-24T15:50:16.123Z","updated_at":"2015-12-24T18:00:44.432Z","web_url":"https://example.com/foo/bar/pipelines/6"},"ref":"master","stage":"test","status":"pending","tag":false,"web_url":"https://example.com/foo/bar/-/jobs/7","user":{"id":1,"name":"Administrator","username":"root","state":"active","avatar_url":"http://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon","web_url":"http://gitlab.dev/root","created_at":"2015-12-21T13:14:24.077Z","bio":null,"location":null,"public_email":"","skype":"","linkedin":"","twitter":"","website_url":"","organization":""},"downstream_pipeline":{"id":5,"sha":"f62a4b2fb89754372a346f24659212eb8da13601","ref":"master","status":"pending","created_at":"2015-12-24T17:54:27.722Z","updated_at":"2015-12-24T17:58:27.896Z","web_url":"https://example.com/diaspora/diaspora-client/pipelines/5"}}] |
0 | { | |
1 | "total_time": 5, | |
2 | "total_count": 1, | |
3 | "success_count": 1, | |
4 | "failed_count": 0, | |
5 | "skipped_count": 0, | |
6 | "error_count": 0, | |
7 | "test_suites": [ | |
8 | { | |
9 | "name": "Secure", | |
10 | "total_time": 5, | |
11 | "total_count": 1, | |
12 | "success_count": 1, | |
13 | "failed_count": 0, | |
14 | "skipped_count": 0, | |
15 | "error_count": 0, | |
16 | "test_cases": [ | |
17 | { | |
18 | "status": "success", | |
19 | "name": "Security Reports can create an auto-remediation MR", | |
20 | "classname": "vulnerability_management_spec", | |
21 | "execution_time": 5, | |
22 | "system_output": null, | |
23 | "stack_trace": null | |
24 | } | |
25 | ] | |
26 | } | |
27 | ] | |
28 | } |
0 | {"link_url":"http://example.com/ci_status.svg?project=%{project_path}&ref=%{default_branch}","image_url":"https://shields.io/my/badge","rendered_link_url":"http://example.com/ci_status.svg?project=example-org/example-project&ref=master","rendered_image_url":"https://shields.io/my/badge"}⏎ |
0 | {"message":"Sorry, we cannot revert this commit automatically. This commit may already have been reverted, or a more recent commit may have updated some of its content.","error_code":"empty"} |
98 | 98 | end |
99 | 99 | |
100 | 100 | it 'renders output as json' do |
101 | expect(JSON.parse(@output)['result']).to eq(JSON.parse(File.read(File.dirname(__FILE__) + '/../fixtures/user.json'))) | |
101 | expect(JSON.parse(@output)['result']).to eq(JSON.parse(File.read("#{File.dirname(__FILE__)}/../fixtures/user.json"))) | |
102 | 102 | expect(JSON.parse(@output)['cmd']).to eq('Gitlab.user') |
103 | 103 | end |
104 | 104 | end |
64 | 64 | end |
65 | 65 | |
66 | 66 | describe '.cherry_pick_commit' do |
67 | before do | |
68 | stub_post('/projects/3/repository/commits/6104942438c14ec7bd21c6cd5bd995272b3faff6/cherry_pick', 'project_commit').with(body: { branch: 'master' }) | |
69 | @cherry_pick_commit = Gitlab.cherry_pick_commit(3, '6104942438c14ec7bd21c6cd5bd995272b3faff6', 'master') | |
70 | end | |
71 | ||
72 | it 'gets the correct resource' do | |
73 | expect(a_post('/projects/3/repository/commits/6104942438c14ec7bd21c6cd5bd995272b3faff6/cherry_pick') | |
74 | .with(body: { branch: 'master' })) | |
75 | .to have_been_made | |
76 | end | |
77 | ||
78 | it 'returns the correct response' do | |
79 | expect(@cherry_pick_commit).to be_a Gitlab::ObjectifiedHash | |
80 | expect(@cherry_pick_commit.id).to eq('6104942438c14ec7bd21c6cd5bd995272b3faff6') | |
67 | context 'on success' do | |
68 | before do | |
69 | stub_post('/projects/3/repository/commits/6104942438c14ec7bd21c6cd5bd995272b3faff6/cherry_pick', 'project_commit').with(body: { branch: 'master' }) | |
70 | @cherry_pick_commit = Gitlab.cherry_pick_commit(3, '6104942438c14ec7bd21c6cd5bd995272b3faff6', 'master') | |
71 | end | |
72 | ||
73 | it 'gets the correct resource' do | |
74 | expect(a_post('/projects/3/repository/commits/6104942438c14ec7bd21c6cd5bd995272b3faff6/cherry_pick') | |
75 | .with(body: { branch: 'master' })) | |
76 | .to have_been_made | |
77 | end | |
78 | ||
79 | it 'returns the correct response' do | |
80 | expect(@cherry_pick_commit).to be_a Gitlab::ObjectifiedHash | |
81 | expect(@cherry_pick_commit.id).to eq('6104942438c14ec7bd21c6cd5bd995272b3faff6') | |
82 | end | |
83 | end | |
84 | ||
85 | context 'on failure' do | |
86 | it 'includes the error_code' do | |
87 | stub_post('/projects/3/repository/commits/6104942438c14ec7bd21c6cd5bd995272b3faff6/cherry_pick', 'cherry_pick_commit_failure', 400) | |
88 | ||
89 | expect { Gitlab.cherry_pick_commit(3, '6104942438c14ec7bd21c6cd5bd995272b3faff6', 'master') }.to raise_error(Gitlab::Error::BadRequest) do |ex| | |
90 | expect(ex.error_code).to eq('conflict') | |
91 | end | |
92 | end | |
93 | end | |
94 | ||
95 | context 'with additional options' do | |
96 | it 'passes additional options' do | |
97 | stub_post('/projects/3/repository/commits/6104942438c14ec7bd21c6cd5bd995272b3faff6/cherry_pick', 'project_commit') | |
98 | .with(body: { branch: 'master', dry_run: true }) | |
99 | ||
100 | Gitlab.cherry_pick_commit(3, '6104942438c14ec7bd21c6cd5bd995272b3faff6', 'master', dry_run: true) | |
101 | ||
102 | expect(a_post('/projects/3/repository/commits/6104942438c14ec7bd21c6cd5bd995272b3faff6/cherry_pick') | |
103 | .with(body: { branch: 'master', dry_run: true })) | |
104 | .to have_been_made | |
105 | end | |
106 | end | |
107 | end | |
108 | ||
109 | describe '.revert_commit' do | |
110 | context 'on success' do | |
111 | before do | |
112 | stub_post('/projects/3/repository/commits/6104942438c14ec7bd21c6cd5bd995272b3faff6/revert', 'project_commit').with(body: { branch: 'master' }) | |
113 | @revert_commit = Gitlab.revert_commit(3, '6104942438c14ec7bd21c6cd5bd995272b3faff6', 'master') | |
114 | end | |
115 | ||
116 | it 'gets the correct resource' do | |
117 | expect(a_post('/projects/3/repository/commits/6104942438c14ec7bd21c6cd5bd995272b3faff6/revert') | |
118 | .with(body: { branch: 'master' })) | |
119 | .to have_been_made | |
120 | end | |
121 | ||
122 | it 'returns the correct response' do | |
123 | expect(@revert_commit).to be_a Gitlab::ObjectifiedHash | |
124 | expect(@revert_commit.id).to eq('6104942438c14ec7bd21c6cd5bd995272b3faff6') | |
125 | end | |
126 | end | |
127 | ||
128 | context 'on failure' do | |
129 | it 'includes the error_code' do | |
130 | stub_post('/projects/3/repository/commits/6104942438c14ec7bd21c6cd5bd995272b3faff6/revert', 'revert_commit_failure', 400) | |
131 | ||
132 | expect { Gitlab.revert_commit(3, '6104942438c14ec7bd21c6cd5bd995272b3faff6', 'master') }.to raise_error(Gitlab::Error::BadRequest) do |ex| | |
133 | expect(ex.error_code).to eq('empty') | |
134 | end | |
135 | end | |
136 | end | |
137 | ||
138 | context 'with additional options' do | |
139 | it 'passes additional options' do | |
140 | stub_post('/projects/3/repository/commits/6104942438c14ec7bd21c6cd5bd995272b3faff6/revert', 'project_commit') | |
141 | .with(body: { branch: 'master', dry_run: true }) | |
142 | ||
143 | Gitlab.revert_commit(3, '6104942438c14ec7bd21c6cd5bd995272b3faff6', 'master', dry_run: true) | |
144 | ||
145 | expect(a_post('/projects/3/repository/commits/6104942438c14ec7bd21c6cd5bd995272b3faff6/revert') | |
146 | .with(body: { branch: 'master', dry_run: true })) | |
147 | .to have_been_made | |
148 | end | |
81 | 149 | end |
82 | 150 | end |
83 | 151 | |
155 | 223 | describe '.update_commit_status' do |
156 | 224 | before do |
157 | 225 | stub_post('/projects/6/statuses/7d938cb8ac15788d71f4b67c035515a160ea76d8', 'project_update_commit_status') |
158 | .with(query: { name: 'test', ref: 'decreased-spec', state: 'failed' }) | |
226 | .with(body: { name: 'test', ref: 'decreased-spec', state: 'failed' }) | |
159 | 227 | @status = Gitlab.update_commit_status(6, '7d938cb8ac15788d71f4b67c035515a160ea76d8', 'failed', name: 'test', ref: 'decreased-spec') |
160 | 228 | end |
161 | 229 | |
162 | 230 | it 'gets the correct resource' do |
163 | 231 | expect(a_post('/projects/6/statuses/7d938cb8ac15788d71f4b67c035515a160ea76d8') |
164 | .with(query: { name: 'test', ref: 'decreased-spec', state: 'failed' })) | |
232 | .with(body: { name: 'test', ref: 'decreased-spec', state: 'failed' })) | |
165 | 233 | end |
166 | 234 | |
167 | 235 | it 'returns information about the newly created status' do |
72 | 72 | describe '.bulk_delete_registry_repository_tags' do |
73 | 73 | context 'when just name_regex provided for deletion' do |
74 | 74 | before do |
75 | stub_delete('/projects/3/registry/repositories/1/tags', 'empty').with(query: { name_regex: '.*' }) | |
75 | stub_delete('/projects/3/registry/repositories/1/tags', 'empty').with(body: { name_regex: '.*' }) | |
76 | 76 | Gitlab.bulk_delete_registry_repository_tags(3, 1, name_regex: '.*') |
77 | 77 | end |
78 | 78 | |
79 | 79 | it 'gets the correct resource' do |
80 | 80 | expect(a_delete('/projects/3/registry/repositories/1/tags') |
81 | .with(query: { name_regex: '.*' })).to have_been_made | |
81 | .with(body: { name_regex: '.*' })).to have_been_made | |
82 | 82 | end |
83 | 83 | end |
84 | 84 | |
85 | 85 | context 'when all options provided for deletion' do |
86 | 86 | before do |
87 | stub_delete('/projects/3/registry/repositories/1/tags', 'empty').with(query: { name_regex: '[0-9a-z]{40}', keep_n: 5, older_than: '1d' }) | |
87 | stub_delete('/projects/3/registry/repositories/1/tags', 'empty').with(body: { name_regex: '[0-9a-z]{40}', keep_n: 5, older_than: '1d' }) | |
88 | 88 | Gitlab.bulk_delete_registry_repository_tags(3, 1, name_regex: '[0-9a-z]{40}', keep_n: 5, older_than: '1d') |
89 | 89 | end |
90 | 90 | |
91 | 91 | it 'gets the correct resource' do |
92 | 92 | expect(a_delete('/projects/3/registry/repositories/1/tags') |
93 | .with(query: { name_regex: '[0-9a-z]{40}', keep_n: 5, older_than: '1d' })).to have_been_made | |
93 | .with(body: { name_regex: '[0-9a-z]{40}', keep_n: 5, older_than: '1d' })).to have_been_made | |
94 | 94 | end |
95 | 95 | end |
96 | 96 | end |
0 | # frozen_string_literal: true | |
1 | ||
2 | # rubocop:disable Style/FormatStringToken | |
3 | ||
4 | require 'spec_helper' | |
5 | ||
6 | describe Gitlab::Client do | |
7 | describe '.group_badges' do | |
8 | before do | |
9 | stub_get('/groups/3/badges', 'group_badges') | |
10 | @group_badges = Gitlab.group_badges(3) | |
11 | end | |
12 | ||
13 | it 'gets the correct resource' do | |
14 | expect(a_get('/groups/3/badges')).to have_been_made | |
15 | end | |
16 | ||
17 | it "returns a paginated response of group's badges" do | |
18 | expect(@group_badges).to be_a Gitlab::PaginatedResponse | |
19 | end | |
20 | end | |
21 | ||
22 | describe '.group_badge' do | |
23 | before do | |
24 | stub_get('/groups/3/badges/1', 'group_badge') | |
25 | @group_badge = Gitlab.group_badge(3, 1) | |
26 | end | |
27 | ||
28 | it 'gets the correct resource' do | |
29 | expect(a_get('/groups/3/badges/1')).to have_been_made | |
30 | end | |
31 | ||
32 | it 'returns information about a badge' do | |
33 | expect(@group_badge.id).to eq(1) | |
34 | end | |
35 | end | |
36 | ||
37 | describe '.add_group_badge' do | |
38 | before do | |
39 | stub_post('/groups/3/badges', 'group_badge') | |
40 | @group_badge = Gitlab.add_group_badge(3, link_url: 'http://example.com/ci_status.svg?project=%{project_path}&ref=%{default_branch}', image_url: 'https://shields.io/my/badge') | |
41 | end | |
42 | ||
43 | it 'gets the correct resource' do | |
44 | expect(a_post('/groups/3/badges') | |
45 | .with(body: { link_url: 'http://example.com/ci_status.svg?project=%{project_path}&ref=%{default_branch}', image_url: 'https://shields.io/my/badge' })).to have_been_made | |
46 | end | |
47 | ||
48 | it 'returns information about an added group badge' do | |
49 | expect(@group_badge.link_url).to eq('http://example.com/ci_status.svg?project=%{project_path}&ref=%{default_branch}') | |
50 | expect(@group_badge.image_url).to eq('https://shields.io/my/badge') | |
51 | end | |
52 | end | |
53 | ||
54 | describe '.edit_group_badge' do | |
55 | before do | |
56 | stub_put('/groups/3/badges/1', 'group_badge') | |
57 | @group_badge = Gitlab.edit_group_badge(3, 1, link_url: 'http://example.com/ci_status.svg?project=%{project_path}&ref=%{default_branch}', image_url: 'https://shields.io/my/badge') | |
58 | end | |
59 | ||
60 | it 'gets the correct resource' do | |
61 | expect(a_put('/groups/3/badges/1') | |
62 | .with(body: { link_url: 'http://example.com/ci_status.svg?project=%{project_path}&ref=%{default_branch}', image_url: 'https://shields.io/my/badge' })).to have_been_made | |
63 | end | |
64 | ||
65 | it 'returns information about an edited group badge' do | |
66 | expect(@group_badge.link_url).to eq('http://example.com/ci_status.svg?project=%{project_path}&ref=%{default_branch}') | |
67 | expect(@group_badge.image_url).to eq('https://shields.io/my/badge') | |
68 | end | |
69 | end | |
70 | ||
71 | describe '.remove_group_badge' do | |
72 | before do | |
73 | stub_delete('/groups/3/badges/3', 'empty') | |
74 | @group_badge = Gitlab.remove_group_badge(3, 3) | |
75 | end | |
76 | ||
77 | it 'gets the correct resource' do | |
78 | expect(a_delete('/groups/3/badges/3')).to have_been_made | |
79 | end | |
80 | end | |
81 | ||
82 | describe '.preview_group_badge' do | |
83 | before do | |
84 | stub_get('/groups/3/badges/render?image_url=https://shields.io/my/badge&link_url=http://example.com/ci_status.svg?project=%25%7Bproject_path%7D%26ref=%25%7Bdefault_branch%7D', 'preview_group_badge') | |
85 | @preview_group_badge = Gitlab.preview_group_badge(3, 'http://example.com/ci_status.svg?project=%{project_path}&ref=%{default_branch}', 'https://shields.io/my/badge') | |
86 | end | |
87 | ||
88 | it 'gets the correct resource' do | |
89 | expect(a_get('/groups/3/badges/render?image_url=https://shields.io/my/badge&link_url=http://example.com/ci_status.svg?project=%25%7Bproject_path%7D%26ref=%25%7Bdefault_branch%7D')).to have_been_made | |
90 | end | |
91 | ||
92 | it 'returns information about the rendered values of a badge' do | |
93 | expect(@preview_group_badge.link_url).to eq('http://example.com/ci_status.svg?project=%{project_path}&ref=%{default_branch}') | |
94 | expect(@preview_group_badge.image_url).to eq('https://shields.io/my/badge') | |
95 | end | |
96 | end | |
97 | end | |
98 | # rubocop:enable Style/FormatStringToken |
53 | 53 | |
54 | 54 | describe '.delete_group_label' do |
55 | 55 | before do |
56 | stub_delete('/groups/3/labels', 'label') | |
56 | stub_delete('/groups/3/labels/Backlog', 'label') | |
57 | 57 | @label = Gitlab.delete_group_label(3, 'Backlog') |
58 | 58 | end |
59 | 59 | |
60 | 60 | it 'gets the correct resource' do |
61 | expect(a_delete('/groups/3/labels') | |
62 | .with(body: { name: 'Backlog' })).to have_been_made | |
61 | expect(a_delete('/groups/3/labels/Backlog')).to have_been_made | |
63 | 62 | end |
64 | 63 | |
65 | 64 | it 'returns information about a deleted snippet' do |
125 | 125 | end |
126 | 126 | end |
127 | 127 | |
128 | describe '.group_billable_members' do | |
129 | before do | |
130 | stub_get('/groups/3/billable_members', 'group_billable_members') | |
131 | @members = Gitlab.group_billable_members(3) | |
132 | end | |
133 | ||
134 | it 'gets the correct resource' do | |
135 | expect(a_get('/groups/3/billable_members')).to have_been_made | |
136 | end | |
137 | ||
138 | it "returns information about a group's billable members" do | |
139 | expect(@members).to be_a Gitlab::PaginatedResponse | |
140 | expect(@members.size).to eq(2) | |
141 | expect(@members[1].name).to eq('John Smith') | |
142 | end | |
143 | end | |
144 | ||
128 | 145 | describe '.group_member' do |
129 | 146 | before do |
130 | 147 | stub_get('/groups/3/members/2', 'group_member') |
46 | 46 | end |
47 | 47 | end |
48 | 48 | |
49 | describe '.pipeline_bridges' do | |
50 | before do | |
51 | stub_get('/projects/1/pipelines/1/bridges', 'pipeline_bridges') | |
52 | @jobs = Gitlab.pipeline_bridges(1, 1) | |
53 | end | |
54 | ||
55 | it 'gets the correct resource' do | |
56 | expect(a_get('/projects/1/pipelines/1/bridges')).to have_been_made | |
57 | end | |
58 | end | |
59 | ||
60 | describe '.pipeline_bridges - with scope' do | |
61 | before do | |
62 | stub_get('/projects/1/pipelines/1/bridges?scope[]=running&scope[]=created', 'pipeline_bridges') | |
63 | @jobs = Gitlab.pipeline_bridges(1, 1, scope: %w[running created]) | |
64 | end | |
65 | ||
66 | it 'gets the correct resource' do | |
67 | expect(a_get('/projects/1/pipelines/1/bridges?scope[]=running&scope[]=created')).to have_been_made | |
68 | end | |
69 | end | |
70 | ||
49 | 71 | describe '.job' do |
50 | 72 | before do |
51 | 73 | stub_get('/projects/1/jobs/1', 'job') |
69 | 91 | end |
70 | 92 | |
71 | 93 | describe '.job_artifacts_download' do |
72 | before do | |
73 | stub_get('/projects/1/jobs/artifacts/master/download?job=Release%20Build', 'job') | |
74 | @projects = Gitlab.job_artifacts_download(1, 'master', 'Release Build') | |
75 | end | |
76 | ||
77 | it 'gets the correct resource' do | |
78 | expect(a_get('/projects/1/jobs/artifacts/master/download?job=Release%20Build')).to have_been_made | |
94 | context 'when successful request' do | |
95 | before do | |
96 | fixture = load_fixture('job_artifacts.zip') | |
97 | fixture.set_encoding(Encoding::ASCII_8BIT) | |
98 | stub_request(:get, "#{Gitlab.endpoint}/projects/3/jobs/artifacts/master/download") | |
99 | .with(query: { job: 'test' }, headers: { 'PRIVATE-TOKEN' => Gitlab.private_token }) | |
100 | .to_return(body: fixture.read, headers: { 'Content-Disposition' => 'attachment; filename=job_artifacts.zip' }) | |
101 | @job_artifacts = Gitlab.job_artifacts_download(3, 'master', 'test') | |
102 | end | |
103 | ||
104 | it 'gets the correct resource' do | |
105 | expect(a_get('/projects/3/jobs/artifacts/master/download') | |
106 | .with(query: { job: 'test' })).to have_been_made | |
107 | end | |
108 | ||
109 | it 'returns a FileResponse' do | |
110 | expect(@job_artifacts).to be_a Gitlab::FileResponse | |
111 | end | |
112 | ||
113 | it 'returns a file with filename' do | |
114 | expect(@job_artifacts.filename).to eq 'job_artifacts.zip' | |
115 | end | |
116 | end | |
117 | ||
118 | context 'when bad request' do | |
119 | it 'throws an exception' do | |
120 | stub_get('/projects/3/jobs/artifacts/master/download', 'error_project_not_found', 404) | |
121 | .with(query: { job: 'test' }) | |
122 | expect { Gitlab.job_artifacts_download(3, 'master', 'test') }.to raise_error(Gitlab::Error::NotFound, "Server responded with code 404, message: 404 Project Not Found. Request URI: #{Gitlab.endpoint}/projects/3/jobs/artifacts/master/download") | |
123 | end | |
124 | end | |
125 | end | |
126 | ||
127 | describe '.download_job_artifact_file' do | |
128 | context 'when successful request' do | |
129 | before do | |
130 | fixture = load_fixture('raw_file.txt') | |
131 | fixture.set_encoding(Encoding::ASCII_8BIT) | |
132 | stub_request(:get, "#{Gitlab.endpoint}/projects/3/jobs/5/artifacts/raw_file.txt") | |
133 | .with(headers: { 'PRIVATE-TOKEN' => Gitlab.private_token }) | |
134 | .to_return(body: fixture.read, headers: { 'Content-Disposition' => 'attachment; filename=raw_file.txt' }) | |
135 | @job_artifact_file = Gitlab.download_job_artifact_file(3, 5, 'raw_file.txt') | |
136 | end | |
137 | ||
138 | it 'gets the correct resource' do | |
139 | expect(a_get('/projects/3/jobs/5/artifacts/raw_file.txt')).to have_been_made | |
140 | end | |
141 | ||
142 | it 'returns a FileResponse' do | |
143 | expect(@job_artifact_file).to be_a Gitlab::FileResponse | |
144 | end | |
145 | ||
146 | it 'returns a file with filename' do | |
147 | expect(@job_artifact_file.filename).to eq 'raw_file.txt' | |
148 | end | |
149 | end | |
150 | ||
151 | context 'when bad request' do | |
152 | it 'throws an exception' do | |
153 | stub_get('/projects/3/jobs/5/artifacts/raw_file.txt', 'error_project_not_found', 404) | |
154 | expect { Gitlab.download_job_artifact_file(3, 5, 'raw_file.txt') }.to raise_error(Gitlab::Error::NotFound, "Server responded with code 404, message: 404 Project Not Found. Request URI: #{Gitlab.endpoint}/projects/3/jobs/5/artifacts/raw_file.txt") | |
155 | end | |
156 | end | |
157 | end | |
158 | ||
159 | describe '.download_branch_artifact_file' do | |
160 | context 'when successful request' do | |
161 | before do | |
162 | fixture = load_fixture('raw_file.txt') | |
163 | fixture.set_encoding(Encoding::ASCII_8BIT) | |
164 | stub_request(:get, "#{Gitlab.endpoint}/projects/1/jobs/artifacts/master/raw/raw_file.txt") | |
165 | .with(query: { job: 'txt' }, headers: { 'PRIVATE-TOKEN' => Gitlab.private_token }) | |
166 | .to_return(body: fixture.read, headers: { 'Content-Disposition' => 'attachment; filename=raw_file.txt' }) | |
167 | @branch_artifact_file = Gitlab.download_branch_artifact_file(1, 'master', 'raw_file.txt', 'txt') | |
168 | end | |
169 | ||
170 | it 'gets the correct resource' do | |
171 | expect(a_get('/projects/1/jobs/artifacts/master/raw/raw_file.txt') | |
172 | .with(query: { job: 'txt' })).to have_been_made | |
173 | end | |
174 | ||
175 | it 'returns a FileResponse' do | |
176 | expect(@branch_artifact_file).to be_a Gitlab::FileResponse | |
177 | end | |
178 | ||
179 | it 'returns a file with filename' do | |
180 | expect(@branch_artifact_file.filename).to eq 'raw_file.txt' | |
181 | end | |
182 | end | |
183 | ||
184 | context 'when bad request' do | |
185 | it 'throws an exception' do | |
186 | stub_get('/projects/1/jobs/artifacts/master/raw/raw_file.txt', 'error_project_not_found', 404) | |
187 | .with(query: { job: 'txt' }) | |
188 | expect { Gitlab.download_branch_artifact_file(1, 'master', 'raw_file.txt', 'txt') }.to raise_error(Gitlab::Error::NotFound, "Server responded with code 404, message: 404 Project Not Found. Request URI: #{Gitlab.endpoint}/projects/1/jobs/artifacts/master/raw/raw_file.txt") | |
189 | end | |
190 | end | |
191 | end | |
192 | ||
193 | describe '.download_tag_artifact_file' do | |
194 | context 'when successful request' do | |
195 | before do | |
196 | fixture = load_fixture('raw_file.txt') | |
197 | fixture.set_encoding(Encoding::ASCII_8BIT) | |
198 | stub_request(:get, "#{Gitlab.endpoint}/projects/1/jobs/artifacts/release/raw/raw_file.txt") | |
199 | .with(query: { job: 'txt' }, headers: { 'PRIVATE-TOKEN' => Gitlab.private_token }) | |
200 | .to_return(body: fixture.read, headers: { 'Content-Disposition' => 'attachment; filename=raw_file.txt' }) | |
201 | @branch_artifact_file = Gitlab.download_tag_artifact_file(1, 'release', 'raw_file.txt', 'txt') | |
202 | end | |
203 | ||
204 | it 'gets the correct resource' do | |
205 | expect(a_get('/projects/1/jobs/artifacts/release/raw/raw_file.txt') | |
206 | .with(query: { job: 'txt' })).to have_been_made | |
207 | end | |
208 | ||
209 | it 'returns a FileResponse' do | |
210 | expect(@branch_artifact_file).to be_a Gitlab::FileResponse | |
211 | end | |
212 | ||
213 | it 'returns a file with filename' do | |
214 | expect(@branch_artifact_file.filename).to eq 'raw_file.txt' | |
215 | end | |
216 | end | |
217 | ||
218 | context 'when bad request' do | |
219 | it 'throws an exception' do | |
220 | stub_get('/projects/1/jobs/artifacts/release/raw/raw_file.txt', 'error_project_not_found', 404) | |
221 | .with(query: { job: 'txt' }) | |
222 | expect { Gitlab.download_tag_artifact_file(1, 'release', 'raw_file.txt', 'txt') }.to raise_error(Gitlab::Error::NotFound, "Server responded with code 404, message: 404 Project Not Found. Request URI: #{Gitlab.endpoint}/projects/1/jobs/artifacts/release/raw/raw_file.txt") | |
223 | end | |
79 | 224 | end |
80 | 225 | end |
81 | 226 |
20 | 20 | |
21 | 21 | describe '.delete' do |
22 | 22 | before do |
23 | stub_delete('/projects/3/labels', 'label') | |
23 | stub_delete('/projects/3/labels/Backlog', 'label') | |
24 | 24 | @label = Gitlab.delete_label(3, 'Backlog') |
25 | 25 | end |
26 | 26 | |
27 | 27 | it 'gets the correct resource' do |
28 | expect(a_delete('/projects/3/labels') | |
29 | .with(body: { name: 'Backlog' })).to have_been_made | |
28 | expect(a_delete('/projects/3/labels/Backlog')).to have_been_made | |
30 | 29 | end |
31 | 30 | |
32 | 31 | it 'returns information about a deleted snippet' do |
107 | 107 | |
108 | 108 | describe '.create_pipeline_schedule_variable' do |
109 | 109 | before do |
110 | stub_post('/projects/3/pipeline_schedules/13/variables?key=NEW%20VARIABLE&value=new%20value', 'pipeline_schedule_variable') | |
110 | stub_post('/projects/3/pipeline_schedules/13/variables', 'pipeline_schedule_variable') | |
111 | .with(body: { key: 'NEW VARIABLE', value: 'new value' }) | |
111 | 112 | @pipeline_schedule_variable = Gitlab.create_pipeline_schedule_variable(3, 13, |
112 | 113 | key: 'NEW VARIABLE', |
113 | 114 | value: 'new value') |
114 | 115 | end |
115 | 116 | |
116 | 117 | it 'gets the correct resource' do |
117 | expect(a_post('/projects/3/pipeline_schedules/13/variables?key=NEW%20VARIABLE&value=new%20value')).to have_been_made | |
118 | expect(a_post('/projects/3/pipeline_schedules/13/variables') | |
119 | .with(body: { key: 'NEW VARIABLE', value: 'new value' })).to have_been_made | |
118 | 120 | end |
119 | 121 | |
120 | 122 | it 'returns a single variable' do |
128 | 130 | |
129 | 131 | describe '.edit_pipeline_schedule_variable' do |
130 | 132 | before do |
131 | stub_put('/projects/3/pipeline_schedules/13/variables/NEW%20VARIABLE?value=update%20value', 'pipeline_schedule_variable_update') | |
133 | stub_put('/projects/3/pipeline_schedules/13/variables/NEW%20VARIABLE', 'pipeline_schedule_variable_update') | |
134 | .with(body: { value: 'update value' }) | |
132 | 135 | @pipeline_schedule_variable = Gitlab.edit_pipeline_schedule_variable(3, 13, 'NEW VARIABLE', value: 'update value') |
133 | 136 | end |
134 | 137 |
34 | 34 | it 'returns information about a pipeline' do |
35 | 35 | expect(@pipeline.id).to eq(46) |
36 | 36 | expect(@pipeline.user.name).to eq('Administrator') |
37 | end | |
38 | end | |
39 | ||
40 | describe '.pipeline_test_report' do | |
41 | before do | |
42 | stub_get('/projects/3/pipelines/46/test_report', 'pipeline_test_report') | |
43 | @report = Gitlab.pipeline_test_report(3, 46) | |
44 | end | |
45 | ||
46 | it 'gets the correct resource' do | |
47 | expect(a_get('/projects/3/pipelines/46/test_report')).to have_been_made | |
48 | end | |
49 | ||
50 | it 'returns a single pipeline' do | |
51 | expect(@report).to be_a Gitlab::ObjectifiedHash | |
52 | end | |
53 | ||
54 | it 'returns information about a pipeline' do | |
55 | expect(@report.total_time).to eq(5) | |
56 | expect(@report.test_suites[0].name).to eq('Secure') | |
37 | 57 | end |
38 | 58 | end |
39 | 59 |
166 | 166 | it 'returns a paginated response of team members' do |
167 | 167 | expect(@team_members).to be_a Gitlab::PaginatedResponse |
168 | 168 | expect(@team_members.first.name).to eq('John Smith') |
169 | end | |
170 | end | |
171 | ||
172 | describe '.all_members' do | |
173 | before do | |
174 | stub_get('/projects/3/members/all', 'team_members') | |
175 | @all_members = Gitlab.all_members(3) | |
176 | end | |
177 | ||
178 | it 'gets the correct resource' do | |
179 | expect(a_get('/projects/3/members/all')).to have_been_made | |
180 | end | |
181 | ||
182 | it 'returns a paginated response of all team members including inherited' do | |
183 | expect(@all_members).to be_a Gitlab::PaginatedResponse | |
184 | expect(@all_members.first.name).to eq('John Smith') | |
169 | 185 | end |
170 | 186 | end |
171 | 187 |
0 | # frozen_string_literal: true | |
1 | ||
2 | require 'spec_helper' | |
3 | ||
4 | describe Gitlab::Client do | |
5 | describe '.issue_state_events' do | |
6 | before do | |
7 | stub_get('/projects/5/issues/42/resource_state_events', 'issue_resource_state_events') | |
8 | @events = Gitlab.issue_state_events(5, 42) | |
9 | end | |
10 | ||
11 | it 'gets the correct resource' do | |
12 | expect(a_get('/projects/5/issues/42/resource_state_events')).to have_been_made | |
13 | end | |
14 | ||
15 | it "returns a paginated response of project's issue's state events" do | |
16 | expect(@events).to be_a Gitlab::PaginatedResponse | |
17 | expect(@events.first.id).to eq(142) | |
18 | end | |
19 | end | |
20 | ||
21 | describe '.issue_state_event' do | |
22 | before do | |
23 | stub_get('/projects/5/issues/42/resource_state_events/142', 'issue_resource_state_event') | |
24 | @event = Gitlab.issue_state_event(5, 42, 142) | |
25 | end | |
26 | ||
27 | it 'gets the correct resource' do | |
28 | expect(a_get('/projects/5/issues/42/resource_state_events/142')).to have_been_made | |
29 | end | |
30 | ||
31 | it "returns a paginated response of project's issue's state event" do | |
32 | expect(@event).to be_a Gitlab::ObjectifiedHash | |
33 | expect(@event.user.name).to eq('Administrator') | |
34 | end | |
35 | end | |
36 | ||
37 | describe '.merge_request_state_events' do | |
38 | before do | |
39 | stub_get('/projects/5/merge_requests/42/resource_state_events', 'mr_resource_state_events') | |
40 | @events = Gitlab.merge_request_state_events(5, 42) | |
41 | end | |
42 | ||
43 | it 'gets the correct resource' do | |
44 | expect(a_get('/projects/5/merge_requests/42/resource_state_events')).to have_been_made | |
45 | end | |
46 | ||
47 | it "returns a paginated response of project's merge request's state events" do | |
48 | expect(@events).to be_a Gitlab::PaginatedResponse | |
49 | expect(@events.first.id).to eq(142) | |
50 | end | |
51 | end | |
52 | ||
53 | describe '.merge_request_state_event' do | |
54 | before do | |
55 | stub_get('/projects/5/merge_requests/42/resource_state_events/142', 'mr_resource_state_event') | |
56 | @event = Gitlab.merge_request_state_event(5, 42, 142) | |
57 | end | |
58 | ||
59 | it 'gets the correct resource' do | |
60 | expect(a_get('/projects/5/merge_requests/42/resource_state_events/142')).to have_been_made | |
61 | end | |
62 | ||
63 | it "returns a paginated response of project's merge request's state event" do | |
64 | expect(@event).to be_a Gitlab::ObjectifiedHash | |
65 | expect(@event.user.name).to eq('Administrator') | |
66 | end | |
67 | end | |
68 | end |
7 | 7 | stub_get('/runners', 'runners') |
8 | 8 | end |
9 | 9 | |
10 | context 'without scope' do | |
10 | context 'without extra queries' do | |
11 | 11 | before do |
12 | 12 | @runner = Gitlab.runners |
13 | 13 | end |
23 | 23 | end |
24 | 24 | end |
25 | 25 | |
26 | context 'with scope' do | |
27 | before do | |
28 | stub_get('/runners?scope=online', 'runners') | |
29 | @runner = Gitlab.runners(scope: :online) | |
30 | end | |
31 | ||
32 | it 'gets the correct resource' do | |
33 | expect(a_get('/runners').with(query: { scope: :online })).to have_been_made | |
26 | context 'with queries' do | |
27 | before do | |
28 | stub_get('/runners?type=instance_type', 'runners') | |
29 | @runner = Gitlab.runners(type: :instance_type) | |
30 | end | |
31 | ||
32 | it 'gets the correct resource' do | |
33 | expect(a_get('/runners').with(query: { type: :instance_type })).to have_been_made | |
34 | 34 | end |
35 | 35 | |
36 | 36 | it 'returns a paginated response of runners' do |
46 | 46 | stub_get('/runners/all', 'runners') |
47 | 47 | end |
48 | 48 | |
49 | context 'without scope' do | |
49 | context 'without extra queries' do | |
50 | 50 | before do |
51 | 51 | @runner = Gitlab.all_runners |
52 | 52 | end |
62 | 62 | end |
63 | 63 | end |
64 | 64 | |
65 | context 'with scope' do | |
66 | before do | |
67 | stub_get('/runners/all?scope=online', 'runners') | |
68 | @runner = Gitlab.all_runners(scope: :online) | |
69 | end | |
70 | ||
71 | it 'gets the correct resource' do | |
72 | expect(a_get('/runners/all').with(query: { scope: :online })).to have_been_made | |
65 | context 'with queries' do | |
66 | before do | |
67 | stub_get('/runners/all?type=instance_type', 'runners') | |
68 | @runner = Gitlab.all_runners(type: :instance_type) | |
69 | end | |
70 | ||
71 | it 'gets the correct resource' do | |
72 | expect(a_get('/runners/all').with(query: { type: :instance_type })).to have_been_made | |
73 | 73 | end |
74 | 74 | |
75 | 75 | it 'returns a paginated response of runners' do |
99 | 99 | |
100 | 100 | describe '.update_runner' do |
101 | 101 | before do |
102 | stub_put('/runners/6', 'runner_edit').with(query: { description: 'abcefg' }) | |
102 | stub_put('/runners/6', 'runner_edit').with(body: { description: 'abcefg' }) | |
103 | 103 | @runner = Gitlab.update_runner(6, description: 'abcefg') |
104 | 104 | end |
105 | 105 | |
106 | 106 | it 'gets the correct resource' do |
107 | expect(a_put('/runners/6').with(query: { description: 'abcefg' })).to have_been_made | |
107 | expect(a_put('/runners/6').with(body: { description: 'abcefg' })).to have_been_made | |
108 | 108 | end |
109 | 109 | |
110 | 110 | it 'returns an updated response of a runner' do |
191 | 191 | end |
192 | 192 | end |
193 | 193 | |
194 | describe '.group_runners' do | |
195 | before do | |
196 | stub_get('/groups/9/runners', 'group_runners') | |
197 | end | |
198 | ||
199 | context 'without extra queries' do | |
200 | before do | |
201 | @runners = Gitlab.group_runners(9) | |
202 | end | |
203 | ||
204 | it 'gets the correct resource' do | |
205 | expect(a_get('/groups/9/runners')).to have_been_made | |
206 | end | |
207 | ||
208 | it 'returns a paginated response of runners' do | |
209 | expect(@runners).to be_a Gitlab::PaginatedResponse | |
210 | end | |
211 | end | |
212 | ||
213 | context 'with queries' do | |
214 | before do | |
215 | stub_get('/groups/9/runners?type=instance_type', 'group_runners') | |
216 | @runner = Gitlab.group_runners(9, type: :instance_type) | |
217 | end | |
218 | ||
219 | it 'gets the correct resource' do | |
220 | expect(a_get('/groups/9/runners').with(query: { type: :instance_type })).to have_been_made | |
221 | end | |
222 | ||
223 | it 'returns a paginated response of runners' do | |
224 | expect(@runner).to be_a Gitlab::PaginatedResponse | |
225 | end | |
226 | end | |
227 | end | |
228 | ||
194 | 229 | describe '.register_runner' do |
195 | 230 | before do |
196 | 231 | stub_post('/runners', 'register_runner_response').with(body: { token: '6337ff461c94fd3fa32ba3b1ff4125', description: 'Some Description', active: true, locked: false }) |
67 | 67 | expect(described_class.new(response_double).send(:build_error_message)).to match(/Retry text/) |
68 | 68 | end |
69 | 69 | end |
70 | ||
71 | describe '#error_code' do | |
72 | it 'returns the value when available' do | |
73 | headers = { 'content-type' => 'application/json' } | |
74 | response_double = double( | |
75 | 'response', | |
76 | body: 'Retry later', | |
77 | to_s: 'Retry text', | |
78 | parsed_response: { message: 'Retry hash' }, | |
79 | code: 400, | |
80 | error_code: 'conflict', | |
81 | options: {}, | |
82 | headers: headers, | |
83 | request: @request_double | |
84 | ) | |
85 | ||
86 | expect(described_class.new(response_double).error_code).to eq 'conflict' | |
87 | end | |
88 | ||
89 | it 'returns nothing when unavailable' do | |
90 | headers = { 'content-type' => 'application/json' } | |
91 | response_double = double( | |
92 | 'response', | |
93 | body: 'Retry later', | |
94 | to_s: 'Retry text', | |
95 | parsed_response: { message: 'Retry hash' }, | |
96 | code: 400, | |
97 | options: {}, | |
98 | headers: headers, | |
99 | request: @request_double | |
100 | ) | |
101 | ||
102 | expect(described_class.new(response_double).error_code).to eq '' | |
103 | end | |
104 | end | |
70 | 105 | end |
12 | 12 | let(:oh) { described_class.new(hash) } |
13 | 13 | |
14 | 14 | it 'allows to call Hash methods' do |
15 | expect(oh.dig('foo')).to eq('bar') | |
16 | expect(oh.merge(key: :value)).to eq({ 'foo' => 'bar', key: :value }) | |
15 | expect(oh['foo']).to eq('bar') | |
16 | expect(oh.merge(key: :value)).to eq('foo' => 'bar', key: :value) | |
17 | 17 | end |
18 | 18 | |
19 | 19 | it 'warns about calling Hash methods' do |
72 | 72 | allow(@paginated_response).to receive(:has_next_page?).and_return(true) |
73 | 73 | allow(@paginated_response).to receive(:next_page).and_return(next_page) |
74 | 74 | allow(next_page).to receive(:has_next_page?).and_return(true) |
75 | # NOTE: | |
76 | # Do not define :next_page on the next_page double to prove that it is NOT | |
77 | # called even though :has_next_page? has been defined to claim another | |
78 | # page is available. | |
75 | # NOTE: Do not define :next_page on the next_page double | |
76 | # to prove that it is NOT called even though :has_next_page? | |
77 | # has been defined to claim another page is available. | |
79 | 78 | allow(next_page).to receive(:to_ary).and_return([5, 6, 7, 8]) |
80 | 79 | expect(@paginated_response.lazy_paginate.take(8)).to contain_exactly(1, 2, 3, 4, 5, 6, 7, 8) |
81 | 80 | end |
62 | 62 | it 'returns an Array of matching commands' do |
63 | 63 | completed_cmds = @comp.call 'issue' |
64 | 64 | expect(completed_cmds).to be_a Array |
65 | expect(completed_cmds.sort).to eq(%w[issue issue_label_event issue_label_events issue_links issue_note issue_notes issues]) | |
65 | expect(completed_cmds.sort).to eq(%w[issue issue_label_event issue_label_events issue_links issue_note issue_notes issue_state_event issue_state_events issues]) | |
66 | 66 | end |
67 | 67 | end |
68 | 68 | end |