Expose acting user on CD entities via GraphQL
What this MR does
The CD Rails design keeps attribution in the transition journal rather than as columns on the entities themselves, so status and attribution stay derived and are never authored directly by clients. But nothing captured that attribution at creation time, so there was no data to derive from.
This MR adds the missing capture points to expose the acting user:
Cd::Rollouts::CreateServicenow writes the initial transition journal row, since it is the only place the requesting user is known synchronously (StartWorker/StartServicerun async).Cd::VersionSets::CreateServicenow setscreated_by. Version sets have no transition journal to derive from, so this is the one case that needed a new column (created_by_id, write-once, consistent with version sets being immutable).Cd::Concerns::PrincipalReferencecentralizes parsing the"user:<id>"principal format so callers never do it themselves.
New GraphQL fields (all batched, N+1-safe):
CdRollout.triggeredByUserCdVersionSet.author
CdDeployment.triggeredByUser and CdService.lastDeployedBy were dropped from this MR: deployment creation has no production write path yet, so cd_deployment_transitions is never populated and those fields would always resolve to null. Follow-up once deployment creation/attribution is designed.
Query Plans
This MR introduces one new query. This CD table carries no meaningful GitLab.com
production data yet (Beta feature, gated by the ai_native_deploy feature flag), so
per the database review guidelines,
the plan below was generated from a local development environment (seeded with
representative rows, reverted afterwards) rather than postgres.ai.
This reuses an index that already existed before this change; no new indexes were
required beyond the one added for cd_version_sets.created_by_id.
Cd::RolloutTransition.first_acting_user_id_by_rollout
SELECT "cd_rollout_transitions"."rollout_id", "cd_rollout_transitions"."principal",
"cd_rollout_transitions"."on_behalf_of", "cd_rollout_transitions"."created_at"
FROM "cd_rollout_transitions"
WHERE "cd_rollout_transitions"."rollout_id" IN (1, 2, ..., 50)
ORDER BY "cd_rollout_transitions"."created_at" ASC, "cd_rollout_transitions"."id" ASCQuery plan (local, 50 rollout ids):
Sort (cost=15.53..15.75 rows=88 width=88) (actual time=0.028..0.029 rows=50 loops=1)
Sort Key: created_at, id
Sort Method: quicksort Memory: 27kB
-> Index Scan using index_cd_rollout_transitions_on_rollout_id_and_created_at on cd_rollout_transitions (cost=0.15..12.69 rows=88 width=88) (actual time=0.012..0.016 rows=50 loops=1)
Index Cond: (rollout_id = ANY ('{1,2,...,50}'::bigint[]))
Planning Time: 0.192 ms
Execution Time: 0.034 msTesting GraphQl queries
- Discover an organization ID and any existing CD entities
query {
organization(id: "gid://gitlab/Organizations::Organization/1") {
id
cdApplications {
nodes {
id
name
services { nodes { id name } }
versionSets { nodes { id name } }
rollouts { nodes { id iid } }
}
}
}
}CdVersionSet.author
query {
organization(id: "gid://gitlab/Organizations::Organization/1") {
cdVersionSet(id: "gid://gitlab/Cd::VersionSet/<ID>") {
id
name
author {
id
username
}
}
}
}CdRollout.triggeredByUser
query {
organization(id: "gid://gitlab/Organizations::Organization/1") {
cdRollout(id: "gid://gitlab/Cd::Rollout/<ID>") {
id
iid
triggeredByUser {
id
username
}
}
}
}Note: reads are gated behind the ai_native_deploy feature flag — enable it first with Feature.enable(:ai_native_deploy) in a rails console if it isn't already on.
Note: triggeredByUser/author are derived from data written at creation time (the transition journal, or created_by_id for version sets). Rollouts and version sets that already existed before this MR will have no attribution to derive from and will correctly return null — this is expected, not a bug. The fields only populate for entities created after this change, via the CdRolloutCreate/CdVersionSetCreate mutations.
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 https://gitlab.com/gitlab-org/gitlab/-/work_items/606062

