From c56747d43015f1cd7b44dc9c046f37b7a15ef647 Mon Sep 17 00:00:00 2001 From: Peter Idah Date: Mon, 13 May 2024 23:46:45 +0100 Subject: [PATCH 1/2] add time from first pr review to merge --- README.md | 8 ++++++++ report_github_metrics.rb | 19 ++++++++++++++++++- 2 files changed, 26 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 43486f8..5243fde 100644 --- a/README.md +++ b/README.md @@ -66,6 +66,13 @@ Metric value: 389.0 Tags: {project: "scribd/my_repository"} ``` + +``` +Metric name: .time_from_first_review_to_merge +Metric value: 125.0 +Tags: {project: "scribd/my_repository"} +``` + ### Metric Counts In addition to all of the above metrics, a metric is also submitted with the value 1 that is named `..count` for each metric to allow for counting the number of each metric submitted. @@ -151,6 +158,7 @@ The following example can be placed into a workflow file to report the Developme - `{datadog-metric-prefix}.time_to_open` - `{datadog-metric-prefix}.time_to_merge` - `{datadog-metric-prefix}.lines_changed` +- `{datadog-metric-prefix}.time_from_first_review_to_merge` ``` name: Velocity Workflow diff --git a/report_github_metrics.rb b/report_github_metrics.rb index 03e7633..c80cd9c 100755 --- a/report_github_metrics.rb +++ b/report_github_metrics.rb @@ -63,16 +63,33 @@ def collect_merged_data(github_client, repo, teams) pr_info = github_client.pull_request(repo, ENV['PR_NUMBER']) base_branch = pr_info[:base][:ref] default_branch = pr_info[:base][:repo][:default_branch] + + # Calculate time to merge time_to_merge = pr_info["merged_at"] - pr_info["created_at"] + + # Calculate lines changed diff_size = pr_info["additions"] + pr_info["deletions"] + + # Calculate time from first review to merge + first_review_time = first_review_creation_time(github_client, pr_info) + time_from_first_review_to_merge = pr_info["merged_at"] - first_review_time + tags = CUSTOM_TAGS + ["project:#{repo}", "default_branch:#{base_branch == default_branch}"] tags += teams.map{|team| "team:#{team}"} if teams && teams.count.positive? + [ ["time_to_merge", time_to_merge, tags], - ["lines_changed", diff_size, tags] + ["lines_changed", diff_size, tags], + ["time_from_first_review_to_merge", time_from_first_review_to_merge, tags] # Adding time from first review to merge metric ] end +def first_review_creation_time(github_client, pr_info) + reviews = github_client.pull_request_reviews(pr_info[:base][:repo][:full_name], pr_info[:number]) + first_review = reviews.find { |review| review["state"] == "APPROVED" || review["state"] == "CHANGES_REQUESTED" } + first_review.nil? ? pr_info["created_at"] : first_review["submitted_at"] +end + def collect_opened_data(github_client, repo, teams) pr_info = github_client.pull_request(repo, ENV['PR_NUMBER']) base_branch = pr_info[:base][:ref] From 91e51f52db0910a363b3fd66768dd8e6e672fd02 Mon Sep 17 00:00:00 2001 From: Peter Idah Date: Tue, 4 Jun 2024 17:40:43 +0100 Subject: [PATCH 2/2] add github merge queue data --- report_github_metrics.rb | 39 +++++++++++++++++++++++++++++++++++---- 1 file changed, 35 insertions(+), 4 deletions(-) diff --git a/report_github_metrics.rb b/report_github_metrics.rb index c80cd9c..8871889 100755 --- a/report_github_metrics.rb +++ b/report_github_metrics.rb @@ -2,8 +2,11 @@ require 'rubygems' require 'dogapi' require 'date' +require 'time' require 'json' +MERGE_QUEUE_ADD_KEY = "merge_queue_add_time" + def collect_metrics(workflow_run, jobs, tags) jobs.map{|job| collect_job_metrics(job, tags)}.compact + \ collect_workflow_metrics(workflow_run, jobs, tags) @@ -63,20 +66,19 @@ def collect_merged_data(github_client, repo, teams) pr_info = github_client.pull_request(repo, ENV['PR_NUMBER']) base_branch = pr_info[:base][:ref] default_branch = pr_info[:base][:repo][:default_branch] - + # Calculate time to merge time_to_merge = pr_info["merged_at"] - pr_info["created_at"] - + # Calculate lines changed diff_size = pr_info["additions"] + pr_info["deletions"] - + # Calculate time from first review to merge first_review_time = first_review_creation_time(github_client, pr_info) time_from_first_review_to_merge = pr_info["merged_at"] - first_review_time tags = CUSTOM_TAGS + ["project:#{repo}", "default_branch:#{base_branch == default_branch}"] tags += teams.map{|team| "team:#{team}"} if teams && teams.count.positive? - [ ["time_to_merge", time_to_merge, tags], ["lines_changed", diff_size, tags], @@ -115,10 +117,31 @@ def collect_duration_data(github_client, repo, run_id) collect_metrics(run, jobs, tags) end +def collect_merge_queue_data + current_time = Time.now.utc + tags = CUSTOM_TAGS + ["event:merge_queue_add_time"] + [ + ["merge_queue_add_time", current_time.to_i, tags] + ] +end + def parse_array_input(arg) arg.nil? || arg == '' ? [] : JSON.parse(arg.strip) end +def first_merge_queue_event?(github_client, repo, pr_number) + pr_info = github_client.pull_request(repo, pr_number) + pr_body = pr_info.body + + if pr_body.include?("#{MERGE_QUEUE_ADD_KEY}:") + false + else + new_body = "#{pr_body}\n\n#{MERGE_QUEUE_ADD_KEY}: #{Time.now.utc.iso8601}" + github_client.update_pull_request(repo, pr_number, body: new_body) + true + end +end + TAGGED_BRANCHES = parse_array_input(ARGV[4]) CUSTOM_TAGS = parse_array_input(ARGV[5]) @@ -140,6 +163,14 @@ def parse_array_input(arg) metrics = collect_opened_data(github_client, repo, teams) when "job_metrics" metrics = collect_duration_data(github_client, repo, run_id) +when "checks_requested" + pr_number = ENV['PR_NUMBER'] + if first_merge_queue_event?(github_client, repo, pr_number) + metrics = collect_merge_queue_data + else + puts "PR added to Merge queue event already reported for PR #{pr_number}" + end end submit_metrics(metrics, datadog_client, metric_prefix) if metrics +