Plot pipeline time series in CI/CD analytics

What does this MR do and why?

This change adds two charts to the CI/CD analytics.

The time series are fetched based on date inputs.

This change is placed behind the feature flag ci_improved_project_pipeline_analytics.

Simplified Scope

For this MR, I have opted to make a few simplifications, to keep MR's size small:

  • Tooltips don't yet match the design exactly, for example there is no duration formatting (e.g. 2 hrs 1 min), so the chart represents the values in seconds.
  • Order of the "stacks" in the pipeline status chart does not match the design (e.g. successful should be at the top). Our charts do not support this out of the box (and neither does echarts, see https://github.com/apache/echarts/issues/14700), so I'd have to contribute to our stacked charts.
  • The legend next to Other in the bottom chart should be next to Cancelled, Skipped text.

All of these improvements should be part of upcoming issues and MRs, once this MR is approved.

References

MR acceptance checklist

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

Screenshots or screen recordings

Before

image

After

image

How to set up and validate locally

You'll need a project with CI enabled and a GitLab instance with clickhouse enabled.

  1. Visit you project's homepage, in my case it is: http://gdk.test:3000/my-group/my-project, and note the project ID
Screenshot_2025-02-18_at_16.16.25
  1. Go to the rails console by typing bundle exec rails c

  2. Enable the feature flag Feature.enable(:ci_improved_project_pipeline_analytics)

  3. We want to simulate having run many pipelines. I've created a script which we can use in the rails console.

Copy the following into the console:

def seed_pipeline_analytics(project_id, from_days, pipeline_count)
  traversal_path = Project.find(project_id).project_namespace.traversal_path

  rand_status = -> { ['success', 'success', 'failed', 'failed', 'canceled'].sample }
  rand_date = -> { (rand((Time.now - 60 * 60 * 24 * from_days)..Time.now)).strftime('%F %T') }
  rand_duration = -> { rand(60) + rand(60) + rand(60) + rand(60) + rand(60) }

  sample_data = []
  pipeline_count.times {|i| sample_data.push({ id: sample_data.length, path: traversal_path, status: rand_status.call, started_at: rand_date.call, duration: rand_duration.call }) } 

  sample_data.each do |record|
    query = <<-SQL
      INSERT INTO ci_finished_pipelines 
      (id, path, status, started_at, duration)
      VALUES (#{record[:id]}, '#{record[:path]}', '#{record[:status]}', '#{record[:started_at]}', '#{record[:duration]}')
    SQL
    ClickHouse::Client.execute(query, :main)
  end
end
seed_pipeline_analytics(22, 7, 100) # project id, one week of activity to simulate, number of pipelines to simulate
  1. Visit your project's CI/CD dashboard at "Analyze > CI/CD Analytics" to see the changes:

Example URL: http://gdk.test:3000/my-group/my-project/-/pipelines/charts

Related to #469603 (closed)

Edited by Miguel Rincon

Merge request reports

Loading