Commit 8ba33b5d authored by Rémy Coutable's avatar Rémy Coutable

Merge branch 'ee-39880-merge-method-api' into 'master'

Port of 39880-merge-method-api to EE

Closes gitlab-ce#39880

See merge request gitlab-org/gitlab-ee!5154
parents fba1f9dc 6436f6ad
---
title: 'API: Add parameter merge_method to projects'
merge_request:
author: Jan Beckmann
type: added
...@@ -16,6 +16,21 @@ Values for the project visibility level are: ...@@ -16,6 +16,21 @@ Values for the project visibility level are:
* `public`: * `public`:
The project can be accessed without any authentication. The project can be accessed without any authentication.
## Project merge method
There are currently three options for `merge_method` to choose from:
* `merge`:
A merge commit is created for every merge, and merging is allowed as long as there are no conflicts.
* `rebase_merge`:
A merge commit is created for every merge, but merging is only allowed if fast-forward merge is possible.
This way you could make sure that if this merge request would build, after merging to target branch it would also build.
* `ff`:
No merge commits are created and all merges are fast-forwarded, which means that merging is only allowed if the branch could be fast-forwarded.
## List all projects ## List all projects
Get a list of all visible projects across GitLab for the authenticated user. Get a list of all visible projects across GitLab for the authenticated user.
...@@ -95,6 +110,7 @@ GET /projects ...@@ -95,6 +110,7 @@ GET /projects
"only_allow_merge_if_all_discussions_are_resolved": false, "only_allow_merge_if_all_discussions_are_resolved": false,
"request_access_enabled": false, "request_access_enabled": false,
"approvals_before_merge": 0, "approvals_before_merge": 0,
"merge_method": "merge",
"statistics": { "statistics": {
"commit_count": 37, "commit_count": 37,
"storage_size": 1038090, "storage_size": 1038090,
...@@ -175,6 +191,7 @@ GET /projects ...@@ -175,6 +191,7 @@ GET /projects
"only_allow_merge_if_all_discussions_are_resolved": false, "only_allow_merge_if_all_discussions_are_resolved": false,
"request_access_enabled": false, "request_access_enabled": false,
"approvals_before_merge": 0, "approvals_before_merge": 0,
"merge_method": "merge",
"statistics": { "statistics": {
"commit_count": 12, "commit_count": 12,
"storage_size": 2066080, "storage_size": 2066080,
...@@ -280,6 +297,7 @@ GET /users/:user_id/projects ...@@ -280,6 +297,7 @@ GET /users/:user_id/projects
"only_allow_merge_if_pipeline_succeeds": false, "only_allow_merge_if_pipeline_succeeds": false,
"only_allow_merge_if_all_discussions_are_resolved": false, "only_allow_merge_if_all_discussions_are_resolved": false,
"request_access_enabled": false, "request_access_enabled": false,
"merge_method": "merge",
"statistics": { "statistics": {
"commit_count": 37, "commit_count": 37,
"storage_size": 1038090, "storage_size": 1038090,
...@@ -359,6 +377,7 @@ GET /users/:user_id/projects ...@@ -359,6 +377,7 @@ GET /users/:user_id/projects
"only_allow_merge_if_pipeline_succeeds": false, "only_allow_merge_if_pipeline_succeeds": false,
"only_allow_merge_if_all_discussions_are_resolved": false, "only_allow_merge_if_all_discussions_are_resolved": false,
"request_access_enabled": false, "request_access_enabled": false,
"merge_method": "merge",
"statistics": { "statistics": {
"commit_count": 12, "commit_count": 12,
"storage_size": 2066080, "storage_size": 2066080,
...@@ -471,6 +490,7 @@ GET /projects/:id ...@@ -471,6 +490,7 @@ GET /projects/:id
"printing_merge_requests_link_enabled": true, "printing_merge_requests_link_enabled": true,
"request_access_enabled": false, "request_access_enabled": false,
"approvals_before_merge": 0, "approvals_before_merge": 0,
"merge_method": "merge",
"statistics": { "statistics": {
"commit_count": 37, "commit_count": 37,
"storage_size": 1038090, "storage_size": 1038090,
...@@ -555,6 +575,7 @@ POST /projects ...@@ -555,6 +575,7 @@ POST /projects
| `public_jobs` | boolean | no | If `true`, jobs can be viewed by non-project-members | | `public_jobs` | boolean | no | If `true`, jobs can be viewed by non-project-members |
| `only_allow_merge_if_pipeline_succeeds` | boolean | no | Set whether merge requests can only be merged with successful jobs | | `only_allow_merge_if_pipeline_succeeds` | boolean | no | Set whether merge requests can only be merged with successful jobs |
| `only_allow_merge_if_all_discussions_are_resolved` | boolean | no | Set whether merge requests can only be merged when all the discussions are resolved | | `only_allow_merge_if_all_discussions_are_resolved` | boolean | no | Set whether merge requests can only be merged when all the discussions are resolved |
| `merge_method` | string | no | Set the merge method used |
| `lfs_enabled` | boolean | no | Enable LFS | | `lfs_enabled` | boolean | no | Enable LFS |
| `request_access_enabled` | boolean | no | Allow users to request member access | | `request_access_enabled` | boolean | no | Allow users to request member access |
| `tag_list` | array | no | The list of tags for a project; put array of tags, that should be finally assigned to a project | | `tag_list` | array | no | The list of tags for a project; put array of tags, that should be finally assigned to a project |
...@@ -592,6 +613,7 @@ POST /projects/user/:user_id ...@@ -592,6 +613,7 @@ POST /projects/user/:user_id
| `public_jobs` | boolean | no | If `true`, jobs can be viewed by non-project-members | | `public_jobs` | boolean | no | If `true`, jobs can be viewed by non-project-members |
| `only_allow_merge_if_pipeline_succeeds` | boolean | no | Set whether merge requests can only be merged with successful jobs | | `only_allow_merge_if_pipeline_succeeds` | boolean | no | Set whether merge requests can only be merged with successful jobs |
| `only_allow_merge_if_all_discussions_are_resolved` | boolean | no | Set whether merge requests can only be merged when all the discussions are resolved | | `only_allow_merge_if_all_discussions_are_resolved` | boolean | no | Set whether merge requests can only be merged when all the discussions are resolved |
| `merge_method` | string | no | Set the merge method used |
| `lfs_enabled` | boolean | no | Enable LFS | | `lfs_enabled` | boolean | no | Enable LFS |
| `request_access_enabled` | boolean | no | Allow users to request member access | | `request_access_enabled` | boolean | no | Allow users to request member access |
| `tag_list` | array | no | The list of tags for a project; put array of tags, that should be finally assigned to a project | | `tag_list` | array | no | The list of tags for a project; put array of tags, that should be finally assigned to a project |
...@@ -629,6 +651,7 @@ PUT /projects/:id ...@@ -629,6 +651,7 @@ PUT /projects/:id
| `public_jobs` | boolean | no | If `true`, jobs can be viewed by non-project-members | | `public_jobs` | boolean | no | If `true`, jobs can be viewed by non-project-members |
| `only_allow_merge_if_pipeline_succeeds` | boolean | no | Set whether merge requests can only be merged with successful jobs | | `only_allow_merge_if_pipeline_succeeds` | boolean | no | Set whether merge requests can only be merged with successful jobs |
| `only_allow_merge_if_all_discussions_are_resolved` | boolean | no | Set whether merge requests can only be merged when all the discussions are resolved | | `only_allow_merge_if_all_discussions_are_resolved` | boolean | no | Set whether merge requests can only be merged when all the discussions are resolved |
| `merge_method` | string | no | Set the merge method used |
| `lfs_enabled` | boolean | no | Enable LFS | | `lfs_enabled` | boolean | no | Enable LFS |
| `request_access_enabled` | boolean | no | Allow users to request member access | | `request_access_enabled` | boolean | no | Allow users to request member access |
| `tag_list` | array | no | The list of tags for a project; put array of tags, that should be finally assigned to a project | | `tag_list` | array | no | The list of tags for a project; put array of tags, that should be finally assigned to a project |
...@@ -734,6 +757,7 @@ Example responses: ...@@ -734,6 +757,7 @@ Example responses:
"only_allow_merge_if_pipeline_succeeds": false, "only_allow_merge_if_pipeline_succeeds": false,
"only_allow_merge_if_all_discussions_are_resolved": false, "only_allow_merge_if_all_discussions_are_resolved": false,
"request_access_enabled": false, "request_access_enabled": false,
"merge_method": "merge",
"_links": { "_links": {
"self": "http://example.com/api/v4/projects", "self": "http://example.com/api/v4/projects",
"issues": "http://example.com/api/v4/projects/1/issues", "issues": "http://example.com/api/v4/projects/1/issues",
...@@ -811,6 +835,7 @@ Example response: ...@@ -811,6 +835,7 @@ Example response:
"only_allow_merge_if_pipeline_succeeds": false, "only_allow_merge_if_pipeline_succeeds": false,
"only_allow_merge_if_all_discussions_are_resolved": false, "only_allow_merge_if_all_discussions_are_resolved": false,
"request_access_enabled": false, "request_access_enabled": false,
"merge_method": "merge",
"_links": { "_links": {
"self": "http://example.com/api/v4/projects", "self": "http://example.com/api/v4/projects",
"issues": "http://example.com/api/v4/projects/1/issues", "issues": "http://example.com/api/v4/projects/1/issues",
...@@ -887,6 +912,7 @@ Example response: ...@@ -887,6 +912,7 @@ Example response:
"only_allow_merge_if_pipeline_succeeds": false, "only_allow_merge_if_pipeline_succeeds": false,
"only_allow_merge_if_all_discussions_are_resolved": false, "only_allow_merge_if_all_discussions_are_resolved": false,
"request_access_enabled": false, "request_access_enabled": false,
"merge_method": "merge",
"_links": { "_links": {
"self": "http://example.com/api/v4/projects", "self": "http://example.com/api/v4/projects",
"issues": "http://example.com/api/v4/projects/1/issues", "issues": "http://example.com/api/v4/projects/1/issues",
...@@ -981,6 +1007,7 @@ Example response: ...@@ -981,6 +1007,7 @@ Example response:
"only_allow_merge_if_pipeline_succeeds": false, "only_allow_merge_if_pipeline_succeeds": false,
"only_allow_merge_if_all_discussions_are_resolved": false, "only_allow_merge_if_all_discussions_are_resolved": false,
"request_access_enabled": false, "request_access_enabled": false,
"merge_method": "merge",
"_links": { "_links": {
"self": "http://example.com/api/v4/projects", "self": "http://example.com/api/v4/projects",
"issues": "http://example.com/api/v4/projects/1/issues", "issues": "http://example.com/api/v4/projects/1/issues",
...@@ -1075,6 +1102,7 @@ Example response: ...@@ -1075,6 +1102,7 @@ Example response:
"only_allow_merge_if_pipeline_succeeds": false, "only_allow_merge_if_pipeline_succeeds": false,
"only_allow_merge_if_all_discussions_are_resolved": false, "only_allow_merge_if_all_discussions_are_resolved": false,
"request_access_enabled": false, "request_access_enabled": false,
"merge_method": "merge",
"_links": { "_links": {
"self": "http://example.com/api/v4/projects", "self": "http://example.com/api/v4/projects",
"issues": "http://example.com/api/v4/projects/1/issues", "issues": "http://example.com/api/v4/projects/1/issues",
......
...@@ -206,6 +206,7 @@ module API ...@@ -206,6 +206,7 @@ module API
expose :request_access_enabled expose :request_access_enabled
expose :only_allow_merge_if_all_discussions_are_resolved expose :only_allow_merge_if_all_discussions_are_resolved
expose :printing_merge_request_link_enabled expose :printing_merge_request_link_enabled
expose :merge_method
expose :statistics, using: 'API::Entities::ProjectStatistics', if: :statistics expose :statistics, using: 'API::Entities::ProjectStatistics', if: :statistics
......
...@@ -28,6 +28,7 @@ module API ...@@ -28,6 +28,7 @@ module API
optional :tag_list, type: Array[String], desc: 'The list of tags for a project' optional :tag_list, type: Array[String], desc: 'The list of tags for a project'
optional :avatar, type: File, desc: 'Avatar image for project' optional :avatar, type: File, desc: 'Avatar image for project'
optional :printing_merge_request_link_enabled, type: Boolean, desc: 'Show link to create/view merge request when pushing from the command line' optional :printing_merge_request_link_enabled, type: Boolean, desc: 'Show link to create/view merge request when pushing from the command line'
optional :merge_method, type: String, values: %w(ff rebase_merge merge), desc: 'The merge method used when merging merge requests'
end end
params :optional_params_ee do params :optional_params_ee do
...@@ -280,6 +281,7 @@ module API ...@@ -280,6 +281,7 @@ module API
:issues_enabled, :issues_enabled,
:lfs_enabled, :lfs_enabled,
:merge_requests_enabled, :merge_requests_enabled,
:merge_method,
:name, :name,
:only_allow_merge_if_all_discussions_are_resolved, :only_allow_merge_if_all_discussions_are_resolved,
:only_allow_merge_if_pipeline_succeeds, :only_allow_merge_if_pipeline_succeeds,
......
...@@ -452,7 +452,8 @@ describe API::Projects do ...@@ -452,7 +452,8 @@ describe API::Projects do
only_allow_merge_if_pipeline_succeeds: false, only_allow_merge_if_pipeline_succeeds: false,
request_access_enabled: true, request_access_enabled: true,
only_allow_merge_if_all_discussions_are_resolved: false, only_allow_merge_if_all_discussions_are_resolved: false,
ci_config_path: 'a/custom/path' ci_config_path: 'a/custom/path',
merge_method: 'ff'
}) })
post api('/projects', user), project post api('/projects', user), project
...@@ -569,6 +570,22 @@ describe API::Projects do ...@@ -569,6 +570,22 @@ describe API::Projects do
expect(json_response['only_allow_merge_if_all_discussions_are_resolved']).to be_truthy expect(json_response['only_allow_merge_if_all_discussions_are_resolved']).to be_truthy
end end
it 'sets the merge method of a project to rebase merge' do
project = attributes_for(:project, merge_method: 'rebase_merge')
post api('/projects', user), project
expect(json_response['merge_method']).to eq('rebase_merge')
end
it 'rejects invalid values for merge_method' do
project = attributes_for(:project, merge_method: 'totally_not_valid_method')
post api('/projects', user), project
expect(response).to have_gitlab_http_status(400)
end
it 'ignores import_url when it is nil' do it 'ignores import_url when it is nil' do
project = attributes_for(:project, import_url: nil) project = attributes_for(:project, import_url: nil)
...@@ -873,6 +890,7 @@ describe API::Projects do ...@@ -873,6 +890,7 @@ describe API::Projects do
expect(json_response['only_allow_merge_if_pipeline_succeeds']).to eq(project.only_allow_merge_if_pipeline_succeeds) expect(json_response['only_allow_merge_if_pipeline_succeeds']).to eq(project.only_allow_merge_if_pipeline_succeeds)
expect(json_response['only_allow_merge_if_all_discussions_are_resolved']).to eq(project.only_allow_merge_if_all_discussions_are_resolved) expect(json_response['only_allow_merge_if_all_discussions_are_resolved']).to eq(project.only_allow_merge_if_all_discussions_are_resolved)
expect(json_response).not_to have_key('repository_storage') expect(json_response).not_to have_key('repository_storage')
expect(json_response['merge_method']).to eq(project.merge_method.to_s)
end end
it 'returns a project by path name' do it 'returns a project by path name' do
...@@ -1540,6 +1558,26 @@ describe API::Projects do ...@@ -1540,6 +1558,26 @@ describe API::Projects do
expect(json_response[k.to_s]).to eq(v) expect(json_response[k.to_s]).to eq(v)
end end
end end
it 'updates merge_method' do
project_param = { merge_method: 'ff' }
put api("/projects/#{project3.id}", user), project_param
expect(response).to have_gitlab_http_status(200)
project_param.each_pair do |k, v|
expect(json_response[k.to_s]).to eq(v)
end
end
it 'rejects to update merge_method when merge_method is invalid' do
project_param = { merge_method: 'invalid' }
put api("/projects/#{project3.id}", user), project_param
expect(response).to have_gitlab_http_status(400)
end
end end
context 'when authenticated as project master' do context 'when authenticated as project master' do
...@@ -1557,6 +1595,7 @@ describe API::Projects do ...@@ -1557,6 +1595,7 @@ describe API::Projects do
wiki_enabled: true, wiki_enabled: true,
snippets_enabled: true, snippets_enabled: true,
merge_requests_enabled: true, merge_requests_enabled: true,
merge_method: 'ff',
description: 'new description' } description: 'new description' }
put api("/projects/#{project3.id}", user4), project_param put api("/projects/#{project3.id}", user4), project_param
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment