Skip to content

Instantly share code, notes, and snippets.

@ozeias
Forked from borischerkasky/full_script.rb
Created October 26, 2024 19:35
Show Gist options
  • Save ozeias/2eae6923950a5cebb24351d5da7b3827 to your computer and use it in GitHub Desktop.
Save ozeias/2eae6923950a5cebb24351d5da7b3827 to your computer and use it in GitHub Desktop.
full Github PR statistics script
class TeamPrStatistics
attr_accessor :team, :stats
class Stat
attr_accessor :titles
attr_reader :name
def initialize(name)
@name = name
@titles = []
end
end
def initialize
@team = ['team-member-1','team-member-2']
@owner = 'owner-of-repos'
@repos = ['repo-1', 'repo-2']
@stats = {}
uname = 'your-username'
token = 'your-personal-token' #Create a personal token on github, don't forget to SSO Enable it
@auth = { username: uname, password: token }
@headers = {"User-Agent"=>"Httparty", "Accept"=>"application/vnd.github.mockingbird-preview"}
@until = Time.now.utc - 3.weeks
end
def run_statistics
@repos.each do |repo_name|
statistics_for_repo(repo_name)
end
@stats
end
def statistics_for_repo(repo_name)
puts ">>> Running statistics for repo: #{repo_name} <<<"
url = "https://api.github.com/repos/#{@owner}/#{repo_name}/pulls?per_page=100&state=all"
loop do
return @stats if url.blank?
puts "*** fetching #{url}"
res = HTTParty.get(url, basic_auth: @auth, headers: @headers)
bodies = JSON.parse(res.body)
puts "got #{bodies.size} prs..."
done = count_prs(bodies, repo_name)
return @stats if done
url = get_next_page(res)
end
end
private
def get_next_page(res)
res.headers['link']&.split(',')&.select{|x| x.include? 'next'}&.first&.split(';')&.first&.gsub(/[ ><]/,'')
end
def count_prs(current_pr_bodies, repo_name)
current_pr_bodies.each do |pr|
next unless author_in_team? pr['user']['login']
return true if too_old? pr['created_at']
reviewers = get_reviewers(pr['number'], repo_name)
count_reviewers(pr['title'], reviewers)
end
false
end
def get_reviewers(pr_number, repo)
reviewers = []
url = "https://api.github.com/repos/#{@owner}/#{repo}/issues/#{pr_number}/timeline"
puts "getting reviewers for: #{url}"
res = HTTParty.get(url, basic_auth: @auth, headers: @headers)
bodies = JSON.parse(res.body)
review_requested_event = bodies.select {|x| x['event'] == 'review_requested'}
review_requested_event.each do |event|
reviewers << event['requested_reviewer']['login']
end
reviewers.uniq
end
def too_old?(created_at_raw)
created_at = Time.parse(created_at_raw)
created_at < @until
end
def count_reviewers(title, reviewers)
reviewers.each do |reviewer|
@stats[reviewer] = Stat.new(reviewer) if @stats[reviewer].blank?
@stats[reviewer].titles << title
end
end
def author_in_team?(author)
@team.include? author
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment