Add user filter and dimension to Pipelines aggregation engine
What does this MR do and why?
The DAP Impact Dashboard needs to let leaders filter and group dashboard data by an arbitrary team (a set of people), not only by GitLab group or project. Issue https://gitlab.com/gitlab-org/gitlab/-/issues/611201 is being delivered as four merge requests, one per ClickHouse aggregation engine that was missing by-user support. This MR covers the Pipelines engine.
The siphon_p_ci_pipelines table stores user_id as Nullable(Int64), and the engine had no way to filter or group by it. Without this, a team-scoped view of pipelines silently fell back to unfiltered data.
Changes:
- Adds
column :user_id, :integer, description: 'User who triggered the pipeline', association: trueandexact_match :user_id, :string, description: 'Filter by one or many user Global IDs', formatter: gid_formattertoee/app/models/analytics/aggregation_engines/pipelines.rb. - This adds a new
userIdargument onAnalytics.pipelinesand a newuserfield of typeUserCoreonPipelinesAggregationResponseDimensions, both generated from the engine declaration. user_idis not part of the table's sort key, so the aggregation framework wraps it inargMaxfor deduplication, matching how the other non-key columns on thisReplacingMergeTreetable are already handled.- Nullable column: pipelines started by a schedule, a trigger token, or an integration have no
user_id. Those rows group under a null key and theuserfield resolves to null. Specs cover that case. - This is the engine's second association dimension, alongside the existing
project_id. That is safe becauseBatchLoader::GraphQL.for(...).batch(key: dimension)already includes thekey:fix from commit890b49c3660c. Without that key, every association field on an engine would share one batch and ids would get looked up against the wrong model. - No migration, schema change, or feature flag: the column already existed in ClickHouse.
- Regenerates
doc/api/graphql/reference/_index.mdandpublic/-/graphql/introspection_result.json. - Spec coverage: dimension examples for
:user_idand the:userassociation alias (including a row with no user), a filter block for a single Global ID and an array of Global IDs, and a GraphQL request context that filters by a user Global ID and groups by the resolved association.
Out of scope
- The
user_usernamefilter work, tracked in #599750. - The
DuoWorkflowsengine, tracked in https://gitlab.com/gitlab-org/gitlab/-/issues/605529, which will ship with by-user filtering and grouping from day one. - The other three engines needing the same treatment (
Contributions,Deployments,MergeRequests), each covered by its own MR against https://gitlab.com/gitlab-org/gitlab/-/issues/611201.
How to set up and validate locally
-
Query the new argument and dimension in GraphiQL:
query { group(fullPath: "gitlab-org") { analytics { pipelines(userId: ["gid://gitlab/User/1"]) { aggregated { nodes { dimensions { user { id username } } totalCount } } } } } } -
Run the specs for this engine:
bundle exec rspec ee/spec/models/analytics/aggregation_engines/pipelines_spec.rb ee/spec/requests/api/graphql/analytics/pipelines_spec.rb -
Confirm the GraphQL docs are up to date:
bundle exec rake gitlab:graphql:check_docs -
Confirm the introspection JSON is up to date:
bundle exec rake gitlab:graphql:check_introspection_sync
References
- Part of https://gitlab.com/gitlab-org/gitlab/-/issues/611201
- Epic https://gitlab.com/groups/gitlab-org/-/work_items/23225
- Related: #599750
- Related: https://gitlab.com/gitlab-org/gitlab/-/issues/605529
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.