Skip compliance violations for MRs auto-merged via another MR
What does this MR do and why?
When an MR's commits are already present in the target branch because a different MR was merged first, GitLab auto-transitions the first MR to merged state (see Merged as part of a different merge request).
The compliance violation pipeline was treating these auto-merged MRs the same as manually merged ones. Because the auto-merged MR has 0 approvals of its own, CreateComplianceViolationsService was creating false-positive "Fewer than two approvals" (and potentially "Committers approved merge request") violations. The violating user was also misattributed to whoever merged the other MR.
Root cause: CreateComplianceViolationsService called MergeRequests::ComplianceViolation.process_merge_request for every merged MR without checking how it became merged.
Fix: When an MR is auto-transitioned to merged via another MR, GitLab records a ResourceStateEvent with state: :merged and a non-nil source_merge_request_id. This MR adds a check in CreateComplianceViolationsService that skips violation processing for such MRs, since the code was reviewed and approved on the originating MR.
Changes:
- Added
ResourceStateEvent.merged_by_another_merge_requestscope to detect auto-merged state events - Added
merged_via_another_merge_request?guard inCreateComplianceViolationsService#execute - Added test coverage for the new behavior
Database
No schema changes. One new read query from CreateComplianceViolationsService#merged_via_another_merge_request?. It runs once for each merged MR the service processes, using the ResourceStateEvent.merged_by_another_merge_request scope.
SELECT 1 AS one FROM "resource_state_events"
WHERE "resource_state_events"."merge_request_id" = 537686105
AND "resource_state_events"."state" = 3
AND "resource_state_events"."source_merge_request_id" IS NOT NULL
LIMIT 1The existing index_resource_state_events_on_merge_request_id index serves both cases, so no new index is needed.
| Case | MR ID | Plan | Result |
|---|---|---|---|
| MR merged via another MR (match found) | 537686105 |
plan | Index Scan, 1 row, 1.5 ms |
| MR merged normally (no match, worst case) | 537644273 |
plan | Index Scan, 0 rows (51 filtered out), 1.1 ms |
References
Resolves #622226
Screenshots or screen recordings
N/A — backend-only change with no UI impact.
| Before | After |
|---|---|
| Auto-merged MRs generate false-positive compliance violations | Auto-merged MRs are skipped by the compliance violation pipeline |
How to set up and validate locally
- Create two MRs (A and B) where B's branch is a subset of A's commits
- Approve and merge MR A (with 2+ approvals)
- Observe MR B auto-transition to merged
- Check the compliance violations report — MR B should no longer appear as a violation
MR acceptance checklist
Evaluate this MR against the MR acceptance checklist. It helps you analyze changes to reduce risks in quality, performance, reliability, security, and maintainability.