Skip to content

Instantly share code, notes, and snippets.

@jtimberman
Last active August 29, 2015 14:17
Show Gist options
  • Save jtimberman/6e1b613a09a629d93ee5 to your computer and use it in GitHub Desktop.
Save jtimberman/6e1b613a09a629d93ee5 to your computer and use it in GitHub Desktop.

Tested with Ruby 2.1.4.

Install the Octokit gem.

gem install octokit -v 3.7.0
Version: 12.1.1
Total PRs: 15
Average duration PRs were open: 4.37 days
Average creation-to-release of PRs: 6.61 days
------------------------------------------------------
Version: 11.18.6
Total PRs: 19
Average duration PRs were open: 11.47 days
Average creation-to-release of PRs: 12.38 days
------------------------------------------------------
Version: 11.18.2
Total PRs: 13
Average duration PRs were open: 9.0 days
Average creation-to-release of PRs: 14.05 days
------------------------------------------------------
Version: 12.0.3
Total PRs: 1
Average duration PRs were open: 0.54 hours
Average creation-to-release of PRs: 1.04 hours
------------------------------------------------------
Version: 12.0.1
Total PRs: 10
Average duration PRs were open: 2.22 days
Average creation-to-release of PRs: 2.54 days
------------------------------------------------------
Version: 11.16.4
Total PRs: 32
Average duration PRs were open: 4.24 days
Average creation-to-release of PRs: 12.58 days
------------------------------------------------------
Version: 11.16.0
Total PRs: 49
Average duration PRs were open: 4.3 days
Average creation-to-release of PRs: 13.16 days
------------------------------------------------------
Version: 11.14.4
Total PRs: 57
Average duration PRs were open: 17.2 days
Average creation-to-release of PRs: 22.57 days
------------------------------------------------------
Version: 11.14.0
Total PRs: 93
Average duration PRs were open: 35.31 days
Average creation-to-release of PRs: 69.21 days
------------------------------------------------------
Version: 11.12.6
Total PRs: 37
Average duration PRs were open: 16.78 days
Average creation-to-release of PRs: 36.77 days
------------------------------------------------------
Version: 11.12.2
Total PRs: 4
Average duration PRs were open: 0.54 hours
Average creation-to-release of PRs: 7.25 hours
------------------------------------------------------
Version: 11.10.4
Total PRs: 4
Average duration PRs were open: 18.69 hours
Average creation-to-release of PRs: 1.27 days
------------------------------------------------------
Version: 11.10.0
Total PRs: 37
Average duration PRs were open: 6.71 days
Average creation-to-release of PRs: 30.22 days
------------------------------------------------------
Version: 11.8.0
Total PRs: 43
Average duration PRs were open: 7.13 days
Average creation-to-release of PRs: 20.52 days
------------------------------------------------------
Version: 11.6.0
Total PRs: 76
Average duration PRs were open: 2.1 days
Average creation-to-release of PRs: 42.79 days
------------------------------------------------------
Version: 11.4.2
Total PRs: 16
Average duration PRs were open: 5.45 days
Average creation-to-release of PRs: 36.78 days
------------------------------------------------------
#!/usr/bin/env ruby
# Author: Joshua Timberman <joshua@chef.io>
#
# https://twitter.com/jtimberman/status/576421331874418690
# "OH 'that looks like a bash script and a text file filtered through a ruby lens'"
#
# Brought to you by itsprobablyfine.jpg, and #worksonmymachine
# Version controlled at:
# - https://gist.github.com/jtimberman/594b095f1e1e77fd968b
#
require 'pp'
class PullRequestFrequency
def initialize(repo = 'chef/chef')
@api_token = api_token
@client ||= client
@repo = repo
end
attr_accessor :api_token, :client
attr_accessor :pulls, :repo, :repo_tags
def api_token
File.read(File.join(File.expand_path('~'), '.github', 'api_token')).chomp
end
def client
require 'octokit'
Octokit::Client.new(access_token: api_token, auto_paginate: true)
end
def pulls
@pulls ||= self.client.pull_requests(self.repo, state: 'closed')
end
def repo_tags
@repo_tags ||= self.client.tags(self.repo)
end
end
def date_between?(date, early, late)
date >= early && date <= late
end
def days_or_hours(num)
hours = num / 3600
if hours > 24
days = hours / 24
else
return "#{hours.round(2)} hours"
end
return "#{days.round(2)} days"
end
prf = PullRequestFrequency.new
desired_tags = prf.repo_tags.select do |t|
t[:name].match(/^(\d+)\.(\d+)\.(\d+)$/) && $1.to_i >= 11
end
desired_tag_data = {}
desired_tags.each do |t|
commit_data = prf.client.commit(prf.repo, t[:commit][:sha])
desired_tag_data[t[:name]] = {
sha: t[:commit][:sha],
date: commit_data[:commit][:committer][:date]
}
end
pr_data = {}
release_data = {}
prf.pulls.each do |pr|
desired_tag_data.keys.reverse.each_slice(2) do |v|
if pr[:merged_at] && date_between?(pr[:merged_at],
desired_tag_data[v.first][:date],
desired_tag_data[v.last][:date])
release_data[v.last] ||= {}
release_data[v.last][:pulls] ||= []
pr_data[pr[:number]] = {
sha: pr[:head][:sha],
merged: pr[:merged_at],
duration: pr[:merged_at] - pr[:created_at],
time_to_release: desired_tag_data[v.last][:date] - pr[:created_at]
}
release_data[v.last][:pulls] << pr_data[pr[:number]]
release_data[v.last][:avg_duration] = release_data[v.last][:pulls].map {|k| k[:duration]}.inject(:+).to_f / release_data[v.last][:pulls].count
release_data[v.last][:avg_ttr] = release_data[v.last][:pulls].map {|k| k[:time_to_release]}.inject(:+).to_f / release_data[v.last][:pulls].count
end
end
end
release_data.each do |version, data|
puts "Version: #{version}"
puts "Total PRs: #{data[:pulls].count}"
puts "Average duration PRs were open: #{days_or_hours(data[:avg_duration])}"
puts "Average creation-to-release of PRs: #{days_or_hours(data[:avg_ttr])}"
puts "------------------------------------------------------"
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment