Skip to content

Process stale issues and PRs #383

Process stale issues and PRs

Process stale issues and PRs #383

Workflow file for this run

name: 'Process stale issues and PRs'
on:
schedule:
- cron: '21 0 * * *'
workflow_dispatch:
pull_request:
types: [converted_to_draft]
permissions: {}
jobs:
stale:
runs-on: ubuntu-latest
permissions:
contents: write
issues: write
pull-requests: write
if: github.event_name == 'schedule' || github.event_name == 'workflow_dispatch'
steps:
- name: Process stale issues and PRs
uses: actions/stale@v9.0.0
with:
repo-token: ${{ secrets.GITHUB_TOKEN }}
stale-issue-message: "As a part of this repository's maintenance, this issue is being marked as stale due to inactivity. Please feel free to comment on it in case we missed something.\n\n###### After 7 days with no activity this issue will be automatically closed."
close-issue-message: 'This issue was closed because it has been 14 days with no activity.'
operations-per-run: 140
days-before-stale: -1
days-before-close: -1
days-before-issue-stale: 7
days-before-issue-close: 7
stale-issue-label: 'status: stale'
exempt-issue-labels: 'type: enhancement'
only-issue-labels: 'needs: author feedback'
close-issue-label: "status: can't reproduce"
days-before-pr-stale: 30
days-before-pr-close: 14
stale-pr-label: 'status: stale'
only-pr-labels: 'needs: author feedback'
stale-pr-message: "As a part of this repository's maintenance, this PR is being marked as stale due to inactivity. Please feel free to comment on it in case we missed something.\n\n###### After 14 days with no activity this PR will be automatically closed."
close-pr-message: 'This PR was closed because it has been 1.5 months with no activity.'
delete-branch: true
ascending: true
- name: Process stale flaky tests issues
uses: actions/stale@v9.0.0
with:
repo-token: ${{ secrets.GITHUB_TOKEN }}
only-issue-labels: 'metric: flaky e2e test'
exempt-issue-labels: 'type: skipped test'
days-before-stale: -1
days-before-close: -1
days-before-issue-stale: 5
days-before-issue-close: 2
stale-issue-label: 'status: stale'
stale-issue-message: 'This issue is being marked as stale due to inactivity. It will be auto-closed if no further activity occurs within the next 2 days.'
close-issue-message: 'Auto-closed due to inactivity. Please re-open if you believe this issue is still valid.'
close-issue-reason: 'not_planned'
remove-stale-when-updated: true
exempt-all-assignees: false
enable-statistics: true
ascending: true
operations-per-run: 120
- name: Remove stale PR approvals (over 30 days old)
uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea #v7.0.1
with:
script: |
const thirtyDaysAgo = new Date();
thirtyDaysAgo.setDate(thirtyDaysAgo.getDate() - 30);
console.log(`Checking for approvals before: ${thirtyDaysAgo.toISOString()}`);
const prs = await github.paginate(github.rest.pulls.list, {
owner: context.repo.owner,
repo: context.repo.repo,
state: 'open',
per_page: 100
});
for (const pr of prs) {
const reviews = await github.paginate(github.rest.pulls.listReviews, {
owner: context.repo.owner,
repo: context.repo.repo,
pull_number: pr.number
});
// Find the latest approval date for this PR
let latestApproval = null;
const approvalReviews = [];
for (const review of reviews) {
if (review.state === 'APPROVED') {
const reviewDate = new Date(review.submitted_at);
approvalReviews.push(review);
if (!latestApproval || reviewDate > latestApproval) {
latestApproval = reviewDate;
}
}
}
// Process only if we found any approvals
if (latestApproval) {
console.log(`PR #${pr.number} latest approval on ${latestApproval.toISOString()}`);
if (latestApproval < thirtyDaysAgo) {
console.log(`Found ${approvalReviews.length} approvals to dismiss on PR #${pr.number} (latest approval was on ${latestApproval.toISOString()})`);
// Dismiss all approvals
for (const review of approvalReviews) {
console.log(`Dismissing approval from ${review.user.login}`);
await github.rest.pulls.dismissReview({
owner: context.repo.owner,
repo: context.repo.repo,
pull_number: pr.number,
review_id: review.id,
message: 'This approval has been dismissed due to being stale (latest PR approval was 30+ days old). Please request a new review.'
});
}
} else {
console.log(`Keeping approvals on PR #${pr.number} (latest approval on ${latestApproval.toISOString()})`);
}
}
}
remove-draft-approvals:
runs-on: ubuntu-latest
permissions:
pull-requests: write
if: github.event_name == 'pull_request' && github.event.action == 'converted_to_draft'
steps:
- name: Remove approvals from draft PR
uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea #v7.0.1
with:
script: |
const pr = context.payload.pull_request;
const reviews = await github.paginate(github.rest.pulls.listReviews, {
owner: context.repo.owner,
repo: context.repo.repo,
pull_number: pr.number
});
for (const review of reviews) {
if (review.state === 'APPROVED') {
console.log(`Dismissing approval on draft PR #${pr.number} from ${review.user.login}`);
await github.rest.pulls.dismissReview({
owner: context.repo.owner,
repo: context.repo.repo,
pull_number: pr.number,
review_id: review.id,
message: 'This approval has been dismissed due to the PR being moved to draft status. Please request a new review when ready.'
});
}
}