MRs with squashing and fast-forward merge are not properly linked to deployments.
Summary
When the project uses fast-forward merges AND squashing in MRs no proper link between MR and deployment is created.
Steps to reproduce
- Prepare project in rails console:
project = Project.find_by_full_path('gitlab-org/gitlab-test')
current_user = User.first
prod = project.environments.production.first
project.protected_branches.destroy_all # allow to merge to master for everyone.
project.update(merge_method: :ff) # change merge method to fast-forward
Deployments::CreateService.new(prod, current_user, {sha: project.repository.commits('master', limit: 1).first.sha, status: 'success', ref: 'master', tag: false}).execute # create new deployment for all old commits.
- Create 3 MRs to master:
- single commit MR with squashing
- multiple commits MR with squashing
- single commit MR without squashing
- Merge them all 1 by 1. You should see something like this in repository commit history:
- In Rails console create new deployment:
Deployments::CreateService.new(prod, current_user, {sha: project.repository.commits('master', limit: 1).first.sha, status: 'success', ref: 'master', tag: false}).execute # create new deployment for all old commits.
- Check linked MRs by visiting
/api/v4/projects/2/deployments/_LAST_DEPLOYMENT_ID_HERE_/merge_requests
. You will see only "single commit MR without squashing".
Technical details
See #384104 (comment 1898097706)
Proposal
We link fast-forward MRs to deployments by the merge_request_diffs.head_commit_sha
. In order to include MRs that are squashed, we also need to link MRs to deployments by squashed_commit_sha
.
There are 2 ways fix this depending on whether this bug also affects non-fast forward MRs.
If non-fast-forward MRs are affected:
In this code block:
commits.each_slice(COMMITS_PER_QUERY) do |slice|
link_merge_requests_by_merge_commits(slice)
link_fast_forward_merge_requests(slice)
+ link_merge_requests_by_squashed_commits(slice) # this method needs to be written
# rest of code here
end
If only fast-forward MRs are affected:
In this code block
def link_fast_forward_merge_requests(commits)
+ deployment.link_merge_requests(merge_requests_by_squashed_commit_sha(commits)) # you will need to write the `merge_requests_by_squashed_commit_sha` method
deployment.link_merge_requests(merge_requests_by_head_commit_sha(commits))
end
Note: the above diffs are only an illustration of what the changes can look like. Please feel free to implement the actual fix how you see fit. You will also need to check that the new query performs well.
Edited by Pam Artiaga