Add merge request and Duo usage GLQL analytics sources

What does this MR do and why?

Bumps gitlab_query_language to 0.33.0, which adds two new analytics sources to the GLQL compiler:

  • type: MergeRequest with mode: analytics, backed by analytics.mergeRequests
  • type: AiUsageEvent with mode: analytics, backed by analytics.duoUsageEvents

The /glql endpoint is source agnostic, so the gem bump is the only code change. The new request specs cover both sources: compile output including the default parameters (quantile: 0.5 on timeToMergeQuantile, granularity: weekly on timestamp), and denied paths for users without read_cycle_analytics/read_pro_ai_analytics. The denied paths run the real authorisation stack rather than stubbing the query service. The existing pipelines source was missing specs, so I've added the same coverage for it (read_ci_cd_analytics, including group-scoped denial) whilst in the file.

Author note (non-blocking): the Gemfile.next.lock diff also picks up Rails-next 8.0.5.1. That's the output of the canonical bundler:gemfile:sync steps, master's next-lock was stale.

The frontend half (presenters and the @gitlab/query-language-rust bump) is in Add GLQL presenters for merge request and Duo u... (!248035 - merged). Neither source is documented until both are merged; docs are tracked in #592280 (closed) and #592272 (closed).

How to set up and validate locally

  1. Run the request specs:

    bundle exec rspec ee/spec/requests/api/glql_spec.rb
  2. Set up Clickhouse in your GDK

  3. Set up Siphon in your GDK so merge requests replicate into ClickHouse

  4. Enable Clickhouse-based analytics: echo 'Gitlab::CurrentSettings.current_application_settings.update(use_clickhouse_for_analytics: true)' | rails c

  5. Seed AI usage events: FILTER=ai_usage_stats bundle exec rake db:seed_fu (seeds the first project; use PROJECT_ID=<id> to target another)

  6. Seed MR Analytics: FILTER=productivity_analytics SEED_PRODUCTIVITY_ANALYTICS=1bundle exec rake db:seed_fu (seeds the first project; use PROJECT_ID=<id> to target another)

  7. Compile and run a merge request analytics query:

    curl --request POST \
      --header "PRIVATE-TOKEN: <token>" \
      --header "Content-Type: application/json" \
      --data '{"glql_yaml": "mode: analytics\ndimensions: merged(weekly), state\nmetrics: totalCount, throughputCount, timeToMergeQuantile(0.5)\nquery: type = MergeRequest AND group = \"gitlab-org\" AND merged > -30d"}' \
      --url "http://gdk.test:8080/api/v4/glql"

    The query compiles against analytics.mergeRequests. The fields array should include timeToMergeQuantile with "type": "metric" and "parameters": {"quantile": "0.5"}, and the data rows should bucket by week.

  8. And an AI usage events query:

    curl --request POST \
      --header "PRIVATE-TOKEN: <token>" \
      --header "Content-Type: application/json" \
      --data '{"glql_yaml": "mode: analytics\ndimensions: feature, timestamp\nmetrics: totalCount, usersCount\nquery: type = AiUsageEvent AND group = \"gitlab-org\" AND timestamp > -30d"}' \
      --url "http://gdk.test:8080/api/v4/glql"

    The query compiles against analytics.duoUsageEvents. The fields array should include timestamp with "parameters": {"granularity": "weekly"}.

Related to #592271 (closed) and #592279 (closed).

Edited by Robert Hunt

Merge request reports

Loading
Loading