summaryrefslogtreecommitdiffhomepage
path: root/.github/workflows
diff options
context:
space:
mode:
Diffstat (limited to '.github/workflows')
-rw-r--r--.github/workflows/close-stale-prs.yml94
1 files changed, 76 insertions, 18 deletions
diff --git a/.github/workflows/close-stale-prs.yml b/.github/workflows/close-stale-prs.yml
index cb5c45063..e1ff4241c 100644
--- a/.github/workflows/close-stale-prs.yml
+++ b/.github/workflows/close-stale-prs.yml
@@ -28,40 +28,98 @@ jobs:
const cutoff = new Date(Date.now() - DAYS_INACTIVE * 24 * 60 * 60 * 1000)
const { owner, repo } = context.repo
const dryRun = context.payload.inputs?.dryRun === "true"
- const stalePrs = []
core.info(`Dry run mode: ${dryRun}`)
+ core.info(`Cutoff date: ${cutoff.toISOString()}`)
- const prs = await github.paginate(github.rest.pulls.list, {
- owner,
- repo,
- state: "open",
- per_page: 100,
- sort: "updated",
- direction: "asc",
- })
-
- for (const pr of prs) {
- const lastUpdated = new Date(pr.updated_at)
- if (lastUpdated > cutoff) {
- core.info(`PR ${pr.number} is fresh`)
- continue
+ const query = `
+ query($owner: String!, $repo: String!, $cursor: String) {
+ repository(owner: $owner, name: $repo) {
+ pullRequests(first: 100, states: OPEN, after: $cursor) {
+ pageInfo {
+ hasNextPage
+ endCursor
+ }
+ nodes {
+ number
+ title
+ author {
+ login
+ }
+ createdAt
+ commits(last: 1) {
+ nodes {
+ commit {
+ committedDate
+ }
+ }
+ }
+ comments(last: 1) {
+ nodes {
+ createdAt
+ }
+ }
+ reviews(last: 1) {
+ nodes {
+ createdAt
+ }
+ }
+ }
+ }
+ }
}
+ `
+
+ const allPrs = []
+ let cursor = null
+ let hasNextPage = true
+
+ while (hasNextPage) {
+ const result = await github.graphql(query, {
+ owner,
+ repo,
+ cursor,
+ })
- stalePrs.push(pr)
+ allPrs.push(...result.repository.pullRequests.nodes)
+ hasNextPage = result.repository.pullRequests.pageInfo.hasNextPage
+ cursor = result.repository.pullRequests.pageInfo.endCursor
}
+ core.info(`Found ${allPrs.length} open pull requests`)
+
+ const stalePrs = allPrs.filter((pr) => {
+ const dates = [
+ new Date(pr.createdAt),
+ pr.commits.nodes[0] ? new Date(pr.commits.nodes[0].commit.committedDate) : null,
+ pr.comments.nodes[0] ? new Date(pr.comments.nodes[0].createdAt) : null,
+ pr.reviews.nodes[0] ? new Date(pr.reviews.nodes[0].createdAt) : null,
+ ].filter((d) => d !== null)
+
+ const lastActivity = dates.sort((a, b) => b.getTime() - a.getTime())[0]
+
+ if (!lastActivity || lastActivity > cutoff) {
+ core.info(`PR #${pr.number} is fresh (last activity: ${lastActivity?.toISOString() || "unknown"})`)
+ return false
+ }
+
+ core.info(`PR #${pr.number} is STALE (last activity: ${lastActivity.toISOString()})`)
+ return true
+ })
+
if (!stalePrs.length) {
core.info("No stale pull requests found.")
return
}
+ core.info(`Found ${stalePrs.length} stale pull requests`)
+
for (const pr of stalePrs) {
const issue_number = pr.number
const closeComment = `Closing this pull request because it has had no updates for more than ${DAYS_INACTIVE} days. If you plan to continue working on it, feel free to reopen or open a new PR.`
if (dryRun) {
- core.info(`[dry-run] Would close PR #${issue_number} from ${pr.user.login}`)
+ core.info(`[dry-run] Would close PR #${issue_number} from ${pr.author.login}: ${pr.title}`)
continue
}
@@ -79,5 +137,5 @@ jobs:
state: "closed",
})
- core.info(`Closed PR #${issue_number} from ${pr.user.login}`)
+ core.info(`Closed PR #${issue_number} from ${pr.author.login}: ${pr.title}`)
}