Commit baf6fa74 authored by Yorick Peterse's avatar Yorick Peterse

Link squashed commits using the changelog API

When generating changelogs using the API, we now link to merge requests
for squashed commits. Prior to this commit, when a merge request was
squashed into a target branch, we weren't able to link back to that
merge request in a generated changelog.

See https://gitlab.com/gitlab-com/gl-infra/delivery/-/issues/1551 for
more information.
parent e4cd9e2b
......@@ -18,8 +18,8 @@ module MergeRequests
mapping = {}
shas = commits.map(&:id)
# To include merge requests by the commit SHA, we don't need to go through
# any diff rows.
# To include merge requests by the merge/squash SHA, we don't need to go
# through any diff rows.
#
# We can't squeeze all this into a single query, as the diff based data
# relies on a GROUP BY. On the other hand, retrieving MRs by their merge
......@@ -27,12 +27,17 @@ module MergeRequests
@project
.merge_requests
.preload_target_project
.by_merge_commit_sha(shas)
.by_merge_or_squash_commit_sha(shas)
.each do |mr|
# Merge SHAs can't be in the merge request itself. It _is_ possible a
# newer merge request includes the merge commit, but in that case we
# still want the oldest merge request.
mapping[mr.merge_commit_sha] = mr
# Merge/squash SHAs can't be in the merge request itself. It _is_
# possible a newer merge request includes the commit, but in that case
# we still want the oldest merge request.
#
# It's also possible that a merge request produces both a squashed
# commit and a merge commit. In that case we want to store the mapping
# for both the SHAs.
mapping[mr.squash_commit_sha] = mr if mr.squash_commit_sha
mapping[mr.merge_commit_sha] = mr if mr.merge_commit_sha
end
remaining = shas - mapping.keys
......
......@@ -276,6 +276,9 @@ class MergeRequest < ApplicationRecord
scope :by_squash_commit_sha, -> (sha) do
where(squash_commit_sha: sha)
end
scope :by_merge_or_squash_commit_sha, -> (sha) do
from_union([by_squash_commit_sha(sha), by_merge_commit_sha(sha)])
end
scope :by_related_commit_sha, -> (sha) do
from_union(
[
......
---
title: Link squashed commits using the changelog API
merge_request: 56985
author:
type: added
......@@ -77,6 +77,45 @@ RSpec.describe MergeRequests::OldestPerCommitFinder do
expect(described_class.new(project).execute(commits)).to eq(sha => mr)
end
it 'includes a merge request that was squashed into the target branch' do
project = create(:project)
sha = Digest::SHA1.hexdigest('foo')
mr = create(
:merge_request,
:merged,
target_project: project,
squash_commit_sha: sha
)
commits = [double(:commit, id: sha)]
expect(MergeRequestDiffCommit)
.not_to receive(:oldest_merge_request_id_per_commit)
expect(described_class.new(project).execute(commits)).to eq(sha => mr)
end
it 'includes a merge request for both a squash and merge commit' do
project = create(:project)
sha1 = Digest::SHA1.hexdigest('foo')
sha2 = Digest::SHA1.hexdigest('bar')
mr = create(
:merge_request,
:merged,
target_project: project,
squash_commit_sha: sha1,
merge_commit_sha: sha2
)
commits = [double(:commit1, id: sha1), double(:commit2, id: sha2)]
expect(MergeRequestDiffCommit)
.not_to receive(:oldest_merge_request_id_per_commit)
expect(described_class.new(project).execute(commits))
.to eq(sha1 => mr, sha2 => mr)
end
it 'includes the oldest merge request when a merge commit is present in a newer merge request' do
project = create(:project)
sha = Digest::SHA1.hexdigest('foo')
......
......@@ -420,6 +420,19 @@ RSpec.describe MergeRequest, factory_default: :keep do
end
end
describe '.by_merge_or_squash_commit_sha' do
subject { described_class.by_merge_or_squash_commit_sha([sha1, sha2]) }
let(:sha1) { '123abc' }
let(:sha2) { '456abc' }
let(:mr1) { create(:merge_request, :merged, squash_commit_sha: sha1) }
let(:mr2) { create(:merge_request, :merged, merge_commit_sha: sha2) }
it 'returns merge requests that match the given squash and merge commits' do
is_expected.to include(mr1, mr2)
end
end
describe '.by_related_commit_sha' do
subject { described_class.by_related_commit_sha(sha) }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment