Tested with Ruby 2.1.4.
Install the Octokit gem.
gem install octokit -v 3.7.0
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 | |
| 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 |