Skip to content
Snippets Groups Projects
Unverified Commit 50342028 authored by Michael Kozono's avatar Michael Kozono
Browse files

Simplify internal post receive messages

Instead of sending varied data to Gitaly, and making Gitaly construct
various messages, build the messages first and have Gitaly print
either basic messages or alert messages, in the order they come.

Depends on https://gitlab.com/gitlab-org/gitaly/merge_requests/1410
parent a82e14c1
No related branches found
No related tags found
No related merge requests found
Loading
Loading
@@ -1705,6 +1705,18 @@ module API
class ClusterGroup < Cluster
expose :group, using: Entities::BasicGroupDetails
end
module InternalPostReceive
class Message < Grape::Entity
expose :message
expose :type
end
class Response < Grape::Entity
expose :messages, using: Message
expose :reference_counter_decreased
end
end
end
end
 
Loading
Loading
Loading
Loading
@@ -44,8 +44,6 @@ module API
end
 
def process_mr_push_options(push_options, project, user, changes)
output = {}
Gitlab::QueryLimiting.whitelist('https://gitlab.com/gitlab-org/gitlab-ce/issues/61359')
 
service = ::MergeRequests::PushOptionsHandlerService.new(
Loading
Loading
@@ -56,15 +54,13 @@ module API
).execute
 
if service.errors.present?
output[:warnings] = push_options_warning(service.errors.join("\n\n"))
push_options_warning(service.errors.join("\n\n"))
end
output
end
 
def push_options_warning(warning)
options = Array.wrap(params[:push_options]).map { |p| "'#{p}'" }.join(' ')
"Error encountered with push options #{options}: #{warning}"
"WARNINGS:\nError encountered with push options #{options}: #{warning}"
end
 
def redis_ping
Loading
Loading
Loading
Loading
@@ -256,25 +256,26 @@ module API
post '/post_receive' do
status 200
 
output = {} # Messages to gitlab-shell
response = Gitlab::InternalPostReceive::Response.new
user = identify(params[:identifier])
project = Gitlab::GlRepository.parse(params[:gl_repository]).first
push_options = Gitlab::PushOptions.new(params[:push_options])
 
response.reference_counter_decreased = Gitlab::ReferenceCounter.new(params[:gl_repository]).decrease
PostReceive.perform_async(params[:gl_repository], params[:identifier],
params[:changes], push_options.as_json)
 
mr_options = push_options.get(:merge_request)
output.merge!(process_mr_push_options(mr_options, project, user, params[:changes])) if mr_options.present?
if mr_options.present?
message = process_mr_push_options(mr_options, project, user, params[:changes])
response.add_alert_message(message)
end
 
broadcast_message = BroadcastMessage.current&.last&.message
reference_counter_decreased = Gitlab::ReferenceCounter.new(params[:gl_repository]).decrease
response.add_alert_message(broadcast_message)
 
output.merge!(
broadcast_message: broadcast_message,
reference_counter_decreased: reference_counter_decreased,
merge_request_urls: merge_request_urls
)
response.add_merge_request_urls(merge_request_urls)
 
# A user is not guaranteed to be returned; an orphaned write deploy
# key could be used
Loading
Loading
@@ -282,11 +283,11 @@ module API
redirect_message = Gitlab::Checks::ProjectMoved.fetch_message(user.id, project.id)
project_created_message = Gitlab::Checks::ProjectCreated.fetch_message(user.id, project.id)
 
output[:redirected_message] = redirect_message if redirect_message
output[:project_created_message] = project_created_message if project_created_message
response.add_basic_message(redirect_message)
response.add_basic_message(project_created_message)
end
 
