diff --git a/db/migrate/20260608120000_add_unique_index_to_integration_html_urls.rb b/db/migrate/20260608120000_add_unique_index_to_integration_html_urls.rb index 139aa858377..0844d402bb3 100644 --- a/db/migrate/20260608120000_add_unique_index_to_integration_html_urls.rb +++ b/db/migrate/20260608120000_add_unique_index_to_integration_html_urls.rb @@ -1,10 +1,11 @@ # frozen_string_literal: true -# The webhook URL is the only globally unique identifier for a pull request, -# merge request or issue: per-project sequential numbers (GitLab's iid) repeat -# across repositories. Enforce that uniqueness at the database level so a -# missed lookup site or a concurrent webhook can never split one entity across -# two rows. Surviving duplicates are folded into the most recent row first; +# The webhook URL is the only globally unique identifier stored for a pull +# request, merge request or issue: GitLab records hold only the per-project +# iid, which repeats across repositories, and GitHub records created from +# comment payloads carry no github_id at all. Enforce the URL's uniqueness at +# the database level so a missed lookup site or a concurrent webhook can never +# split one entity across two rows. Surviving duplicates are folded into the most recent row first; # none are expected, since every write path already keys on the URL. class AddUniqueIndexToIntegrationHtmlUrls < ActiveRecord::Migration[8.1] disable_ddl_transaction! diff --git a/modules/gitlab_integration/app/models/gitlab_issue.rb b/modules/gitlab_integration/app/models/gitlab_issue.rb index d976aa3c222..1370a2abd8c 100644 --- a/modules/gitlab_integration/app/models/gitlab_issue.rb +++ b/modules/gitlab_integration/app/models/gitlab_issue.rb @@ -55,6 +55,8 @@ class GitlabIssue < ApplicationRecord def self.find_by_gitlab_identifiers(url:, id: nil, initialize: false) raise ArgumentError, "needs an url" if url.blank? + # gitlab_id holds GitLab's per-project iid, which repeats across + # repositories, so the URL is the only identifier safe to look up by. found = find_by(gitlab_html_url: url) found || (new(gitlab_id: id, gitlab_html_url: url) if initialize) end diff --git a/modules/gitlab_integration/app/models/gitlab_merge_request.rb b/modules/gitlab_integration/app/models/gitlab_merge_request.rb index 0755cbbc030..583289e09aa 100644 --- a/modules/gitlab_integration/app/models/gitlab_merge_request.rb +++ b/modules/gitlab_integration/app/models/gitlab_merge_request.rb @@ -58,6 +58,8 @@ class GitlabMergeRequest < ApplicationRecord def self.find_by_gitlab_identifiers(url:, id: nil, initialize: false) raise ArgumentError, "needs an url" if url.blank? + # gitlab_id holds GitLab's per-project iid, which repeats across + # repositories, so the URL is the only identifier safe to look up by. found = find_by(gitlab_html_url: url) found || (new(gitlab_id: id, gitlab_html_url: url) if initialize) end