Trigger auto-merge process after pipeline creation completes
What does this MR do and why?
When an MR is pushed with auto_merge=true (via push options) and
workflow:rules suppresses pipeline creation, the MR sits open until
someone visits its page. The page view publishes MergeableEvent which
the controller documents as the fallback for "auto merge was missed"
(app/controllers/projects/merge_requests_controller.rb:436-444).
Root cause
merge_statusstate-machineafter_transition any => :can_be_merged(app/models/merge_request.rb:304-311) enqueuesAutoMergeProcessWorkeras soon as git mergeability is clean — but this fires before async pipeline creation finishes.- The worker runs
MergeWhenChecksPassService#process→merge_request.mergeable?→CheckCiStatusService, which seespipeline_creating?is stilltrueand returnschecking→ worker bails. - When
workflow:rulesdrops the pipeline,Ci::CreatePipelineServicebuilds an unpersisted pipeline object and returns an error — noCi::Pipelinerow is created, so theCi::Pipeline.after_transitionhook atapp/models/ci/pipeline.rb:372that normally re-firesAutoMergeProcessWorkercannot run. - Nothing else re-triggers the worker until the user opens the page.
Fix
Hook the previously-empty MergeRequests::CreatePipelineWorker#after_perform
to re-enqueue AutoMergeProcessWorker when the MR has auto-merge enabled
and diff_head_pipeline is nil at the end of pipeline creation. By then,
pipeline_creating? is false and (in the no-pipeline-created case)
all_pipelines.any? is false, so has_ci_enabled? is false and the
CI mergeability check passes.
This is the worker-side counterpart to !228142 (merged) (which fixed the API path); together they cover the push-options and API surfaces.
| Case | Trigger |
|---|---|
| Pipeline created, reaches terminal state | Ci::Pipeline.after_transition (existing) |
| Pipeline never created (workflow:rules) | this MR |
| Pipeline created, still running | nothing yet — handled when it completes |
merge_request.diff_head_pipeline early-returns when a pipeline exists,
so there is no double-fire for the existing flow.
The EE override of after_perform now calls super to keep the
UnenforceablePolicyRulesNotificationWorker enqueue side-by-side with
the new auto-merge re-trigger.
Feature flag
Behind `trigger_auto_merge_after_pipeline_creation` (`gitlab_com_derisk`, default disabled).
Closes #600832
References
- https://gitlab.com/gitlab-com/request-for-help/-/work_items/3850
- Prior MRs in this series: !217382 (merged), !222317 (merged), !228142 (merged)
- Customer comment confirming the bug still reproduces: https://gitlab.com/gitlab-com/request-for-help/-/work_items/3850#note_3339062115
- Example MR exhibiting the bug: https://gitlab.com/gitlab-org/secure/vulnerability-research/advisories/nvd-mirror-json-data-v2/-/merge_requests/15781
How to set up and validate locally
- Enable the feature flag for your project: `Feature.enable(:trigger_auto_merge_after_pipeline_creation, project)`
- From inside a project that has at least one ref-scoped `workflow:rules` that drops pipelines on new branches, push a branch with: ```bash git push -o merge_request.create \ -o merge_request.target=main \ -o merge_request.auto_merge=true \ origin "test-branch" ```
- The MR should auto-merge once `CreatePipelineWorker` finishes, without requiring a page view.
MR acceptance checklist
- Tests added
- Feature flag added (`gitlab_com_derisk`, default off)
- Rollout issue created and linked in the feature flag YAML