Skip to content

ci: replace the deprecated stale app with actions/stale - #5306

Merged
ReneWerner87 merged 2 commits into
masterfrom
claude/migrate-stale-action
Aug 1, 2026
Merged

ci: replace the deprecated stale app with actions/stale#5306
ReneWerner87 merged 2 commits into
masterfrom
claude/migrate-stale-action

Conversation

@ReneWerner87

@ReneWerner87 ReneWerner87 commented Aug 1, 2026

Copy link
Copy Markdown
Member

The problem

.github/stale.yml configures the probot/stale GitHub App, which states on its own repository:

The stale app is deprecated and this repository is no longer maintained.

Upstream points users at actions/stale instead.

The substantive issue is one line in that config:

staleLabel: wontfix

wontfix reads 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 wontfix label 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 how gobuild.yml and codeql.yml pin actions. .github/stale.yml is removed.

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.

Beyond the migration:

  • stale-issue-label / stale-pr-label are now stale rather than wontfix
  • exempt-all-assignees: true so anything somebody has picked up is not closed for inactivity. The old app had no equivalent option.
  • bot and maintainer authored items are skipped, see below

Skipping bots and maintainers

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). 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:

Category Signal
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 names like "copilot, gemini, coderabbitai" would miss whatever is added next.

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.

One caveat worth stating

exempt-all-assignees already 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 wontfix label has already been removed from #2704, #2705, #2706 and #2718, since changing the config does not clear it retroactively.

Verification

.github/workflows/stale.yml parses as valid YAML with both steps in the right order, and the embedded script parses as valid JavaScript. Every input name used was checked against action.yml at the pinned tag rather than assumed, since GitHub Actions silently ignores unknown with: keys.

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.
Copilot AI review requested due to automatic review settings August 1, 2026 12:26

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 wontfix stale label with stale and keep exemptions for pinned and security plus “exempt if assigned”.
  • Remove the obsolete .github/stale.yml config 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.

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.
Copilot AI review requested due to automatic review settings August 1, 2026 12:46

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 no stale label. actions/stale does not create missing labels (it only calls issues.addLabels), so runs will log “Error when adding a label” and items may never become stale/close as intended. Consider ensuring the stale label exists in the github-script step, similar to how you already create no-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 {

@ReneWerner87
ReneWerner87 merged commit c1ebdd6 into master Aug 1, 2026
10 checks passed
@ReneWerner87
ReneWerner87 deleted the claude/migrate-stale-action branch August 1, 2026 12:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants