diff options
author | Bob Van Landuyt <bob@vanlanduyt.co> | 2018-10-24 19:01:44 +0300 |
---|---|---|
committer | Bob Van Landuyt <bob@vanlanduyt.co> | 2018-11-07 18:27:55 +0300 |
commit | 6fbdc5ed5224154b89cf351e11a8f9db48e6d7f0 (patch) | |
tree | dd2ccecd4b1100d4b83f91292b96ec988eecde6d /app | |
parent | 6d8810a64f944ff96af54e5c759f866bb68a7453 (diff) |
Apply patches when creating MR via email
This allows users to add patches as attachments to merge request
created via email.
When an email to create a merge request is sent, all the attachments
ending in `.patch` will be applied to the branch specified in the
subject of the email. If the branch did not exist, it will be created
from the HEAD of the repository.
When the patches could not be applied, the error message will be
replied to the user.
The patches can have a maximum combined size of 2MB for now.
Diffstat (limited to 'app')
-rw-r--r-- | app/services/commits/commit_patch_service.rb | 61 | ||||
-rw-r--r-- | app/services/commits/create_service.rb | 7 | ||||
-rw-r--r-- | app/services/merge_requests/build_service.rb | 4 | ||||
-rw-r--r-- | app/workers/email_receiver_worker.rb | 2 |
4 files changed, 72 insertions, 2 deletions
diff --git a/app/services/commits/commit_patch_service.rb b/app/services/commits/commit_patch_service.rb new file mode 100644 index 00000000000..9253cfaac20 --- /dev/null +++ b/app/services/commits/commit_patch_service.rb @@ -0,0 +1,61 @@ +# frozen_string_literal: true + +module Commits + class CommitPatchService < CreateService + # Requires: + # - project: `Project` to be committed into + # - user: `User` that will be the committer + # - params: + # - branch_name: `String` the branch that will be committed into + # - start_branch: `String` the branch that will will started from + # - patches: `Gitlab::Git::Patches::Collection` that contains the patches + def initialize(*args) + super + + @patches = Gitlab::Git::Patches::Collection.new(Array(params[:patches])) + end + + private + + def new_branch? + !repository.branch_exists?(@branch_name) + end + + def create_commit! + if @start_branch && new_branch? + prepare_branch! + end + + Gitlab::Git::Patches::CommitPatches + .new(current_user, project.repository, @branch_name, @patches) + .commit + end + + def prepare_branch! + branch_result = CreateBranchService.new(project, current_user) + .execute(@branch_name, @start_branch) + + if branch_result[:status] != :success + raise ChangeError, branch_result[:message] + end + end + + # Overridden from the Commits::CreateService, to skip some validations we + # don't need: + # - validate_on_branch! + # Not needed, the patches are applied on top of HEAD if the branch did not + # exist + # - validate_branch_existence! + # Not needed because we continue applying patches on the branch if it + # already existed, and create it if it did not exist. + def validate! + validate_patches! + validate_new_branch_name! if new_branch? + validate_permissions! + end + + def validate_patches! + raise_error("Patches are too big") unless @patches.valid_size? + end + end +end diff --git a/app/services/commits/create_service.rb b/app/services/commits/create_service.rb index 3ce9acc833c..34593e12bd5 100644 --- a/app/services/commits/create_service.rb +++ b/app/services/commits/create_service.rb @@ -19,7 +19,12 @@ module Commits new_commit = create_commit! success(result: new_commit) - rescue ValidationError, ChangeError, Gitlab::Git::Index::IndexError, Gitlab::Git::CommitError, Gitlab::Git::PreReceiveError => ex + rescue ValidationError, + ChangeError, + Gitlab::Git::Index::IndexError, + Gitlab::Git::CommitError, + Gitlab::Git::PreReceiveError, + Gitlab::Git::CommandError => ex error(ex.message) end diff --git a/app/services/merge_requests/build_service.rb b/app/services/merge_requests/build_service.rb index 0e76d2cc3ab..6c9e566109a 100644 --- a/app/services/merge_requests/build_service.rb +++ b/app/services/merge_requests/build_service.rb @@ -6,8 +6,10 @@ module MergeRequests def execute @params_issue_iid = params.delete(:issue_iid) + self.merge_request = MergeRequest.new + merge_quick_actions_into_params!(merge_request) + merge_request.assign_attributes(params) - self.merge_request = MergeRequest.new(params) merge_request.author = current_user merge_request.compare_commits = [] merge_request.source_project = find_source_project diff --git a/app/workers/email_receiver_worker.rb b/app/workers/email_receiver_worker.rb index 12706613ac2..bf637f82df2 100644 --- a/app/workers/email_receiver_worker.rb +++ b/app/workers/email_receiver_worker.rb @@ -40,6 +40,8 @@ class EmailReceiverWorker "You are not allowed to perform this action. If you believe this is in error, contact a staff member." when Gitlab::Email::NoteableNotFoundError "The thread you are replying to no longer exists, perhaps it was deleted? If you believe this is in error, contact a staff member." + when Gitlab::Email::InvalidAttachment + error.message when Gitlab::Email::InvalidRecordError can_retry = true error.message |