From 0b99dc23f36a052f72ce4194362760656abf8321 Mon Sep 17 00:00:00 2001 From: Sahil Sharma Date: Tue, 9 Sep 2025 18:37:34 +0100 Subject: [PATCH 1/9] Make Run Pipeline button in Merge Request view dynamic --- .../javascripts/ci/pipeline_details/mixins/pipelines_mixin.js | 4 ++-- .../javascripts/ci/pipeline_details/stores/pipelines_store.js | 4 +++- .../commit/pipelines/legacy_pipelines_table_wrapper.vue | 2 +- app/controllers/projects/merge_requests_controller.rb | 1 + 4 files changed, 7 insertions(+), 4 deletions(-) diff --git a/app/assets/javascripts/ci/pipeline_details/mixins/pipelines_mixin.js b/app/assets/javascripts/ci/pipeline_details/mixins/pipelines_mixin.js index 074e5b49759000..837e52ce227e13 100644 --- a/app/assets/javascripts/ci/pipeline_details/mixins/pipelines_mixin.js +++ b/app/assets/javascripts/ci/pipeline_details/mixins/pipelines_mixin.js @@ -144,8 +144,8 @@ export default { .then((response) => this.successCallback(response)) .catch((error) => this.errorCallback(error)); }, - setCommonData(pipelines, isUsingAsyncPipelineCreation = false) { - this.store.storePipelines(pipelines, isUsingAsyncPipelineCreation); + setCommonData(pipelines, isUsingAsyncPipelineCreation = false, pipelineCreationInProgress = false) { + this.store.storePipelines(pipelines, isUsingAsyncPipelineCreation, pipelineCreationInProgress); this.isLoading = false; this.updateGraphDropdown = true; this.hasMadeRequest = true; diff --git a/app/assets/javascripts/ci/pipeline_details/stores/pipelines_store.js b/app/assets/javascripts/ci/pipeline_details/stores/pipelines_store.js index 96c6448858e395..daf730faacff95 100644 --- a/app/assets/javascripts/ci/pipeline_details/stores/pipelines_store.js +++ b/app/assets/javascripts/ci/pipeline_details/stores/pipelines_store.js @@ -12,7 +12,7 @@ export default class PipelinesStore { this.state.isRunningMergeRequestPipeline = false; } - storePipelines(pipelines = [], isUsingAsyncPipelineCreation) { + storePipelines(pipelines = [], isUsingAsyncPipelineCreation, pipelineCreationInProgress = false) { if (isUsingAsyncPipelineCreation && pipelines.length) { const firstPipelineFromTable = this.state.pipelines[0]; const firstPipelineFromRequest = pipelines[0]; @@ -20,6 +20,8 @@ export default class PipelinesStore { if (firstPipelineFromTable?.created_at !== firstPipelineFromRequest?.created_at) { this.toggleIsRunningPipeline(false); } + + this.toggleIsRunningPipeline(pipelineCreationInProgress); } this.state.pipelines = pipelines; diff --git a/app/assets/javascripts/commit/pipelines/legacy_pipelines_table_wrapper.vue b/app/assets/javascripts/commit/pipelines/legacy_pipelines_table_wrapper.vue index a975a83c300a66..50de9ba9999216 100644 --- a/app/assets/javascripts/commit/pipelines/legacy_pipelines_table_wrapper.vue +++ b/app/assets/javascripts/commit/pipelines/legacy_pipelines_table_wrapper.vue @@ -147,7 +147,7 @@ export default { const pipelines = resp.data.pipelines || resp.data; this.store.storePagination(resp.headers); - this.setCommonData(pipelines, this.isMergeRequestTable); + this.setCommonData(pipelines, this.isMergeRequestTable, resp.data.pipeline_creation_in_progress); if (resp.headers?.['x-total']) { const updatePipelinesEvent = new CustomEvent('update-pipelines-count', { diff --git a/app/controllers/projects/merge_requests_controller.rb b/app/controllers/projects/merge_requests_controller.rb index 197e2b4d326f0f..114f521e912b01 100644 --- a/app/controllers/projects/merge_requests_controller.rb +++ b/app/controllers/projects/merge_requests_controller.rb @@ -176,6 +176,7 @@ def pipelines preload_downstream_statuses: false, disable_stage_actions: true ), + pipeline_creation_in_progress: merge_request.pipeline_creating?, count: { all: @pipelines_count } -- GitLab From f14c15a8350aee659fb133ad94f6a1e17cb1c7ab Mon Sep 17 00:00:00 2001 From: Sahil Sharma Date: Tue, 9 Sep 2025 18:42:05 +0100 Subject: [PATCH 2/9] Prettier fixes --- .../ci/pipeline_details/mixins/pipelines_mixin.js | 12 ++++++++++-- .../pipelines/legacy_pipelines_table_wrapper.vue | 6 +++++- 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/app/assets/javascripts/ci/pipeline_details/mixins/pipelines_mixin.js b/app/assets/javascripts/ci/pipeline_details/mixins/pipelines_mixin.js index 837e52ce227e13..7d867c3fafdf9d 100644 --- a/app/assets/javascripts/ci/pipeline_details/mixins/pipelines_mixin.js +++ b/app/assets/javascripts/ci/pipeline_details/mixins/pipelines_mixin.js @@ -144,8 +144,16 @@ export default { .then((response) => this.successCallback(response)) .catch((error) => this.errorCallback(error)); }, - setCommonData(pipelines, isUsingAsyncPipelineCreation = false, pipelineCreationInProgress = false) { - this.store.storePipelines(pipelines, isUsingAsyncPipelineCreation, pipelineCreationInProgress); + setCommonData( + pipelines, + isUsingAsyncPipelineCreation = false, + pipelineCreationInProgress = false, + ) { + this.store.storePipelines( + pipelines, + isUsingAsyncPipelineCreation, + pipelineCreationInProgress, + ); this.isLoading = false; this.updateGraphDropdown = true; this.hasMadeRequest = true; diff --git a/app/assets/javascripts/commit/pipelines/legacy_pipelines_table_wrapper.vue b/app/assets/javascripts/commit/pipelines/legacy_pipelines_table_wrapper.vue index 50de9ba9999216..21604e5a9b5750 100644 --- a/app/assets/javascripts/commit/pipelines/legacy_pipelines_table_wrapper.vue +++ b/app/assets/javascripts/commit/pipelines/legacy_pipelines_table_wrapper.vue @@ -147,7 +147,11 @@ export default { const pipelines = resp.data.pipelines || resp.data; this.store.storePagination(resp.headers); - this.setCommonData(pipelines, this.isMergeRequestTable, resp.data.pipeline_creation_in_progress); + this.setCommonData( + pipelines, + this.isMergeRequestTable, + resp.data.pipeline_creation_in_progress, + ); if (resp.headers?.['x-total']) { const updatePipelinesEvent = new CustomEvent('update-pipelines-count', { -- GitLab From b28ea7522566310fe290a705f4b3754833b7345f Mon Sep 17 00:00:00 2001 From: Sahil Sharma Date: Tue, 9 Sep 2025 18:57:49 +0100 Subject: [PATCH 3/9] Remove redundant toggle code --- .../ci/pipeline_details/stores/pipelines_store.js | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/app/assets/javascripts/ci/pipeline_details/stores/pipelines_store.js b/app/assets/javascripts/ci/pipeline_details/stores/pipelines_store.js index daf730faacff95..5de3fae9f4a0b5 100644 --- a/app/assets/javascripts/ci/pipeline_details/stores/pipelines_store.js +++ b/app/assets/javascripts/ci/pipeline_details/stores/pipelines_store.js @@ -13,14 +13,7 @@ export default class PipelinesStore { } storePipelines(pipelines = [], isUsingAsyncPipelineCreation, pipelineCreationInProgress = false) { - if (isUsingAsyncPipelineCreation && pipelines.length) { - const firstPipelineFromTable = this.state.pipelines[0]; - const firstPipelineFromRequest = pipelines[0]; - - if (firstPipelineFromTable?.created_at !== firstPipelineFromRequest?.created_at) { - this.toggleIsRunningPipeline(false); - } - + if (isUsingAsyncPipelineCreation) { this.toggleIsRunningPipeline(pipelineCreationInProgress); } -- GitLab From cd2489a17854e2f726a19cf4f19cbf2c81d83bdd Mon Sep 17 00:00:00 2001 From: Sahil Sharma Date: Fri, 12 Sep 2025 10:40:35 +0100 Subject: [PATCH 4/9] Initial subscription logic added (with debugging) --- ...tion_requests_updated.subscription.graphql | 10 +++ .../legacy_pipelines_table_wrapper.vue | 79 +++++++++++++++++++ app/graphql/graphql_triggers.rb | 5 ++ .../ci/pipeline_creation/requests_updated.rb | 45 +++++++++++ app/graphql/types/merge_request_type.rb | 7 ++ app/graphql/types/subscription_type.rb | 4 + .../merge_requests/create_pipeline_service.rb | 10 ++- doc/api/graphql/reference/_index.md | 12 +++ lib/api/merge_requests.rb | 23 +++--- 9 files changed, 182 insertions(+), 13 deletions(-) create mode 100644 app/assets/javascripts/ci/merge_requests/graphql/subscriptions/ci_pipeline_creation_requests_updated.subscription.graphql create mode 100644 app/graphql/subscriptions/ci/pipeline_creation/requests_updated.rb diff --git a/app/assets/javascripts/ci/merge_requests/graphql/subscriptions/ci_pipeline_creation_requests_updated.subscription.graphql b/app/assets/javascripts/ci/merge_requests/graphql/subscriptions/ci_pipeline_creation_requests_updated.subscription.graphql new file mode 100644 index 00000000000000..3b0e3f49de1fe2 --- /dev/null +++ b/app/assets/javascripts/ci/merge_requests/graphql/subscriptions/ci_pipeline_creation_requests_updated.subscription.graphql @@ -0,0 +1,10 @@ +subscription ciPipelineCreationRequestsUpdated($mergeRequestId: MergeRequestID!) { + ciPipelineCreationRequestsUpdated(mergeRequestId: $mergeRequestId) { + mergeRequestId + pipelineCreationRequests { + status + pipelineId + error + } + } +} diff --git a/app/assets/javascripts/commit/pipelines/legacy_pipelines_table_wrapper.vue b/app/assets/javascripts/commit/pipelines/legacy_pipelines_table_wrapper.vue index 21604e5a9b5750..464a0c8d654742 100644 --- a/app/assets/javascripts/commit/pipelines/legacy_pipelines_table_wrapper.vue +++ b/app/assets/javascripts/commit/pipelines/legacy_pipelines_table_wrapper.vue @@ -10,6 +10,9 @@ import PipelinesService from '~/ci/pipelines_page/services/pipelines_service'; import PipelineStore from '~/ci/pipeline_details/stores/pipelines_store'; import TablePagination from '~/vue_shared/components/pagination/table_pagination.vue'; import { s__, __ } from '~/locale'; +import { convertToGraphQLId } from '~/graphql_shared/utils'; +import { TYPENAME_MERGE_REQUEST } from '~/graphql_shared/constants'; +import ciPipelineCreationRequestsUpdatedSubscription from '~/ci/merge_requests/graphql/subscriptions/ci_pipeline_creation_requests_updated.subscription.graphql'; export default { components: { @@ -82,6 +85,8 @@ export default { page: getParameterByName('page') || '1', requestData: {}, modalId: 'create-pipeline-for-fork-merge-request-modal', + pipelineCreationRequests: [], + subscriptionObserver: null, }; }, @@ -135,10 +140,55 @@ export default { (latest.flags.detached_merge_request_pipeline || latest.flags.merge_request_pipeline) ); }, + isCreatingPipeline() { + const result = + this.pipelineCreationRequests?.some((request) => request.status === 'in_progress') || false; + return result; + }, + }, + watch: { + // Watch for changes in pipeline creation requests + pipelineCreationRequests: { + handler(newRequests, oldRequests) { + this.store.toggleIsRunningPipeline(this.isCreatingPipeline); + + const newFailedRequests = newRequests.filter( + (req) => + req.status === 'failed' && + !oldRequests?.some((oldReq) => oldReq.id === req.id && oldReq.status === 'failed'), + ); + newFailedRequests.forEach((request) => { + this.$toast.show(`Pipeline creation failed: ${request.error}`); + }); + + // Refresh pipelines table when creation completes + const hasNewlyCompletedRequests = newRequests.some( + (req) => + (req.status === 'succeeded' || req.status === 'failed') && + !oldRequests?.some((oldReq) => oldReq.id === req.id && oldReq.status !== 'in_progress'), + ); + + if (hasNewlyCompletedRequests) { + this.updateTable(); + } + }, + deep: true, + }, }, created() { this.service = new PipelinesService(this.endpoint); this.requestData = { page: this.page }; + + // Initialize subscription for merge request tables + if (this.isMergeRequestTable && this.mergeRequestId) { + this.initializePipelineCreationSubscription(); + } + }, + beforeDestroy() { + // Clean up subscription + if (this.subscriptionObserver) { + this.subscriptionObserver.unsubscribe(); + } }, methods: { // eslint-disable-next-line vue/no-unused-properties -- successCallback() is used by the `PipelinesMixin` mixin @@ -164,6 +214,35 @@ export default { } } }, + + initializePipelineCreationSubscription() { + if (!this.$apollo) { + return; + } + + try { + this.subscriptionObserver = this.$apollo + .subscribe({ + query: ciPipelineCreationRequestsUpdatedSubscription, + variables: { + mergeRequestId: convertToGraphQLId(TYPENAME_MERGE_REQUEST, this.mergeRequestId), + }, + }) + .subscribe({ + next: ({ data }) => { + if (data?.ciPipelineCreationRequestsUpdated?.pipelineCreationRequests) { + this.pipelineCreationRequests = + data.ciPipelineCreationRequestsUpdated.pipelineCreationRequests; + } + }, + error: () => { + // Gracefully degrade - subscription failure shouldn't break basic functionality + }, + }); + } catch (error) { + // + } + }, /** * When the user clicks on the "Run pipeline" button * we need to make a post request and diff --git a/app/graphql/graphql_triggers.rb b/app/graphql/graphql_triggers.rb index 6d8b15ea48b2c9..99783f055f7bf9 100644 --- a/app/graphql/graphql_triggers.rb +++ b/app/graphql/graphql_triggers.rb @@ -11,6 +11,11 @@ def self.ci_job_status_updated(job) GitlabSchema.subscriptions.trigger(:ci_job_status_updated, { job_id: job.to_gid }, job) end + def self.ci_pipeline_creation_requests_updated(merge_request) + GitlabSchema.subscriptions.trigger(:ci_pipeline_creation_requests_updated, + { merge_request_id: merge_request.to_gid }, merge_request) + end + def self.ci_pipeline_status_updated(pipeline) GitlabSchema.subscriptions.trigger(:ci_pipeline_status_updated, { pipeline_id: pipeline.to_gid }, pipeline) end diff --git a/app/graphql/subscriptions/ci/pipeline_creation/requests_updated.rb b/app/graphql/subscriptions/ci/pipeline_creation/requests_updated.rb new file mode 100644 index 00000000000000..b4101806f98a33 --- /dev/null +++ b/app/graphql/subscriptions/ci/pipeline_creation/requests_updated.rb @@ -0,0 +1,45 @@ +# frozen_string_literal: true + +module Subscriptions + module Ci + module PipelineCreation + class RequestsUpdated < BaseSubscription + description 'Triggered when pipeline creation requests are updated for a merge request' + + argument :merge_request_id, Types::GlobalIDType[::MergeRequest], + required: true, + description: 'ID of the merge request to subscribe to pipeline creation updates for.' + + field :merge_request_id, Types::GlobalIDType[::MergeRequest], + null: false, + description: 'ID of the merge request.' + + field :pipeline_creation_requests, + [Types::Ci::PipelineCreation::RequestType], + null: false, + description: 'Updated pipeline creation requests for the merge request.' + + def update(merge_request_id:) + merge_request = authorized_find!(merge_request_id) + + { + merge_request_id: merge_request_id, + pipeline_creation_requests: pipeline_creation_requests_for(merge_request) + } + end + + private + + def authorized_find!(merge_request_id) + merge_request = GitlabSchema.object_from_id(merge_request_id, expected_type: ::MergeRequest) + authorize!(merge_request, :read_merge_request) + merge_request + end + + def pipeline_creation_requests_for(merge_request) + Ci::PipelineCreation::Requests.for_merge_request(merge_request) + end + end + end + end +end diff --git a/app/graphql/types/merge_request_type.rb b/app/graphql/types/merge_request_type.rb index 11b046b39df4d0..305f81579ece63 100644 --- a/app/graphql/types/merge_request_type.rb +++ b/app/graphql/types/merge_request_type.rb @@ -171,6 +171,9 @@ def self.authorization_scopes field :head_pipeline, Types::Ci::PipelineType, null: true, method: :diff_head_pipeline, description: 'Pipeline running on the branch HEAD of the merge request.' + field :pipeline_creation_requests, [Types::Ci::PipelineCreation::RequestType], + null: false, + description: 'Pipeline creation requests for the merge request.' field :pipelines, null: true, description: 'Pipelines for the merge request. Note: for performance reasons, ' \ @@ -413,6 +416,10 @@ def notes_count_for_collection(key) end end end + + def pipeline_creation_requests + ::Ci::PipelineCreation::Requests.for_merge_request(object) + end end end diff --git a/app/graphql/types/subscription_type.rb b/app/graphql/types/subscription_type.rb index bac1ab5ba98ae2..5f8ada190bde92 100644 --- a/app/graphql/types/subscription_type.rb +++ b/app/graphql/types/subscription_type.rb @@ -12,6 +12,10 @@ class SubscriptionType < ::Types::BaseObject subscription: Subscriptions::Ci::Jobs::StatusUpdated, null: true, description: 'Triggered when a job status is updated.' + field :ci_pipeline_creation_requests_updated, + subscription: Subscriptions::Ci::PipelineCreation::RequestsUpdated, null: true, + description: 'Triggered when a pipeline creation request is updated.' + field :ci_pipeline_status_updated, subscription: Subscriptions::Ci::Pipelines::StatusUpdated, null: true, description: 'Triggered when a pipeline status is updated.', diff --git a/app/services/merge_requests/create_pipeline_service.rb b/app/services/merge_requests/create_pipeline_service.rb index ab716a55664b9c..13a0b9a852e170 100644 --- a/app/services/merge_requests/create_pipeline_service.rb +++ b/app/services/merge_requests/create_pipeline_service.rb @@ -19,18 +19,26 @@ def execute_async(merge_request) project.id, current_user.id, merge_request.id, params.merge(pipeline_creation_request: pipeline_creation_request).deep_stringify_keys ) + + GraphqlTriggers.ci_pipeline_creation_requests_updated(merge_request) + + pipeline_creation_request['id'] end def create_merge_request_pipeline(merge_request) project, ref = pipeline_project_and_ref(merge_request) - Ci::CreatePipelineService.new(project, + pipeline = Ci::CreatePipelineService.new(project, current_user, ref: ref, push_options: params[:push_options], pipeline_creation_request: params[:pipeline_creation_request], gitaly_context: params[:gitaly_context] ).execute(:merge_request_event, merge_request: merge_request) + + GraphqlTriggers.ci_pipeline_creation_requests_updated(merge_request) + + pipeline end def can_create_pipeline_for?(merge_request) diff --git a/doc/api/graphql/reference/_index.md b/doc/api/graphql/reference/_index.md index 3739be075e7f1c..53dc6410e878e5 100644 --- a/doc/api/graphql/reference/_index.md +++ b/doc/api/graphql/reference/_index.md @@ -34037,6 +34037,7 @@ Defines which user roles, users, or groups can merge into a protected branch. | `milestone` | [`Milestone`](#milestone) | Milestone of the merge request. | | `name` | [`String`](#string) | Name or title of the object. | | `participants` | [`MergeRequestParticipantConnection`](#mergerequestparticipantconnection) | Participants in the merge request. This includes the author, assignees, reviewers, and users mentioned in notes. (see [Connections](#connections)) | +| `pipelineCreationRequests` | [`[CiPipelineCreationRequest!]!`](#cipipelinecreationrequest) | Pipeline creation requests for the merge request. | | `policiesOverridingApprovalSettings` | [`[PolicyApprovalSettingsOverride!]`](#policyapprovalsettingsoverride) | Approval settings that are overridden by the policies for the merge request. | | `policyViolations` | [`PolicyViolationDetails`](#policyviolationdetails) | Policy violations reported on the merge request. | | `preparedAt` | [`Time`](#time) | Timestamp of when the merge request was prepared. | @@ -42163,6 +42164,17 @@ Returns [`Blame`](#blame). | `name` | [`String!`](#string) | Name of the repository language. | | `share` | [`Float`](#float) | Percentage of the repository's languages. | +### `RequestsUpdatedPayload` + +Autogenerated return type of RequestsUpdated. + +#### Fields + +| Name | Type | Description | +| ---- | ---- | ----------- | +| `mergeRequestId` | [`MergeRequestID!`](#mergerequestid) | ID of the merge request. | +| `pipelineCreationRequests` | [`[CiPipelineCreationRequest!]!`](#cipipelinecreationrequest) | Updated pipeline creation requests for the merge request. | + ### `Requirement` Represents a requirement. diff --git a/lib/api/merge_requests.rb b/lib/api/merge_requests.rb index 1b1321055e16cc..9ec926223d5d6d 100644 --- a/lib/api/merge_requests.rb +++ b/lib/api/merge_requests.rb @@ -655,7 +655,6 @@ def batch_process_mergeability_checks(merge_requests) desc: 'Indicates if the merge request pipeline creation should be performed asynchronously. If set to `true`, the pipeline will be created outside of the API request and the endpoint will return an empty response with a `202` status code. When the response is `202`, the creation can still fail outside of this request.' end post ':id/merge_requests/:merge_request_iid/pipelines', urgency: :low, feature_category: :pipeline_composition do - pipeline = nil merge_request = find_merge_request_with_access(params[:merge_request_iid]) merge_request_params = { allow_duplicate: true } @@ -665,20 +664,20 @@ def batch_process_mergeability_checks(merge_requests) ) if params[:async] - service.execute_async(merge_request) - else - pipeline = service.execute(merge_request).payload - end + request_id = service.execute_async(merge_request) - if params[:async] status :accepted - elsif pipeline.nil? - not_allowed! - elsif pipeline.persisted? - status :ok - present pipeline, with: ::API::Entities::Ci::Pipeline + present request_id: request_id else - render_validation_error!(pipeline) + pipeline = service.execute(merge_request).payload + if pipeline.nil? + not_allowed! + elsif pipeline.persisted? + status :ok + present pipeline, with: ::API::Entities::Ci::Pipeline + else + render_validation_error!(pipeline) + end end end -- GitLab From 57019305b5028e1f667e4bb3822b2b5cbbf53a55 Mon Sep 17 00:00:00 2001 From: Sahil Sharma Date: Thu, 18 Sep 2025 11:23:29 +0100 Subject: [PATCH 5/9] Strip StatusUpdated subscription to bare min for debug --- .../ci/pipeline_creation/requests_updated.rb | 29 +++++++------------ doc/api/graphql/reference/_index.md | 11 ------- 2 files changed, 10 insertions(+), 30 deletions(-) diff --git a/app/graphql/subscriptions/ci/pipeline_creation/requests_updated.rb b/app/graphql/subscriptions/ci/pipeline_creation/requests_updated.rb index b4101806f98a33..ccf363d67875d9 100644 --- a/app/graphql/subscriptions/ci/pipeline_creation/requests_updated.rb +++ b/app/graphql/subscriptions/ci/pipeline_creation/requests_updated.rb @@ -3,36 +3,27 @@ module Subscriptions module Ci module PipelineCreation - class RequestsUpdated < BaseSubscription - description 'Triggered when pipeline creation requests are updated for a merge request' + class RequestsUpdated < ::Subscriptions::BaseSubscription + include Gitlab::Graphql::Laziness - argument :merge_request_id, Types::GlobalIDType[::MergeRequest], + argument :merge_request_id, + Types::GlobalIDType[::MergeRequest], required: true, description: 'ID of the merge request to subscribe to pipeline creation updates for.' - field :merge_request_id, Types::GlobalIDType[::MergeRequest], - null: false, - description: 'ID of the merge request.' - - field :pipeline_creation_requests, - [Types::Ci::PipelineCreation::RequestType], - null: false, - description: 'Updated pipeline creation requests for the merge request.' + payload_type Types::GlobalIDType[::MergeRequest] def update(merge_request_id:) - merge_request = authorized_find!(merge_request_id) - - { - merge_request_id: merge_request_id, - pipeline_creation_requests: pipeline_creation_requests_for(merge_request) - } + merge_request_id end private def authorized_find!(merge_request_id) - merge_request = GitlabSchema.object_from_id(merge_request_id, expected_type: ::MergeRequest) - authorize!(merge_request, :read_merge_request) + merge_request = force(GitlabSchema.find_by_gid(merge_request_id)) + + unauthorized! unless merge_request && Ability.allowed?(current_user, :read_merge_request, merge_request) + merge_request end diff --git a/doc/api/graphql/reference/_index.md b/doc/api/graphql/reference/_index.md index 53dc6410e878e5..57894240867cda 100644 --- a/doc/api/graphql/reference/_index.md +++ b/doc/api/graphql/reference/_index.md @@ -42164,17 +42164,6 @@ Returns [`Blame`](#blame). | `name` | [`String!`](#string) | Name of the repository language. | | `share` | [`Float`](#float) | Percentage of the repository's languages. | -### `RequestsUpdatedPayload` - -Autogenerated return type of RequestsUpdated. - -#### Fields - -| Name | Type | Description | -| ---- | ---- | ----------- | -| `mergeRequestId` | [`MergeRequestID!`](#mergerequestid) | ID of the merge request. | -| `pipelineCreationRequests` | [`[CiPipelineCreationRequest!]!`](#cipipelinecreationrequest) | Updated pipeline creation requests for the merge request. | - ### `Requirement` Represents a requirement. -- GitLab From 7309fe3fa784130e980ae2ce8b7271efd3068051 Mon Sep 17 00:00:00 2001 From: Sahil Sharma Date: Mon, 22 Sep 2025 09:53:56 +0100 Subject: [PATCH 6/9] Apollo subscription logic updated with debug logs (cherry picked from commit 8ed3b368aa561981b1ad8c3854182af47f8b2cd8) --- .../legacy_pipelines_table_wrapper.vue | 86 ++++++++++--------- .../ci/pipeline_creation/requests_updated.rb | 19 +++- .../requests_updated_payload_type.rb | 19 ++++ doc/api/graphql/reference/_index.md | 11 +++ 4 files changed, 89 insertions(+), 46 deletions(-) create mode 100644 app/graphql/types/ci/pipeline_creation/requests_updated_payload_type.rb diff --git a/app/assets/javascripts/commit/pipelines/legacy_pipelines_table_wrapper.vue b/app/assets/javascripts/commit/pipelines/legacy_pipelines_table_wrapper.vue index 464a0c8d654742..18c54ba5db5b92 100644 --- a/app/assets/javascripts/commit/pipelines/legacy_pipelines_table_wrapper.vue +++ b/app/assets/javascripts/commit/pipelines/legacy_pipelines_table_wrapper.vue @@ -1,5 +1,5 @@