Resolve dismissal MRs by source branch for merged-results pipelines
Problem
Issue #560563 (closed) (Scenario 1, "Gate 3"): when all vulnerabilities are dismissed, the merge request approval policy can stay blocked until the pipeline is re-run, specifically for merge requests using merge trains or merged results pipelines.
This is a separate, follow-up fix to !240608 (closed). !240608 (closed) addresses the dismissal-unblock evaluation paths (UUID-cascade and the UpdateApprovalsService artifact-expiry early-return). This MR fixes the trigger / MR-resolution gap that those changes do not cover.
Root cause
A dismissal triggers SyncFindingsToApprovalRulesService with the scan (branch) pipeline. update_required_approvals_for_scan_finding resolves affected MRs via pipeline.opened_merge_requests_with_head_sha, which matches MRs whose latest diff head_commit_sha is in the pipeline's [sha, source_sha].
When the MR's current head pipeline is a merged results / merge train pipeline, its SHA differs from the dismissal's branch scan pipeline SHA, so the head-sha match does not return the MR. UpdateApprovalsService is therefore never invoked for that MR, the policy is not re-evaluated, and the MR stays blocked. A manual pipeline re-run sidesteps this by creating a head pipeline whose SHA matches.
Change
SyncFindingsToApprovalRulesService now additionally resolves opened merge requests by source branch (for branch pipelines only) and evaluates each against its own current head pipeline (diff_head_pipeline), deduplicated against the MRs already handled by the head-sha match.
- Guarded with
pipeline.merge_request?only (merge request pipelines already resolve to their single MR via the head-sha match). - Intentionally not guarded with
pipeline.latest?: for merge trains / merged results, the scan pipeline's SHA is the internal merge ref commit rather than the source branch tip, solatest?returnsfalsefor exactly the pipelines this branch needs to catch. Using it would make the fix a no-op. Resolution stays safe because each MR is synced via its owndiff_head_pipeline(not this scan pipeline) andSyncMergeRequestApprovalsWorkeris deduplicated. - Reuses the existing
diff_head_pipeline+start_merge_request_worker_policy_syncpattern, so policy sync-state tracking stays correct.
Testing
- New spec: a branch pipeline whose SHA is not the MR diff head SHA resolves the MR by source branch and syncs via its head pipeline.
- New spec: a merge request pipeline does not double-resolve by source branch.
- Updated the existing
'when pipeline is not for diff_head_sha'example to reflect the new behavior. - New specs use isolated projects so they cannot pollute the shared
let_it_berecords used by other examples.
Notes for reviewers
- Performance: this adds one
by_source_branchquery per branch-pipeline completion and may enqueueSyncMergeRequestApprovalsWorkerfor additional same-source-branch MRs. The worker is deduplicated, and resolution is project-scoped + branch-scoped. Please confirm this is acceptable on busy projects. - Forks: like the existing target-branch resolution,
project.merge_requests.by_source_branchresolves MRs in the project; cross-fork source branches are out of scope here (same limitation as the pre-existing code).
Related
- Follow-up to !240608 (closed)
- Related to #560563 (closed)