Fix any_merge_request policy violations stuck in running on fork MRs

What does this MR do and why?

  • Fixes Security::ScanResultPolicyViolation rows for any_merge_request approval policy rules getting stuck at status: running forever on fork MRs, especially personal-namespace forks.
  • While stuck running, CheckSecurityPolicyViolationsService reports checking, so detailed_merge_status is security_policy_violations and the merge widget spins with no automatic recovery.
  • Since 18.4 removed the policy_mergability_check flag, this status is a hard merge gate, so a lost sync now permanently blocks the MR.
  • Close/reopen currently works around it (ReopenService re-creates rules and re-schedules the sync), but that's manual.
  • Reported via customer escalation: request-for-help work item 5212 and two Zendesk tickets, recurring across versions.

Three root causes, one commit each (review order: 2, 3, 1):

# Where Bug Fix
1 EE::MergeRequests::CreateService#after_create Violations created after super already enqueued NewMergeRequestWorker, the only thing that resolves them at creation time Create violations before super
2 MergeRequests::Refresh::ApprovalService#sync_any_merge_request_approval_rules Worker enqueue gated on the pushed-to project (the fork, no policies/license), while still re-creating running violations from the target project's rules on every push Gate per MR on merge_request.project (target project), memoized per project id, matching SyncMergeRequestsService
3 UnenforceablePolicyRulesPipelineNotificationWorker / UnblockPendingMergeRequestViolationsWorker Gated on pipeline.project; fork pipelines run in the fork, so the 90s unblock safety net never fired for fork MRs Gate per related MR on its target project

Fourth commit is perf-only, no behavior change:

  • restores a cheap short-circuit in the notification worker for non-fork, non-MR pipelines (they can only match MRs targeting their own project)
  • preloads the target project in opened_merge_requests_with_head_sha instead of in the workers
  • memoizes the unblock worker's availability check
  • renames a shadowing project param to target_project in ApprovalService

Notes:

  • Defect 2 side effect: MRs whose target project has no commit-targeting policies are no longer enqueued. Safe, since SyncAnyMergeRequestRulesService already early-returns.

  • Defect 3 is roughly query-neutral: loads related MRs before gating, drops a project-level approval_rules existence query.

  • UnenforceablePolicyRulesNotificationWorker call sites are unchanged; it already gates per MR.

  • No data migration for already-stuck MRs. A push or a close/reopen unsticks one; so does merge_request.synchronize_approval_rules_from_target_project + schedule_policy_synchronization in a console.

  • No feature flag: small, strictly corrective fix. A flag on the create-path ordering change would be untestable in the field.

References

Screenshots or screen recordings

Before After
N/A N/A

How to set up and validate locally

  1. GDK with an Ultimate license. Create a group with a security policy project.
  2. Add an approval policy rule: type: any_merge_request, commits: any, an approval action, fallback_behavior: fail: closed.
  3. Create a project in that group with a protected default branch and no .gitlab-ci.yml.
  4. As a second user, fork the project into their personal namespace and push a branch.
  5. Open an MR from the fork branch into the upstream project.
  6. Before this fix: the violation stays running, is re-created running on every push, and the widget spins on "Checking if merge request can be merged."
  7. After this fix: the violation moves to failed (until approved) or is deleted, and the widget resolves. Pushing again re-evaluates the violation correctly.
  8. Relevant specs: ee/spec/services/ee/merge_requests/create_service_spec.rb, ee/spec/services/merge_requests/refresh/approval_service_spec.rb, ee/spec/workers/security/unenforceable_policy_rules_pipeline_notification_worker_spec.rb, ee/spec/workers/security/scan_result_policies/unblock_pending_merge_request_violations_worker_spec.rb.

MR acceptance checklist

Evaluate this MR against the MR acceptance checklist.

Edited by Alexander Turinske

Merge request reports

Loading
Loading