Skip to content

Instantly share code, notes, and snippets.

@LunaticMuch
Created February 21, 2022 20:37
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save LunaticMuch/40061e49c4982683eb009b4335db21c7 to your computer and use it in GitHub Desktop.
Save LunaticMuch/40061e49c4982683eb009b4335db21c7 to your computer and use it in GitHub Desktop.
# 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