name: Stale Issue, Branch and Old Workflows Cleanup on: schedule: # Every day at midnight - cron: "0 0 * * *" workflow_dispatch: permissions: contents: read jobs: issues: runs-on: ubuntu-latest permissions: # Needed to close issues. issues: write # Needed to close PRs. pull-requests: write steps: - name: Harden Runner uses: step-security/harden-runner@ec9f2d5744a09debf3a187a3f4f675c53b671911 # v2.13.0 with: egress-policy: audit - name: stale uses: actions/stale@5bef64f19d7facfb25b37b414482c7164d639639 # v9.1.0 with: stale-issue-label: "stale" stale-pr-label: "stale" # days-before-stale: 180 # essentially disabled for now while we work through polish issues days-before-stale: 3650 # Pull Requests become stale more quickly due to merge conflicts. # Also, we promote minimizing WIP. days-before-pr-stale: 7 days-before-pr-close: 3 # We rarely take action in response to the message, so avoid # cluttering the issue and just close the oldies. stale-pr-message: "" stale-issue-message: "" # Upped from 30 since we have a big tracker and was hitting the limit. operations-per-run: 60 # Start with the oldest issues, always. ascending: true - name: "Close old issues labeled likely-no" uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1 with: github-token: ${{ secrets.GITHUB_TOKEN }} script: | const thirtyDaysAgo = new Date(new Date().setDate(new Date().getDate() - 30)); console.log(`Looking for issues labeled with 'likely-no' more than 30 days ago, which is after ${thirtyDaysAgo.toISOString()}`); const issues = await github.rest.issues.listForRepo({ owner: context.repo.owner, repo: context.repo.repo, labels: 'likely-no', state: 'open', }); console.log(`Found ${issues.data.length} open issues labeled with 'likely-no'`); for (const issue of issues.data) { console.log(`Checking issue #${issue.number} created at ${issue.created_at}`); const timeline = await github.rest.issues.listEventsForTimeline({ owner: context.repo.owner, repo: context.repo.repo, issue_number: issue.number, }); const labelEvent = timeline.data.find(event => event.event === 'labeled' && event.label.name === 'likely-no'); if (labelEvent) { console.log(`Issue #${issue.number} was labeled with 'likely-no' at ${labelEvent.created_at}`); if (new Date(labelEvent.created_at) < thirtyDaysAgo) { console.log(`Issue #${issue.number} is older than 30 days with 'likely-no' label, closing issue.`); await github.rest.issues.update({ owner: context.repo.owner, repo: context.repo.repo, issue_number: issue.number, state: 'closed', state_reason: 'not_planned' }); } } else { console.log(`Issue #${issue.number} does not have a 'likely-no' label event in its timeline.`); } } branches: runs-on: ubuntu-latest permissions: # Needed to delete branches. contents: write steps: - name: Harden Runner uses: step-security/harden-runner@ec9f2d5744a09debf3a187a3f4f675c53b671911 # v2.13.0 with: egress-policy: audit - name: Checkout repository uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - name: Run delete-old-branches-action uses: beatlabs/delete-old-branches-action@4eeeb8740ff8b3cb310296ddd6b43c3387734588 # v0.0.11 with: repo_token: ${{ github.token }} date: "6 months ago" dry_run: false delete_tags: false # extra_protected_branch_regex: ^(foo|bar)$ exclude_open_pr_branches: true del_runs: runs-on: ubuntu-latest permissions: # Needed to delete workflow runs. actions: write steps: - name: Harden Runner uses: step-security/harden-runner@ec9f2d5744a09debf3a187a3f4f675c53b671911 # v2.13.0 with: egress-policy: audit - name: Delete PR Cleanup workflow runs uses: Mattraks/delete-workflow-runs@39f0bbed25d76b34de5594dceab824811479e5de # v2.0.6 with: token: ${{ github.token }} repository: ${{ github.repository }} retain_days: 30 keep_minimum_runs: 30 delete_workflow_pattern: pr-cleanup.yaml - name: Delete PR Deploy workflow skipped runs uses: Mattraks/delete-workflow-runs@39f0bbed25d76b34de5594dceab824811479e5de # v2.0.6 with: token: ${{ github.token }} repository: ${{ github.repository }} retain_days: 30 keep_minimum_runs: 30 delete_workflow_pattern: pr-deploy.yaml