Created
February 21, 2022 20:37
-
-
Save LunaticMuch/40061e49c4982683eb009b4335db21c7 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
# The origin of this script is https://gist.github.com/iambchan/273219729eb88155e11672c4ccac72b3 | |
# as linked in the blog post https://building.kickstarter.com/how-to-konmari-your-git-repo-474907a29d2e | |
# I applied two changes: a fix for cursor loop and add multiple dates for the PR for better reporting | |
require 'http' | |
require 'date' | |
REPOSITORY_OWNER = "" | |
REPOSITORY_NAME = "" | |
REFS_PREFIX = "refs/heads/" | |
GITHUB_AUTH_TOKEN = "" | |
# Simple request to the Github Graphql api | |
def self.perform_request(auth_token:, graphql:) | |
response = HTTP | |
.auth("Bearer #{auth_token}") | |
.post( | |
"https://api.github.com/graphql", | |
body: { query: graphql }.to_json | |
) | |
unless response.code == 200 | |
raise response.inspect | |
end | |
JSON.parse(response.body) | |
end | |
# Gets first 100 branches and associated pull requests | |
# Takes a cursor for paging | |
def self.pull_requests(token:, repository:, owner:, cursor: nil) | |
query = <<~GRAPHQL | |
query { | |
repository(name: "#{repository}", owner: "#{owner}") { | |
refs(refPrefix: "refs/heads/", first: 100 #{", after: \"#{cursor}\"" if cursor}) { | |
edges { | |
cursor | |
node { | |
name | |
target { | |
oid | |
} | |
associatedPullRequests(last: 100) { | |
edges { | |
node { | |
number | |
publishedAt | |
updatedAt | |
closedAt | |
state | |
isDraft | |
changedFiles | |
mergeable | |
author{ | |
login | |
} | |
} | |
} | |
} | |
} | |
} | |
} | |
} | |
} | |
GRAPHQL | |
data = perform_request(auth_token: token, graphql: query) | |
edges = data.dig("data", "repository", "refs", "edges") | |
raise data.inspect if edges.nil? | |
# For each branch output: date, branch name, author, pull request state, todo | |
# todo is set to 'DELETE' if state of the PR is merged, deleted, | |
# or older than 3 months ago (hard coded to before Sept 1, 2018) | |
edges.map do |edge| | |
branch = edge.fetch("node") | |
date = Time.at(`git show #{branch.dig("target", "oid")} --format="format:%at" | head -n 1`.to_i).to_date | |
pr = (branch.dig("associatedPullRequests", "edges").first || {})["node"] || {} | |
publishedAt = pr.dig("publishedAt") ? DateTime.iso8601(pr.dig("publishedAt")).to_date : "" | |
closedAt = pr.dig("closedAt") ? DateTime.iso8601(pr.dig("publishedAt")).to_date : "" | |
updatedAt = pr.dig("updatedAt") ? DateTime.iso8601(pr.dig("publishedAt")).to_date : "" | |
# Very naive implementation for setting the `todo` column | |
todo = "" | |
todo = "DELETE" if pr["state"] == "MERGED" | |
todo = "DELETE" if pr["state"] == "CLOSED" | |
todo = "DELETE" if date < Date.new(2018, 9, 1) | |
todo = "" if pr["state"] == "OPEN" | |
todo = "" if branch["name"].start_with?("hd") # hackday | |
todo = "" if branch["name"] == "master" | |
puts [ | |
date, | |
branch["name"], | |
pr.dig("number"), | |
publishedAt, | |
updatedAt, | |
closedAt, | |
pr.dig("state"), | |
pr.dig("isDraft"), | |
pr.dig("changedFiles"), | |
pr.dig("mergeable"), | |
pr.dig("author", "login"), | |
pr.dig("state"), | |
todo | |
].join(",") | |
end | |
exit if edges.size < 100 | |
cursor = edges.last["cursor"] | |
end | |
# Process refs in batches of 100. | |
cursor = nil | |
loop do | |
cursor = pull_requests(token: GITHUB_AUTH_TOKEN, repository: REPOSITORY_NAME, owner: REPOSITORY_OWNER, cursor: cursor) | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment