Stale Bot workflow (gatsbyjs/gatsby)
The Stale Bot workflow from gatsbyjs/gatsby, explained and optimized by Latchkey.
CI health: B - good
Point runs-on at Latchkey and get job timeouts, SHA-pinned actions, self-healing for flaky steps, and up to 58% lower cost, applied automatically.
What it does
This is the Stale Bot workflow from the gatsbyjs/gatsby repository, a real project running GitHub Actions. It is shown here with attribution under its MIT license.
Below, Latchkey shows a faster, safer version produced by its optimization engine.
The workflow
name: Stale Bot
on:
schedule:
- cron: "0 */12 * * *"
permissions:
contents: read
jobs:
stale:
permissions:
contents: read
issues: write
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- uses: actions/stale@v10
name: stale
id: stale
with:
days-before-stale: 20
days-before-pr-stale: -1 # Don't mark PRs as stale
days-before-close: 40
exempt-all-assignees: true
operations-per-run: 1000
stale-issue-message: |
Hiya!
This issue has gone quiet. Spooky quiet. 👻
We get a lot of issues, so we currently close issues after 60 days of inactivity. It’s been at least 20 days since the last update here.
If we missed this issue or if you want to keep it open, please reply here.
As a friendly reminder: the best way to see this issue, or any other, fixed is to open a Pull Request. Check out [gatsby.dev/contribute](https://www.gatsbyjs.com/contributing#how-to-contribute) for more information about opening PRs, triaging issues, and contributing!
Thanks for being a part of the Gatsby community! 💪💜
close-issue-message: |
Hey again!
It’s been 60 days since anything happened on this issue, so our friendly neighborhood robot (that’s me!) is going to close it.
Please keep in mind that I’m only a robot, so if I’ve closed this issue in error, I’m `HUMAN_EMOTION_SORRY`. Please feel free to comment on this issue or create a new one if you need anything else.
As a friendly reminder: the best way to see this issue, or any other, fixed is to open a Pull Request. Check out [gatsby.dev/contribute](https://www.gatsbyjs.com/contributing#how-to-contribute) for more information about opening PRs, triaging issues, and contributing!
Thanks again for being part of the Gatsby community! 💪💜
stale-issue-label: "stale?"
exempt-issue-labels: "not stale,status: triage needed,status: confirmed"
- name: Format Stale Output
id: format-stale-output
uses: ./.github/actions/format-stale-output
with:
staled-issues-prs: ${{ steps.stale.outputs.staled-issues-prs }}
closed-issues-prs: ${{ steps.stale.outputs.closed-issues-prs }}
- name: Slack Report Closed Issues
uses: pullreminders/slack-action@master
env:
SLACK_BOT_TOKEN: ${{ secrets.SLACK_TOKEN }}
with:
args: '{\"channel\": \"${{ secrets.SLACK_STALE_CHANNEL_ID }}\", \"text\": \"\", \"blocks\": ${{ steps.format-stale-output.outputs.blocks }} }'
The same workflow, on Latchkey
Removes redundant runs and caps runaway jobs. Added and changed lines are highlighted.
name: Stale Bot on: schedule: - cron: "0 */12 * * *" permissions: contents: read jobs: stale: timeout-minutes: 30 permissions: contents: read issues: write runs-on: latchkey-small steps: - uses: actions/checkout@v6 - uses: actions/stale@v10 name: stale id: stale with: days-before-stale: 20 days-before-pr-stale: -1 # Don't mark PRs as stale days-before-close: 40 exempt-all-assignees: true operations-per-run: 1000 stale-issue-message: | Hiya! This issue has gone quiet. Spooky quiet. 👻 We get a lot of issues, so we currently close issues after 60 days of inactivity. It’s been at least 20 days since the last update here. If we missed this issue or if you want to keep it open, please reply here. As a friendly reminder: the best way to see this issue, or any other, fixed is to open a Pull Request. Check out [gatsby.dev/contribute](https://www.gatsbyjs.com/contributing#how-to-contribute) for more information about opening PRs, triaging issues, and contributing! Thanks for being a part of the Gatsby community! 💪💜 close-issue-message: | Hey again! It’s been 60 days since anything happened on this issue, so our friendly neighborhood robot (that’s me!) is going to close it. Please keep in mind that I’m only a robot, so if I’ve closed this issue in error, I’m `HUMAN_EMOTION_SORRY`. Please feel free to comment on this issue or create a new one if you need anything else. As a friendly reminder: the best way to see this issue, or any other, fixed is to open a Pull Request. Check out [gatsby.dev/contribute](https://www.gatsbyjs.com/contributing#how-to-contribute) for more information about opening PRs, triaging issues, and contributing! Thanks again for being part of the Gatsby community! 💪💜 stale-issue-label: "stale?" exempt-issue-labels: "not stale,status: triage needed,status: confirmed" - name: Format Stale Output id: format-stale-output uses: ./.github/actions/format-stale-output with: staled-issues-prs: ${{ steps.stale.outputs.staled-issues-prs }} closed-issues-prs: ${{ steps.stale.outputs.closed-issues-prs }} - name: Slack Report Closed Issues uses: pullreminders/slack-action@master env: SLACK_BOT_TOKEN: ${{ secrets.SLACK_TOKEN }} with: args: '{\"channel\": \"${{ secrets.SLACK_STALE_CHANNEL_ID }}\", \"text\": \"\", \"blocks\": ${{ steps.format-stale-output.outputs.blocks }} }'
What changed
- Run on Latchkey managed runners with one line (
runs-on), which apply the fixes below automatically and self-heal transient failures. This example useslatchkey-small; pick the runner size that fits the job. - Add a job timeout so a hung step cannot burn hours of runner time.
1 third-party action is referenced by a movable tag. Pin it to the commit SHA (Latchkey resolves and applies this automatically) so a repointed tag cannot change what runs.
This workflow runs 1 job per trigger. On Latchkey the same minutes cost up to 58% less than GitHub-hosted, with zero queue time.