chore: import upstream snapshot with attribution
This commit is contained in:
@@ -0,0 +1,112 @@
|
||||
name: Close stale pull requests
|
||||
|
||||
on:
|
||||
schedule:
|
||||
- cron: "17 3 * * *"
|
||||
workflow_dispatch:
|
||||
|
||||
permissions:
|
||||
issues: write
|
||||
pull-requests: write
|
||||
|
||||
jobs:
|
||||
close-stale-pull-requests:
|
||||
if: github.repository == 'anomalyco/models.dev'
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/github-script@v8
|
||||
env:
|
||||
REVIEWER: rekram1-node
|
||||
with:
|
||||
script: |
|
||||
const { owner, repo } = context.repo
|
||||
const now = Date.now()
|
||||
const weekAgo = now - 7 * 24 * 60 * 60 * 1000
|
||||
const monthAgo = now - 30 * 24 * 60 * 60 * 1000
|
||||
|
||||
const pulls = await github.paginate(github.rest.pulls.list, {
|
||||
owner,
|
||||
repo,
|
||||
state: "open",
|
||||
per_page: 100,
|
||||
})
|
||||
|
||||
const feedbackPulls = new Set()
|
||||
for (const qualifier of ["commenter", "reviewed-by"]) {
|
||||
const results = await github.paginate(
|
||||
github.rest.search.issuesAndPullRequests,
|
||||
{
|
||||
q: `repo:${owner}/${repo} is:pr is:open ${qualifier}:${process.env.REVIEWER}`,
|
||||
per_page: 100,
|
||||
},
|
||||
)
|
||||
|
||||
for (const result of results) feedbackPulls.add(result.number)
|
||||
}
|
||||
|
||||
for (const pull of pulls) {
|
||||
let feedbackAt = 0
|
||||
if (feedbackPulls.has(pull.number)) {
|
||||
const [comments, reviews, reviewComments] = await Promise.all([
|
||||
github.paginate(github.rest.issues.listComments, {
|
||||
owner,
|
||||
repo,
|
||||
issue_number: pull.number,
|
||||
per_page: 100,
|
||||
}),
|
||||
github.paginate(github.rest.pulls.listReviews, {
|
||||
owner,
|
||||
repo,
|
||||
pull_number: pull.number,
|
||||
per_page: 100,
|
||||
}),
|
||||
github.paginate(github.rest.pulls.listReviewComments, {
|
||||
owner,
|
||||
repo,
|
||||
pull_number: pull.number,
|
||||
per_page: 100,
|
||||
}),
|
||||
])
|
||||
|
||||
const feedbackTimes = [
|
||||
...comments
|
||||
.filter((comment) => comment.user?.login === process.env.REVIEWER)
|
||||
.map((comment) => Date.parse(comment.updated_at)),
|
||||
...reviews
|
||||
.filter((review) => review.user?.login === process.env.REVIEWER && review.submitted_at)
|
||||
.map((review) => Date.parse(review.submitted_at)),
|
||||
...reviewComments
|
||||
.filter((comment) => comment.user?.login === process.env.REVIEWER)
|
||||
.map((comment) => Date.parse(comment.updated_at)),
|
||||
]
|
||||
feedbackAt = Math.max(0, ...feedbackTimes)
|
||||
}
|
||||
|
||||
// Refetch after loading feedback so activity during this run cannot be missed.
|
||||
const { data: currentPull } = await github.rest.pulls.get({
|
||||
owner,
|
||||
repo,
|
||||
pull_number: pull.number,
|
||||
})
|
||||
const updatedAt = Date.parse(currentPull.updated_at)
|
||||
const monthStale = updatedAt < monthAgo
|
||||
const feedbackStale = feedbackAt > 0 && feedbackAt < weekAgo && updatedAt <= feedbackAt
|
||||
if (!monthStale && !feedbackStale) continue
|
||||
|
||||
const reason = monthStale
|
||||
? "it has not been updated in 30 days"
|
||||
: `it has not been updated since feedback from @${process.env.REVIEWER} was left 7 days ago`
|
||||
|
||||
await github.rest.issues.createComment({
|
||||
owner,
|
||||
repo,
|
||||
issue_number: pull.number,
|
||||
body: `Closing this pull request as stale because ${reason}. Feel free to reopen it or submit a new pull request if the work is resumed.`,
|
||||
})
|
||||
await github.rest.pulls.update({
|
||||
owner,
|
||||
repo,
|
||||
pull_number: pull.number,
|
||||
state: "closed",
|
||||
})
|
||||
}
|
||||
Reference in New Issue
Block a user