diff --git a/.github/workflows/stale_pr_close.yml b/.github/workflows/stale_pr_close.yml new file mode 100644 index 000000000..df62a6f8e --- /dev/null +++ b/.github/workflows/stale_pr_close.yml @@ -0,0 +1,89 @@ +name: Stale PR Management + +on: + schedule: + # Runs daily at midnight UTC + - cron: "0 0 * * *" + pull_request: + types: + - labeled + +jobs: + stale-prs: + runs-on: ubuntu-latest + steps: + - name: Handle stale label + uses: actions/github-script@v7 + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + script: | + const now = new Date(); + const owner = context.repo.owner; + const repo = context.repo.repo; + + // Handle when PR is labeled + if (context.eventName === "pull_request" && context.payload.action === "labeled") { + const label = context.payload.label?.name; + if (label === "stale") { + await github.issues.createComment({ + owner, + repo, + issue_number: context.payload.pull_request.number, + body: "This PR has been marked as stale. It will be closed if no new commits are added in 7 days." + }); + } + return; + } + + // Scheduled run: fetch all open PRs + const { data: prs } = await github.pulls.list({ + owner, + repo, + state: "open", + per_page: 100 + }); + + for (const pr of prs) { + const hasStale = pr.labels.some(l => l.name === "stale"); + if (!hasStale) continue; + + // Fetch commits for this PR + const { data: commits } = await github.pulls.listCommits({ + owner, + repo, + pull_number: pr.number + }); + + const lastCommitDate = new Date(commits[commits.length - 1].commit.author.date); + const diffDays = (now - lastCommitDate) / (1000 * 60 * 60 * 24); + + if (diffDays > 7) { + // Close stale PR + await github.pulls.update({ + owner, + repo, + pull_number: pr.number, + state: "closed" + }); + await github.issues.createComment({ + owner, + repo, + issue_number: pr.number, + body: "Closing stale PR due to inactivity." + }); + } else if (lastCommitDate > new Date(now - 7*24*60*60*1000)) { + // Remove stale label if recent activity + await github.issues.removeLabel({ + owner, + repo, + issue_number: pr.number, + name: "stale" + }); + await github.issues.createComment({ + owner, + repo, + issue_number: pr.number, + body: "Recent activity detected. Removing stale label." + }); + } + }