fix: exempt team members from compliance cleanup

This commit is contained in:
Aiden Cline 2026-05-21 16:15:45 -05:00 committed by GitHub
parent 39e7ff932d
commit 1268f8657e
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 56 additions and 31 deletions

View file

@ -15,8 +15,11 @@ const cutoff = new Date(Date.now() - days * 24 * 60 * 60 * 1000)
type Issue = {
number: number
updated_at: string
author_association: string
}
const teamAssociations = new Set(["OWNER", "MEMBER", "COLLABORATOR"])
const headers = {
Authorization: `Bearer ${token}`,
"Content-Type": "application/json",
@ -63,6 +66,10 @@ async function main() {
for (const i of all) {
const updated = new Date(i.updated_at)
if (updated < cutoff) {
if (teamAssociations.has(i.author_association)) {
console.log(`Skipping #${i.number}: author association is ${i.author_association}`)
continue
}
stale.push(i.number)
} else {
console.log(`\nFound fresh issue #${i.number}, stopping`)

View file

@ -69,6 +69,7 @@ const maxClose =
const sleepMs = requireNonNegativeInteger("sleep-ms", values["sleep-ms"])
const printLimit = requireNonNegativeInteger("print-limit", values["print-limit"])
const cutoff = subtractMonths(new Date(), ageMonths)
const teamAssociations = new Set(["OWNER", "MEMBER", "COLLABORATOR"])
const headers = {
Authorization: `Bearer ${token}`,
@ -82,6 +83,7 @@ type PullRequest = {
title: string
url: string
createdAt: string
authorAssociation: string
reactionGroups: Array<{
content: string
users: {
@ -145,19 +147,25 @@ async function main() {
console.log(`Threshold: fewer than ${threshold} positive reactions`)
const prs = await fetchOpenPullRequests()
const recentCount = prs.filter((pr) => new Date(pr.createdAt) >= cutoff).length
const matching = prs
.map((pr) => ({ ...pr, positiveReactions: positiveReactionCount(pr) }))
.filter((pr) => new Date(pr.createdAt) < cutoff && pr.positiveReactions < threshold)
const scored = prs.map((pr) => ({ ...pr, positiveReactions: positiveReactionCount(pr) }))
const recentCount = scored.filter((pr) => new Date(pr.createdAt) >= cutoff).length
const teamCount = scored.filter((pr) => isTeamMember(pr)).length
const matching = scored.filter(
(pr) => !isTeamMember(pr) && new Date(pr.createdAt) < cutoff && pr.positiveReactions < threshold,
)
const candidates = matching.filter((pr) => !hasPriorCleanup(pr))
const selected = maxClose === undefined ? candidates : candidates.slice(0, maxClose)
console.log(`Fetched ${prs.length} open PRs`)
console.log(`Matching cleanup criteria: ${matching.length}`)
console.log(`Skipped previously cleaned PRs: ${matching.length - candidates.length}`)
console.log(`Team member PRs untouched: ${teamCount}`)
console.log(`Recent PRs untouched: ${recentCount}`)
console.log(
`Older PRs with at least ${threshold} positive reactions untouched: ${prs.length - matching.length - recentCount}`,
`Older PRs with at least ${threshold} positive reactions untouched: ${
scored.filter((pr) => !isTeamMember(pr) && new Date(pr.createdAt) < cutoff && pr.positiveReactions >= threshold)
.length
}`,
)
if (selected.length === 0) return
@ -205,6 +213,7 @@ async function fetchOpenPullRequests() {
title
url
createdAt
authorAssociation
reactionGroups {
content
users {
@ -335,6 +344,10 @@ function hasPriorCleanup(pr: PullRequest) {
return pr.labels.nodes.some((label) => label.name === cleanupLabel)
}
function isTeamMember(pr: PullRequest) {
return teamAssociations.has(pr.authorAssociation)
}
function requireRepo(value: string | undefined) {
if (!value) throw new Error("repo is required")
const [owner, name] = value.split("/")