Skip to content

Commit 08759be

Browse files
committed
Fall back to the global GitHub id when the URL lookup misses
A URL miss with an id hit is the same pull request after a repository rename or transfer; the upsert then writes the new URL back. GitLab gets no such fallback because its ids repeat per project.
1 parent ac68f81 commit 08759be

3 files changed

Lines changed: 38 additions & 2 deletions

File tree

modules/github_integration/app/models/github_pull_request.rb

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,11 @@ class GithubPullRequest < ApplicationRecord
6363
def self.find_by_github_identifiers(url:, id: nil, initialize: false)
6464
raise ArgumentError, "needs an url" if url.blank?
6565

66-
found = find_by(github_html_url: url)
66+
# The URL matches across every payload shape (comment payloads carry no
67+
# pull request id). The id fallback covers repository renames: GitHub ids
68+
# are globally unique, so a URL miss with an id hit is the same pull
69+
# request under a new URL, which the next upsert writes back.
70+
found = find_by(github_html_url: url) || (find_by(github_id: id) if id)
6771
found || (new(github_id: id, github_html_url: url) if initialize)
6872
end
6973

modules/github_integration/spec/lib/open_project/github_integration/services/upsert_pull_request_spec.rb

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,17 @@
126126
end
127127
end
128128

129+
context "when the repository was renamed and only the id still matches" do
130+
let!(:github_pull_request) do
131+
create(:github_pull_request, github_id:, github_html_url: "https://github.com/test_user/old_repo_name")
132+
end
133+
134+
it "updates the existing record and stores the new url instead of duplicating" do
135+
expect { upsert }.not_to change(GithubPullRequest, :count)
136+
expect(github_pull_request.reload.github_html_url).to eql github_html_url
137+
end
138+
end
139+
129140
context "when a partial github pull request with that html_url already exists" do
130141
let(:github_pull_request) do
131142
create(:github_pull_request,

modules/github_integration/spec/models/github_pull_request_spec.rb

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,13 +104,34 @@
104104
end
105105

106106
context "when the url does not match" do
107-
it "returns nothing even when the id matches" do
107+
it "falls back to the id so renamed repositories keep their records" do
108108
expect(described_class.find_by_github_identifiers(id: pull_request.github_id,
109109
url: "#{pull_request.github_html_url}zzzz"))
110+
.to eql pull_request
111+
end
112+
113+
it "returns nothing when the id does not match either" do
114+
expect(described_class.find_by_github_identifiers(id: pull_request.github_id + 1,
115+
url: "#{pull_request.github_html_url}zzzz"))
110116
.to be_nil
111117
end
112118
end
113119

120+
context "when the url matches one record and the id another" do
121+
let!(:other_pull_request) do
122+
create(:github_pull_request,
123+
github_id: github_id + 1,
124+
github_html_url: "#{github_url}4")
125+
end
126+
127+
before { pull_request }
128+
129+
it "prefers the url match" do
130+
expect(described_class.find_by_github_identifiers(id: other_pull_request.github_id, url: github_url))
131+
.to eql pull_request
132+
end
133+
end
134+
114135
context "when the url does not match but initialize is true" do
115136
subject(:finder) do
116137
described_class.find_by_github_identifiers(id: pull_request.github_id + 1,

0 commit comments

Comments
 (0)