diff options
author | Luke Duncalfe <lduncalfe@eml.cc> | 2019-03-29 14:07:03 +1300 |
---|---|---|
committer | Luke Duncalfe <lduncalfe@eml.cc> | 2019-04-09 09:36:42 +1200 |
commit | aa352a95df665ded5178c1b26d4492433e47714e (patch) | |
tree | 47e60787a36f6ab36d4649cef763f16b636583d8 /lib/api | |
parent | 225edb0d2d7737cf52ef5cd358082d08e20feaa4 (diff) | |
download | gitlab-ce-aa352a95df665ded5178c1b26d4492433e47714e.tar.gz |
Support merge request create with push options
To create a new merge request:
git push -u origin -o merge_request.create
To create a new merge request setting target branch:
git push -u origin -o merge_request.create \
-o merge_request.target=123
To update an existing merge request with a new target branch:
git push -u origin -o merge_request.target=123
A new Gitlab::PushOptions class handles parsing and validating the push
options array. This can be the start of the standard of GitLab accepting
push options that follow namespacing rules. Rules are discussed in issue
https://gitlab.com/gitlab-org/gitlab-ce/issues/43263.
E.g. these push options:
-o merge_request.create -o merge_request.target=123
Become parsed as:
{
merge_request: {
create: true,
target: '123',
}
}
And are fetched with the class via:
push_options.get(:merge_request)
push_options.get(:merge_request, :create)
push_options.get(:merge_request, :target)
A new MergeRequests::PushOptionsHandlerService takes the `merge_request`
namespaced push options and handles creating and updating
merge requests.
Any errors encountered are passed to the existing `output` Hash in
Api::Internal's `post_receive` endpoint, and passed to gitlab-shell
where they're output to the user.
Issue https://gitlab.com/gitlab-org/gitlab-ce/issues/43263
Diffstat (limited to 'lib/api')
-rw-r--r-- | lib/api/helpers/internal_helpers.rb | 5 | ||||
-rw-r--r-- | lib/api/internal.rb | 36 |
2 files changed, 34 insertions, 7 deletions
diff --git a/lib/api/helpers/internal_helpers.rb b/lib/api/helpers/internal_helpers.rb index 3fd824877ae..5014ba51b94 100644 --- a/lib/api/helpers/internal_helpers.rb +++ b/lib/api/helpers/internal_helpers.rb @@ -43,6 +43,11 @@ module API ::MergeRequests::GetUrlsService.new(project).execute(params[:changes]) end + def push_options_warning(warning) + options = Array.wrap(params[:push_options]).map { |p| "'#{p}'" }.join(' ') + "Error encountered with push options #{options}: #{warning}" + end + def redis_ping result = Gitlab::Redis::SharedState.with { |redis| redis.ping } diff --git a/lib/api/internal.rb b/lib/api/internal.rb index 9c7b9146c8f..75202fa953c 100644 --- a/lib/api/internal.rb +++ b/lib/api/internal.rb @@ -256,19 +256,41 @@ module API post '/post_receive' do status 200 + output = {} # Messages to gitlab-shell + user = identify(params[:identifier]) + project = Gitlab::GlRepository.parse(params[:gl_repository]).first + push_options = Gitlab::PushOptions.new(params[:push_options]) + PostReceive.perform_async(params[:gl_repository], params[:identifier], params[:changes], params[:push_options].to_a) + + if (mr_options = push_options.get(:merge_request)) + begin + service = ::MergeRequests::PushOptionsHandlerService.new( + project, + user, + params[:changes], + mr_options + ).execute + + if service.errors.present? + output[:warnings] = push_options_warning(service.errors.join("\n\n")) + end + rescue ::MergeRequests::PushOptionsHandlerService::Error => e + output[:warnings] = push_options_warning(e.message) + rescue Gitlab::Access::AccessDeniedError + output[:warnings] = push_options_warning('User access was denied') + end + end + broadcast_message = BroadcastMessage.current&.last&.message reference_counter_decreased = Gitlab::ReferenceCounter.new(params[:gl_repository]).decrease - output = { - merge_request_urls: merge_request_urls, + output.merge!( broadcast_message: broadcast_message, - reference_counter_decreased: reference_counter_decreased - } - - project = Gitlab::GlRepository.parse(params[:gl_repository]).first - user = identify(params[:identifier]) + reference_counter_decreased: reference_counter_decreased, + merge_request_urls: merge_request_urls + ) # A user is not guaranteed to be returned; an orphaned write deploy # key could be used |