Add GraphQL subscription for CD deployment status updates

What does this MR do and why?

Adds a GraphQL subscription so the frontend can receive live deployment status changes instead of polling:

  • cdDeploymentUpdated — pushed when a Cd::Deployment changes state (pendingdeployinghealthy/degraded/failed/cancelled).

This is substrate work, following the same approach used for cdRolloutUpdated (!247398 (merged)) and cdServiceUpdated: it adds the subscription type and the GraphqlTriggers.cd_deployment_updated method that later work will call from the real deployment state transitions. No application code calls this trigger yet.

The subscription is keyed by applicationId (resolved as deployment.service.application) and authorizes read_cd_application, resolved from the GID argument (not self.object, since on delivery self.object is the deployment payload, not the application).

scopes is deliberately narrower than cdRolloutUpdated ([:api, :read_api], no :ai_features): this payload carries no AI/Duo data, matching the choice already made for cdApplicationHealthUpdated and cdServiceUpdated.

References

Resolves https://gitlab.com/gitlab-org/gitlab/-/work_items/607493

Requested during review of !247398 (merged) (see note).

Example query

cdDeploymentUpdated

subscription {
  cdDeploymentUpdated(applicationId: "gid://gitlab/Cd::Application/1") {
    id
    state
    startedAt
    finishedAt
    service {
      id
      name
    }
    rolloutEnvironment {
      id
      state
    }
  }
}

Screenshot_2026-07-31_at_11.19.19

How to set up and validate locally

  1. In a Rails console or GraphiQL (/-/graphql-explorer), subscribe to the query above, using the global ID of an existing Cd::Application (or create one: application = FactoryBot.create(:cd_application) in a console, if factories are loaded in your environment; otherwise use an application created through the CD UI/API).
  2. Fetch a deployment belonging to that application and fire the trigger manually from a Rails console:
application = Cd::Application.first
deployment = Cd::Deployment.joins(:service).where(cd_services: { application_id: application.id }).first

GraphqlTriggers.cd_deployment_updated(deployment)
  1. Confirm the subscriber receives the deployment payload.
  2. Confirm a deployment belonging to a different application does not trigger a delivery to the same subscriber.

MR acceptance checklist

Evaluate this MR against the MR acceptance checklist. It helps you analyze changes to reduce risks in quality, performance, reliability, security, and maintainability.

Related to #607493

Merge request reports

Loading
Loading