output
present response, with: Entities::InternalPostReceive::Response
end
end
end
Loading
Loading
# frozen_string_literal: true
module Gitlab
module InternalPostReceive
class Response
attr_accessor :reference_counter_decreased
attr_reader :messages
Message = Struct.new(:message, :type) do
def self.basic(text)
new(text, :basic)
end
def self.alert(text)
new(text, :alert)
end
end
def initialize
@messages = []
@reference_counter_decreased = false
end
def add_merge_request_urls(urls_data)
urls_data.each do |url_data|
add_merge_request_url(url_data)
end
end
def add_merge_request_url(url_data)
message = if url_data[:new_merge_request]
"To create a merge request for #{url_data[:branch_name]}, visit:"
else
"View merge request for #{url_data[:branch_name]}:"
end
message += "\n #{url_data[:url]}"
add_basic_message(message)
end
def add_basic_message(text)
@messages << Message.basic(text) if text.present?
end
def add_alert_message(text)
@messages.unshift(Message.alert(text)) if text.present?
end
end
end
end
# frozen_string_literal: true
require 'spec_helper'
describe Gitlab::InternalPostReceive::Response do
subject { described_class.new }
describe '#add_merge_request_urls' do
context 'when there are urls_data' do
it 'adds a message for each merge request URL' do
urls_data = [
{ new_merge_request: false, branch_name: 'foo', url: 'http://example.com/foo/bar/merge_requests/1' },
{ new_merge_request: true, branch_name: 'bar', url: 'http://example.com/foo/bar/merge_requests/new?merge_request%5Bsource_branch%5D=bar' }
]
subject.add_merge_request_urls(urls_data)
expected = [a_kind_of(described_class::Message), a_kind_of(described_class::Message)]
expect(subject.messages).to match(expected)
end
end
end
describe '#add_merge_request_url' do
context 'when :new_merge_request is false' do
it 'adds a basic message to view the existing merge request' do
url_data = { new_merge_request: false, branch_name: 'foo', url: 'http://example.com/foo/bar/merge_requests/1' }
subject.add_merge_request_url(url_data)
message = <<~MESSAGE.strip
View merge request for foo:
http://example.com/foo/bar/merge_requests/1
MESSAGE
expect(subject.messages.first.message).to eq(message)
expect(subject.messages.first.type).to eq(:basic)
end
end
context 'when :new_merge_request is true' do
it 'adds a basic message to create a new merge request' do
url_data = { new_merge_request: true, branch_name: 'bar', url: 'http://example.com/foo/bar/merge_requests/new?merge_request%5Bsource_branch%5D=bar' }
subject.add_merge_request_url(url_data)
message = <<~MESSAGE.strip
To create a merge request for bar, visit:
http://example.com/foo/bar/merge_requests/new?merge_request%5Bsource_branch%5D=bar
MESSAGE
expect(subject.messages.first.message).to eq(message)
expect(subject.messages.first.type).to eq(:basic)
end
end
end
describe '#add_basic_message' do
context 'when text is present' do
it 'adds a basic message' do
subject.add_basic_message('hello')
expect(subject.messages.first.message).to eq('hello')
expect(subject.messages.first.type).to eq(:basic)
end
end
context 'when text is blank' do
it 'does not add a message' do
subject.add_basic_message(' ')
expect(subject.messages).to be_blank
end
end
end
describe '#add_alert_message' do
context 'when text is present' do
it 'adds a alert message' do
subject.add_alert_message('hello')
expect(subject.messages.first.message).to eq('hello')
expect(subject.messages.first.type).to eq(:alert)
end
end
context 'when text is blank' do
it 'does not add a message' do
subject.add_alert_message(' ')
expect(subject.messages).to be_blank
end
end
end
describe '#reference_counter_decreased' do
context 'initially' do
it 'reference_counter_decreased is set to false' do
expect(subject.reference_counter_decreased).to eq(false)
end
end
end
describe '#reference_counter_decreased=' do
context 'when the argument is truthy' do
it 'reference_counter_decreased is truthy' do
subject.reference_counter_decreased = true
expect(subject.reference_counter_decreased).to be_truthy
end
end
context 'when the argument is falsey' do
it 'reference_counter_decreased is falsey' do
subject.reference_counter_decreased = false
expect(subject.reference_counter_decreased).to be_falsey
end
end
end
end
Loading
Loading
@@ -925,19 +925,20 @@ describe API::Internal do
it 'returns link to create new merge request' do
post api('/internal/post_receive'), params: valid_params
 
expect(json_response['merge_request_urls']).to match [{
"branch_name" => branch_name,
"url" => "http://#{Gitlab.config.gitlab.host}/#{project.full_path}/merge_requests/new?merge_request%5Bsource_branch%5D=#{branch_name}",
"new_merge_request" => true
}]
message = <<~MESSAGE.strip
To create a merge request for #{branch_name}, visit:
http://#{Gitlab.config.gitlab.host}/#{project.full_path}/merge_requests/new?merge_request%5Bsource_branch%5D=#{branch_name}
MESSAGE
expect(json_response['messages']).to include(build_basic_message(message))
end
 
