Add user_initiated flag to MR pipeline creation requests
What does this MR do and why?
MR pipeline creation requests, the short-lived Redis entries behind the MR Pipelines tab's real-time creation states, don't record who started them. The tab alerts whenever the FAILED count grows, so "Pipeline creation failed. Please try again." shows up even when the failed attempt was started automatically on MR creation. In a project whose CI config produces no merge request pipelines, every MR greets its author with that alert. Based on the discussion in this thread, we decided that a failed automatic background attempt isn't a user error, and no message should show for it.
This MR is the backend half of the fix discussed in that thread.
Ci::PipelineCreation::Requests.start_for_merge_request now takes user_initiated: and hset writes id and user_initiated into the JSON value stored in Redis. The request hash already rides through Sidekiq args back into Requests.failed/succeeded, so both fields survive to completion with no extra reads. Requests have exactly one writer, CreatePipelineService#execute_async, with five callers:
execute_async caller |
Origin | user_initiated |
|---|---|---|
| async REST run-pipeline endpoint, what the tab's "Run pipeline" button calls | user | true |
/run_pipeline quick action |
user | true |
| MR creation | automatic | false |
| push to the source branch | automatic | false |
| retarget after the target branch merges | automatic | false |
GraphQL's CiPipelineCreationRequest exposes both new fields: userInitiated for the follow-up frontend MR to gate the alert on, and a nullable id so that we can persist per creation request dismissals for Dismissed pipeline creation failure alerts shou... (#612803 - closed).
How to set up and validate locally
-
Trigger the automatic path from the rails console and read the stored request back.
user_initiatedisfalse:mr = MergeRequest.find(<id>) MergeRequests::CreatePipelineService .new(project: mr.project, current_user: mr.author, params: { allow_duplicate: true }) .execute_async(mr) Ci::PipelineCreation::Requests.for_merge_request(mr) # => [{"status"=>"in_progress", "id"=>"<uuid>", "user_initiated"=>false}] -
Trigger a user path: select "Run pipeline" on the MR's Pipelines tab, comment
/run_pipelineon the MR, orPOST /api/v4/projects/:id/merge_requests/:iid/pipelines?async=true. Reading the requests back now shows the new entry with"user_initiated"=>true. -
Within 5 minutes (the Redis TTL), query the new fields in
/-/graphql-explorer:{ project(fullPath: "<full-path>") { mergeRequest(iid: "<iid>") { pipelineCreationRequests { id status userInitiated } } } } -
Requests created before this branch (or with the JSON fields stripped from Redis by hand) return
"id" => niland"userInitiated" => true.
References
- Related to Differentiate between automatic and user-initia... (#612802 - closed) (covers this MR plus the frontend alert gating, which comes as a follow-up MR once this deploys)
- Dismissed pipeline creation failure alerts shou... (#612803 - closed)
- Parent issue: MR pipelines tab has error "Pipeline creation f... (#605631 - closed)