-
Notifications
You must be signed in to change notification settings - Fork 136
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Optimistic batching for batch merging #252
Open
deibido
wants to merge
9
commits into
smarkets:master
Choose a base branch
from
deibido:master
base: master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
9 commits
Select commit
Hold shift + click to select a range
71f9754
Optimistic batching for batch merging
4598b2c
Revert "Optimistic batching for batch merging"
fe20e15
Add separate flag for optimistic batching
07dfe3a
Add logic to update individual MRs with previous MR changes
05f562e
Merge remote-tracking branch 'upstream/master'
f34d399
Fixed the batch MR merging logic for optimistic batching
89f6bf0
Tidy up code and make sure not to add trailers twice
4e8f99e
Added docs for the flag
cd0e198
Made sure batch MR + branch is always generated
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -16,8 +16,9 @@ class CannotBatch(Exception): | |
class BatchMergeJob(MergeJob): | ||
BATCH_BRANCH_NAME = 'marge_bot_batch_merge_job' | ||
|
||
def __init__(self, *, api, user, project, repo, options, merge_requests): | ||
def __init__(self, *, api, user, project, repo, options, optimistic=False, merge_requests): | ||
super().__init__(api=api, user=user, project=project, repo=repo, options=options) | ||
self._optimistic = optimistic | ||
self._merge_requests = merge_requests | ||
|
||
def remove_batch_branch(self): | ||
|
@@ -135,20 +136,22 @@ def accept_mr( | |
if new_target_sha != expected_remote_target_branch_sha: | ||
raise CannotBatch('Someone was naughty and by-passed marge') | ||
|
||
# FIXME: we should only add tested-by for the last MR in the batch | ||
_, _, actual_sha = self.update_from_target_branch_and_push( | ||
merge_request, | ||
source_repo_url=source_repo_url, | ||
) | ||
if not self._optimistic: | ||
# When optimistic batching is enabled we've already applied the trailers | ||
# FIXME: we should only add tested-by for the last MR in the batch | ||
_, _, actual_sha = self.update_from_target_branch_and_push( | ||
merge_request, | ||
source_repo_url=source_repo_url, | ||
) | ||
|
||
sha_now = Commit.last_on_branch( | ||
merge_request.source_project_id, merge_request.source_branch, self._api, | ||
).id | ||
# Make sure no-one managed to race and push to the branch in the | ||
# meantime, because we're about to impersonate the approvers, and | ||
# we don't want to approve unreviewed commits | ||
if sha_now != actual_sha: | ||
raise CannotMerge('Someone pushed to branch while we were trying to merge') | ||
sha_now = Commit.last_on_branch( | ||
merge_request.source_project_id, merge_request.source_branch, self._api, | ||
).id | ||
# Make sure no-one managed to race and push to the branch in the | ||
# meantime, because we're about to impersonate the approvers, and | ||
# we don't want to approve unreviewed commits | ||
if sha_now != actual_sha: | ||
raise CannotMerge('Someone pushed to branch while we were trying to merge') | ||
|
||
# As we're not using the API to merge the MR, we don't strictly need to reapprove it. However, | ||
# it's a little weird to look at the merged MR to find it has no approvals, so let's do it anyway. | ||
|
@@ -213,6 +216,14 @@ def execute(self): | |
'%s/%s' % (merge_request_remote, merge_request.source_branch), | ||
) | ||
|
||
if self._optimistic: | ||
#TODO REBASE ON THE SAME VERSION OF MASTER AS THE | ||
# BATCH MR WAS CREATED FROM HERE!!! | ||
|
||
# Apply the trailers before running the batch MR | ||
self.add_trailers(merge_request) | ||
self.push_force_to_mr(merge_request, True, source_repo_url, skip_ci=True) | ||
|
||
# Update <source_branch> on latest <batch> branch so it contains previous MRs | ||
self.fuse( | ||
merge_request.source_branch, | ||
|
@@ -239,12 +250,12 @@ def execute(self): | |
working_merge_requests.append(merge_request) | ||
if len(working_merge_requests) <= 1: | ||
raise CannotBatch('not enough ready merge requests') | ||
# This switches git to <batch> branch | ||
self.push_batch() | ||
batch_mr = self.create_batch_mr( | ||
target_branch=target_branch, | ||
) | ||
if self._project.only_allow_merge_if_pipeline_succeeds: | ||
# This switches git to <batch> branch | ||
self.push_batch() | ||
batch_mr = self.create_batch_mr( | ||
target_branch=target_branch, | ||
) | ||
for merge_request in working_merge_requests: | ||
merge_request.comment('I will attempt to batch this MR (!{})...'.format(batch_mr.iid)) | ||
try: | ||
|
@@ -258,19 +269,56 @@ def execute(self): | |
), | ||
) | ||
raise CannotBatch(err.reason) from err | ||
for merge_request in working_merge_requests: | ||
for index, merge_req in enumerate(working_merge_requests): | ||
try: | ||
# FIXME: this should probably be part of the merge request | ||
_, source_repo_url, merge_request_remote = self.fetch_source_project(merge_request) | ||
self.ensure_mr_not_changed(merge_request) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why has this check been lost? |
||
self.ensure_mergeable_mr(merge_request) | ||
remote_target_branch_sha = self.accept_mr( | ||
merge_request, | ||
remote_target_branch_sha, | ||
source_repo_url=source_repo_url, | ||
) | ||
_, source_repo_url, merge_request_remote = self.fetch_source_project(merge_req) | ||
self.ensure_mr_not_changed(merge_req) | ||
self.ensure_mergeable_mr(merge_req) | ||
if self._optimistic: | ||
if index == 0: | ||
continue | ||
elif index == len(working_merge_requests) - 1: | ||
# Update <source_branch> so it contains previous merge_reqs | ||
self.fuse( | ||
merge_req.source_branch, | ||
working_merge_requests[index - 1], | ||
source_repo_url=source_repo_url, | ||
local=True, | ||
) | ||
self.push_force_to_mr( | ||
merge_req, | ||
True, | ||
source_repo_url, | ||
skip_ci=True, | ||
) | ||
remote_target_branch_sha = self.accept_mr( | ||
batch_mr, | ||
remote_target_branch_sha, | ||
source_repo_url=source_repo_url, | ||
) | ||
else: | ||
# Update <source_branch> so it contains previous merge_reqs | ||
self.fuse( | ||
merge_req.source_branch, | ||
working_merge_requests[index - 1], | ||
source_repo_url=source_repo_url, | ||
local=True, | ||
) | ||
self.push_force_to_mr( | ||
merge_req, | ||
True, | ||
source_repo_url, | ||
skip_ci=True, | ||
) | ||
else: | ||
remote_target_branch_sha = self.accept_mr( | ||
merge_req, | ||
remote_target_branch_sha, | ||
source_repo_url=source_repo_url, | ||
) | ||
except CannotBatch as err: | ||
merge_request.comment( | ||
merge_req.comment( | ||
"I couldn't merge this branch: {error} I will retry later...".format( | ||
error=str(err), | ||
), | ||
|
@@ -280,6 +328,6 @@ def execute(self): | |
# Raise here to avoid being caught below - we don't want to be unassigned. | ||
raise | ||
except CannotMerge as err: | ||
self.unassign_from_mr(merge_request) | ||
merge_request.comment("I couldn't merge this branch: %s" % err.reason) | ||
self.unassign_from_mr(merge_req) | ||
merge_req.comment("I couldn't merge this branch: %s" % err.reason) | ||
raise |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We seem to have lost this check. Whilst batching is a bit weird if you don't have pipelines enabled, we'd still want to support simply merging the batch branch in without waiting for any pipelines (which won't exist now) to finish.