it 'returns empty array if printing_merge_request_link_enabled is false' do
it 'returns no merge request messages if printing_merge_request_link_enabled is false' do
project.update!(printing_merge_request_link_enabled: false)
 
post api('/internal/post_receive'), params: valid_params
 
expect(json_response['merge_request_urls']).to eq([])
expect(json_response['messages']).to be_blank
end
 
it 'does not invoke MergeRequests::PushOptionsHandlerService' do
Loading
Loading
@@ -968,11 +969,12 @@ describe API::Internal do
it 'links to the newly created merge request' do
post api('/internal/post_receive'), params: valid_params
 
expect(json_response['merge_request_urls']).to match [{
'branch_name' => branch_name,
'url' => "http://#{Gitlab.config.gitlab.host}/#{project.full_path}/merge_requests/1",
'new_merge_request' => false
}]
message = <<~MESSAGE.strip
View merge request for #{branch_name}:
http://#{Gitlab.config.gitlab.host}/#{project.full_path}/merge_requests/1
MESSAGE
expect(json_response['messages']).to include(build_basic_message(message))
end
 
it 'adds errors on the service instance to warnings' do
Loading
Loading
@@ -982,7 +984,8 @@ describe API::Internal do
 
post api('/internal/post_receive'), params: valid_params
 
expect(json_response['warnings']).to eq('Error encountered with push options \'merge_request.create\': my error')
message = "WARNINGS:\nError encountered with push options 'merge_request.create': my error"
expect(json_response['messages']).to include(build_alert_message(message))
end
 
it 'adds ActiveRecord errors on invalid MergeRequest records to warnings' do
Loading
Loading
@@ -995,38 +998,39 @@ describe API::Internal do
 
post api('/internal/post_receive'), params: valid_params
 
expect(json_response['warnings']).to eq('Error encountered with push options \'merge_request.create\': my error')
message = "WARNINGS:\nError encountered with push options 'merge_request.create': my error"
expect(json_response['messages']).to include(build_alert_message(message))
end
end
 
context 'broadcast message exists' do
let!(:broadcast_message) { create(:broadcast_message, starts_at: 1.day.ago, ends_at: 1.day.from_now ) }
 
it 'returns one broadcast message' do
it 'outputs a broadcast message' do
post api('/internal/post_receive'), params: valid_params
 
expect(response).to have_gitlab_http_status(200)
expect(json_response['broadcast_message']).to eq(broadcast_message.message)
expect(json_response['messages']).to include(build_alert_message(broadcast_message.message))
end
end
 
context 'broadcast message does not exist' do
it 'returns empty string' do
it 'does not output a broadcast message' do
post api('/internal/post_receive'), params: valid_params
 
expect(response).to have_gitlab_http_status(200)
expect(json_response['broadcast_message']).to eq(nil)
expect(has_alert_messages?(json_response['messages'])).to be_falsey
end
end
 
context 'nil broadcast message' do
it 'returns empty string' do
it 'does not output a broadcast message' do
allow(BroadcastMessage).to receive(:current).and_return(nil)
 
post api('/internal/post_receive'), params: valid_params
 
expect(response).to have_gitlab_http_status(200)
expect(json_response['broadcast_message']).to eq(nil)
expect(has_alert_messages?(json_response['messages'])).to be_falsey
end
end
 
Loading
Loading
@@ -1038,8 +1042,7 @@ describe API::Internal do
post api('/internal/post_receive'), params: valid_params
 
expect(response).to have_gitlab_http_status(200)
expect(json_response["redirected_message"]).to be_present
expect(json_response["redirected_message"]).to eq(project_moved.message)
expect(json_response['messages']).to include(build_basic_message(project_moved.message))
end
end
 
Loading
Loading
@@ -1051,8 +1054,7 @@ describe API::Internal do
post api('/internal/post_receive'), params: valid_params
 
expect(response).to have_gitlab_http_status(200)
expect(json_response["project_created_message"]).to be_present
expect(json_response["project_created_message"]).to eq(project_created.message)
expect(json_response['messages']).to include(build_basic_message(project_created.message))
end
end
 
Loading
Loading
@@ -1172,4 +1174,18 @@ describe API::Internal do
}
)
end
def build_alert_message(message)
{ 'type' => 'alert', 'message' => message }
end
def build_basic_message(message)
{ 'type' => 'basic', 'message' => message }
end
def has_alert_messages?(messages)
messages.any? do |message|
message['type'] == 'alert'
end
end
end
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment