Class: Danger::DangerGitlabGraph

Inherits:
Plugin
  • Object
show all
Defined in:
lib/gitlab_graph/plugin.rb

Overview

This plugin retrieves a certain metric from previous job runs and displays them as a graph

outputs a graph similiar to this ![sample graph](spec/support/fixtures/graph-simple-expected.svg)

Examples:

Extract values from job “test” with the given regex


gitlab_graph.report_metric([{
                           regex: /took ([0-9]+)/,
                           series_name: "Performance",
                           job_name: "test1"
                         }, {
                           regex: /slept ([0-9]+)/,
                           series_name: "IDLE time",
                           job_name: "test1"
                         }])

See Also:

  • kingjan1999/danger-gitlab_graph

Defined Under Namespace

Classes: JobNotFoundException

Instance Method Summary collapse

Instance Method Details

#gather_metric(extraction_config, prev_pipeline_count = 10) ⇒ Arrray<{pipeline_id => int, :metric => float}>

Gathers metric data from current and pevious pipelines

Returns:

  • (Arrray<{pipeline_id => int, :metric => float}>)


27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
# File 'lib/gitlab_graph/plugin.rb', line 27

def gather_metric(extraction_config, prev_pipeline_count = 10)
  pipeline_id = ENV["CI_PIPELINE_ID"].to_i
  project_id = ENV.fetch("CI_PROJECT_ID", nil)

  target_branch = gitlab.branch_for_merge

  begin
    new_metric = extract_metric_from_pipeline(project_id, pipeline_id, extraction_config[:regex], extraction_config[:job_name])
  rescue JobNotFoundException
    warn("Job #{extraction_config[:job_name]} for metric extraction of #{extraction_config[:series_name]} not found in current pipeline")
    return []
  end

  unless new_metric[:metric]
    warn("No updated metric #{extraction_config[:series_name]} found for job #{extraction_config[:job_name]}")
    return []
  end

  previous_target_branch_pipelines = gitlab.api.pipelines(project_id, {
    status: "success",
    ref: target_branch,
    per_page: prev_pipeline_count
  })

  previous_metrics = previous_target_branch_pipelines.collect do |pipeline|
    extract_metric_from_pipeline(project_id, pipeline.id, extraction_config[:regex], extraction_config[:job_name]).merge(hash: pipeline.sha)
  rescue JobNotFoundException
    return { pipeline_id: pipeline.id, metric: false, hash: pipeline.sha }
  end

  previous_metrics + [new_metric.merge(hash: ENV.fetch("CI_COMMIT_SHA", "invalid_hash"))]
end

#report_metric(extraction_configs, prev_pipeline_count = 10, graph_options = {}) ⇒ void

This method returns an undefined value.

Creates and comments a graph based on a certain metric, extracted via regex

Parameters:

  • extraction_configs (Array<hash>)

    Hash-Array: :job_name, :series_name

  • prev_pipeline_count (int) (defaults to: 10)
  • graph_options (hash) (defaults to: {})

    see svg-graph doc



65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
# File 'lib/gitlab_graph/plugin.rb', line 65

def report_metric(extraction_configs, prev_pipeline_count = 10, graph_options = {})
  project_id = ENV.fetch("CI_PROJECT_ID", nil)

  fields = nil
  all_data = []
  extraction_configs.each do |extraction_config|
    all_metrics = gather_metric(extraction_config, prev_pipeline_count)

    if all_metrics.length.zero?
      next
    end

    if fields and all_metrics.length != fields.length
      warn("Not all metrics could be found in an equal amount of jobs. Unable to plot #{extraction_config[:series_name]}")
      next
    end

    data = all_metrics.collect { |val| val[:metric] }

    fields ||= all_metrics.collect { |pipeline| pipeline[:hash][0..7] }

    all_data.push({ data: data, title: extraction_config[:series_name] })
  end

  if all_data.empty?
    return
  end

  default_graph_options = {
    width: 640,
    height: 480,
    graph_title: "Performance Metric",
    show_graph_title: true,
    x_title: "Commit",
    y_title: "Metric Value",
    show_y_title: true,
    show_x_title: true,
    number_format: "%.2fs",
    fields: fields
  }

  # create graph
  g = SVG::Graph::Line.new(default_graph_options.merge(graph_options))

  all_data.each { |elem| g.add_data(data: elem[:data], title: elem[:title]) }

  temp_file = Tempfile.new(%w(graph .svg))
  begin
    temp_file.write(g.burn_svg_only)
    uploaded_file = gitlab.api.upload_file(project_id, temp_file.path)
    markdown(uploaded_file.markdown)
  ensure
    temp_file.close
    temp_file.unlink
  end
end