Last active
September 27, 2020 14:49
-
-
Save fudanchii/b9d5f57f49feb9b655465c5246cd612f to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require "rubygems" | |
require "bundler" | |
Bundler.require(:default) | |
def find_ref(body) | |
refs = body.split("\n").map do |line| | |
next unless line =~ /https:/ | |
line.gsub(%r{.*(https://[^\s\)">]+).*}, '\1') | |
end | |
.compact | |
.select { |url| !%w(.jpg .jpeg .png .gif).include?(File.extname(url)) } | |
.join("\n") | |
return nil if refs == body | |
refs | |
end | |
def search_query(last_cursor:, predicates:[]) | |
{ | |
variables: { | |
query: predicates.compact.join(" "), | |
cursor: last_cursor, | |
}, | |
query: <<~GQL | |
query search($query: String!, $cursor: String) { | |
search(query: $query, type: ISSUE, first: 100, after: $cursor) { | |
nodes { | |
...pullRequestFragment | |
} | |
pageInfo { | |
hasNextPage | |
endCursor | |
} | |
} | |
} | |
fragment pullRequestFragment on PullRequest { | |
author { login } | |
title | |
body | |
createdAt | |
url | |
state | |
} | |
GQL | |
} | |
end | |
def search_by_author(cursor:, since:, org:, repo:, login:) | |
query = search_query( | |
last_cursor: cursor, | |
predicates: [ | |
"is:pr", | |
"created:>=#{since}", | |
"author:#{login}", | |
"org:#{org}", | |
"repo:#{repo}" | |
] | |
).to_json | |
gh_client.post("/graphql", query) | |
end | |
def author(since:, org:, repo:, member_logins:) | |
nodes = [] | |
member_logins.each do |login| | |
has_next = true | |
cursor = nil | |
while has_next | |
puts "querying PRs created by: #{login}" | |
response = search_by_author(cursor: cursor, since: since, org: org, repo: repo, login: login) | |
response = response[:data][:search] | |
nodes += response[:nodes] | |
has_next = response[:pageInfo][:hasNextPage] | |
cursor = response[:pageInfo][:endCursor] | |
end | |
sleep(2) | |
end | |
nodes | |
end | |
def scan_author(since:, org:, repo:, member_logins:) | |
nodes = author(since: since, org: org, repo: repo, member_logins: member_logins) | |
CSV.open(ENV.fetch("CSV_FILENAME", "author_org-#{org}_since-#{since}.csv"), "wb") do |csv| | |
csv << %w(created status author title url ref) | |
nodes.each do |node| | |
date = Date.parse(node[:createdAt]).iso8601 rescue nil | |
login = node[:author][:login] rescue node[:author] | |
title = node[:title] | |
ref = find_ref(node[:body] || '') | |
url = node[:url] | |
status = node[:state] | |
csv << [date, status, login, title, url, ref] | |
end | |
end | |
end | |
def search_by_reviewer(cursor:, since:, org:, repo:, login:) | |
query = search_query( | |
last_cursor: cursor, | |
predicates: [ | |
"is:pr", | |
"created:>=#{since}", | |
"reviewed-by:#{login}", | |
"org:#{org}", | |
"repo:#{repo}" | |
] | |
).to_json | |
gh_client.post("/graphql", query) | |
end | |
def reviewer(since:, org:, repo:, member_logins:) | |
nodes = [] | |
member_logins.each do |login| | |
has_next = true | |
cursor = nil | |
while has_next | |
puts "querying PRs reviewed by: #{login}" | |
response = search_by_reviewer(cursor: cursor, since: since, org: org, repo: repo, login: login) | |
response = response[:data][:search] | |
nodes += response[:nodes].map { |node| node[:reviewer] = login; node } | |
has_next = response[:pageInfo][:hasNextPage] | |
cursor = response[:pageInfo][:endCursor] | |
end | |
sleep(2) | |
end | |
nodes | |
end | |
def scan_reviewer(since:, org:, repo:, member_logins:) | |
nodes = reviewer(since: since, org: org, repo: repo, member_logins: member_logins) | |
CSV.open(ENV.fetch("CSV_FILENAME", "reviewer_org-#{org}_since-#{since}.csv"), "wb") do |csv| | |
csv << %w(created status reviewer title url ref) | |
nodes.each do |node| | |
date = Date.parse(node[:createdAt]).iso8601 rescue nil | |
login = node[:reviewer] | |
title = node[:title] | |
ref = find_ref(node[:body] || '') | |
url = node[:url] | |
status = node[:state] | |
csv << [date, status, login, title, url, ref] | |
end | |
end | |
end | |
def gh_client | |
@gh_client ||= Octokit::Client.new(access_token: ENV["GITHUB_TOKEN"]) | |
end | |
logins = ENV["GITHUB_LOGINS"].split(",") | |
if ENV["USE_GITHUB_TEAM"] == "true" | |
team_id = ENV.fetch("GITHUB_TEAM_ID", 2265354) | |
logins = gh_client.team_members(team_id).map(&:login) | |
end | |
scan_author(since: "2020-03-16", org: "quipper", repo: "quipper/monorepo-global", member_logins: logins) | |
scan_reviewer(since: "2020-03-16", org: "quipper", repo: "quipper/monorepo-global", member_logins: logins) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment