Accept CD Deployment transitions from autoflow

What does this MR do?

This MR lets the CD orchestrator report flow-graph progress back to GitLab through POST /api/v4/rollouts/:id, and makes that reporting safe to retry.

The endpoint accepts three event types for a single service inside an environment – service started, service succeeded, and service failed – plus one event that marks a whole rollout complete. Service events move the matching deployment through pending, deploying, and healthy or failed, and every step is journaled as a deployment transition under the system:autoflow principal so the history stays auditable. The rollout-succeeded event is the only thing that marks a rollout complete: state syncing from step data can only ever derive a failure, never a success, so there is exactly one path to "done" and the orchestrator only takes it once, after every step has finished without a failure.

Each event carries the environment name, service name, step position, and, for failures, an error message. These are read through a small WorkflowEvent wrapper, and every event type string is defined once and shared across the API and the transition logic, so there is one source of truth instead of several. The environment, deployment, and rollout-level transitions (including the step tree and approval gate) each live in their own focused class, and a thin service runs all three in a single transaction, turning any database error into a normal API response rather than a 500. Duplicate or out-of-order deliveries are handled as no-ops, so the callback can be retried freely. This ships with no feature flag and no database migration.

How to test

1. Seed data (Rails console)
org = Organizations::Organization.find(1)

application = Cd::Application.create!(organization: org, name: "deploy-progress-test")
service = Cd::Service.create!(application: application, organization: org, name: "web")
environment = Cd::Environment.create!(organization: org, name: "test-env", tier: :production)
driver_binding = Cd::EnvironmentDriverBinding.create!(
  environment: environment, organization: org,
  driver_ref: "argo-rollouts", driver_config: { "cluster_agent_id" => "1" }
)
version_set = Cd::VersionSet.create!(organization: org, application: application, name: "test-release")

rollout = Cd::Rollout.create!(
  organization: org, application: application, version_set: version_set,
  state: :in_progress, workflow_ref: "wk:manual/mrtest", started_at: Time.current
)
rollout_environment = rollout.rollout_environments.create!(
  organization: org, environment: environment, driver_binding: driver_binding,
  position: 1, state: :in_progress
)
deployment = Cd::Deployment.create!(organization: org, rollout_environment: rollout_environment, service: service, state: :pending)

token = Cd::Rollouts::CallbackToken.encode(rollout)
puts "rollout_id=#{rollout.id}"
puts "environment_name=#{environment.name}"
puts "callback_token=#{token}"

Verified live on a real GDK.

2. Post the orchestrator's workflow events (curl)
curl -X POST "http://gdk.test:3000/api/v4/rollouts/<rollout_id>" \
  -H "Authorization: Bearer <callback_token>" -H "Content-Type: application/json" \
  -d '{"topic":"com.gitlab.cd.deployment","type":"com.gitlab.cd.service_started","data":{"position":[0,0],"environment":"<environment_name>","service":"web"}}'

curl -X POST "http://gdk.test:3000/api/v4/rollouts/<rollout_id>" \
  -H "Authorization: Bearer <callback_token>" -H "Content-Type: application/json" \
  -d '{"topic":"com.gitlab.cd.deployment","type":"com.gitlab.cd.service_succeeded","data":{"position":[0,0],"environment":"<environment_name>","service":"web"}}'

Verified live: both requests returned 202, and the deployment transitioned pending -> deploying -> healthy.

Expected: the deployment moves from pending to deploying to healthy, with a Cd::DeploymentTransition recorded for each step.

References

Screenshots or screen recordings

No UI change - backend-only.

How to set up and validate locally

  1. Seed the records using the Rails console script above.
  2. Post the two workflow events for the deployment with the curl commands above.
  3. In a Rails console, confirm the Cd::Deployment reached healthy and check that its Cd::DeploymentTransition rows exist for each state change.

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.

Edited by George Koltsov

Merge request reports

Loading
Loading