ci: replace the deprecated stale app with actions/stale - #5306
Merged
Conversation
The probot/stale GitHub App configured through .github/stale.yml is
deprecated. Its repository states it is no longer maintained and points
users at actions/stale instead. This migrates to the action, pinned to
v11.0.0 by commit SHA to match how the other workflows here pin actions.
The substantive change is the stale label. The old config used:
staleLabel: wontfix
`wontfix` reads as a maintainer decision not to act, while the bot only
means "no activity for 60 days". Conflating the two made several reports
that no human had ever answered look declined. #2718 is the clearest
case: a valid bug report, five comments, all of them from the welcome and
stale bots, carrying a `wontfix` label nobody chose. #2704, #2705 and
#2706 have the label for the same reason. The action now applies a plain
`stale` label to issues and pull requests.
Also adds `exempt-all-assignees`, so anything somebody has picked up is
not closed for inactivity. That option does not exist in the old app.
Everything else is carried over unchanged: 60 days to stale, 7 more to
close, `pinned` and `security` exempt, and the same wording for the mark
and close comments, split into issue and pull request variants as the
action requires.
Worth stating plainly, since it was the original request: neither the old
app nor the action can exempt by author, so maintainer or bot authored
issues cannot be excluded that way. exempt-authors is an open feature
request upstream (actions/stale#933). Fixing the label addresses the same
problem for every author instead.
There was a problem hiding this comment.
Pull request overview
This PR migrates stale-issue automation from the deprecated probot/stale GitHub App configuration to a first-party scheduled GitHub Actions workflow using actions/stale, keeping the same inactivity thresholds while updating the stale label to a clearer stale.
Changes:
- Add a scheduled + manually triggerable workflow that marks and closes stale issues/PRs via
actions/stale(pinned by SHA). - Replace the prior
wontfixstale label withstaleand keep exemptions forpinnedandsecurityplus “exempt if assigned”. - Remove the obsolete
.github/stale.ymlconfig that was only used by the deprecated app.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.
| File | Description |
|---|---|
| .github/workflows/stale.yml | Introduces scheduled actions/stale workflow to mark/close inactive issues and PRs with updated labeling and messages. |
| .github/stale.yml | Removes deprecated probot/stale app configuration file. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
This was referenced Aug 1, 2026
actions/stale cannot exempt by author. Its exemptions are labels, assignees, milestones and projects, and exempt-authors is a long-open request upstream (actions/stale#933). The action is only a step though, so a step before it can label the authors we want skipped, which the action then exempts through exempt-issue-labels and exempt-pr-labels. Both signals come from the API rather than a hardcoded list of account names, so a new bot or a new maintainer is covered without touching this file: bots user.type == "Bot", or login ending in [bot] maintainers author_association of OWNER, MEMBER or COLLABORATOR The two are checked independently on purpose. coderabbitai[bot] reports author_association CONTRIBUTOR, so association alone would not identify bots, and matching on account names would miss any bot added later. listForRepo covers pull requests as well as issues. Items already carrying the label are skipped, and the label is created on first run since addLabels does not create missing ones. Worth noting what this does not change: exempt-all-assignees already covered anything a maintainer had picked up, which is the stronger signal. Issue #2707 qualifies today through its assignee alone. This adds the weaker "was opened by" case on top, as requested.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 2 out of 2 changed files in this pull request and generated no new comments.
Suppressed comments (1)
.github/workflows/stale.yml:55
- The workflow introduces
stale-issue-label: stale/stale-pr-label: stale, but this repo currently has nostalelabel.actions/staledoes not create missing labels (it only callsissues.addLabels), so runs will log “Error when adding a label” and items may never become stale/close as intended. Consider ensuring thestalelabel exists in the github-script step, similar to how you already createno-auto-stale.
const EXEMPT = 'no-auto-stale'
const MAINTAINER = new Set(['OWNER', 'MEMBER', 'COLLABORATOR'])
// addLabels does not create missing labels, so make sure it exists.
try {
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The problem
.github/stale.ymlconfigures the probot/stale GitHub App, which states on its own repository:Upstream points users at actions/stale instead.
The substantive issue is one line in that config:
wontfixreads as a maintainer decision not to act. The bot only means "no activity for 60 days". Conflating the two made several reports that no human had ever answered look declined.#2718 is the clearest case: a valid bug report about missing database timeouts, five comments, all five from the welcome and stale bots, carrying a
wontfixlabel nobody chose. I nearly skipped it on that basis before checking where the label came from. #2704, #2705 and #2706 carried it for the same reason.Changes
Migrates to
actions/stale, pinned to v11.0.0 by commit SHA to match howgobuild.ymlandcodeql.ymlpin actions..github/stale.ymlis removed.Carried over unchanged: 60 days to stale, 7 more to close,
pinnedandsecurityexempt, and the same wording for the mark and close comments, split into issue and pull request variants as the action requires.Beyond the migration:
stale-issue-label/stale-pr-labelare nowstalerather thanwontfixexempt-all-assignees: trueso anything somebody has picked up is not closed for inactivity. The old app had no equivalent option.Skipping bots and maintainers
actions/stalecannot exempt by author. Its exemptions are labels, assignees, milestones and projects, andexempt-authorsis a long-open request upstream (actions/stale#933). Same for the old app.The action is only a step, though. A step before it labels the authors we want skipped, and the action exempts that label. Both signals come from the API rather than a hardcoded list of account names, so a bot or maintainer added later is covered without editing this file:
user.type == "Bot", or login ending in[bot]author_associationofOWNER,MEMBERorCOLLABORATORThe two are checked independently on purpose.
coderabbitai[bot]reportsauthor_association: CONTRIBUTOR, so association alone would not identify bots, and matching on names like "copilot, gemini, coderabbitai" would miss whatever is added next.listForRepocovers pull requests as well as issues. Items already carrying the label are skipped, and the label is created on first run sinceaddLabelsdoes not create missing ones.One caveat worth stating
exempt-all-assigneesalready covered anything a maintainer had picked up, which is the stronger signal. #2707 qualifies today through its assignee alone. The author check adds the weaker "was opened by" case on top.The trade-off: an issue a maintainer opened and then forgot is exactly the kind the bot would rightly resurface, and it will now stay quiet instead. Deliberate, but worth knowing.
Follow-up
The
wontfixlabel has already been removed from #2704, #2705, #2706 and #2718, since changing the config does not clear it retroactively.Verification
.github/workflows/stale.ymlparses as valid YAML with both steps in the right order, and the embedded script parses as valid JavaScript. Every input name used was checked againstaction.ymlat the pinned tag rather than assumed, since GitHub Actions silently ignores unknownwith:keys.