Skip to content

fix(ci): fix mergify stale/close rules that never trigger - #798

Merged
CatherineSue merged 2 commits into
mainfrom
fix/mergify-stale-close-rules
Mar 18, 2026
Merged

CatherineSue merged 2 commits into
mainfrom
fix/mergify-stale-close-rules

Conversation

@CatherineSue

@CatherineSue CatherineSue commented Mar 18, 2026 •

Copy link
Copy Markdown
Member

Description

Problem

The Mergify stale PR rules have three bugs that prevent auto-close from ever firing:

  1. Stale comment resets updated-at: The 14-day stale rule posts a comment, which bumps updated-at. The 30-day close rule checks updated-at < 30 days ago, but the PR was just "updated" by the comment. The cycle repeats every 14 days indefinitely.

  2. Stale label immediately removed: The "remove stale label" rule checks updated-at > 14 days ago, which is true right after the stale comment. Label is added and removed in rapid succession.

  3. updated-at is unreliable: GitHub silently bumps updated-at for invisible events like merge conflict recalculation when main changes. This explains why all old PRs show recent update timestamps despite no real activity for months.

As a result, no open PR has ever received the stale label or been auto-closed.

Solution

Replace Mergify stale/close rules with actions/stale GitHub Action (same approach as vLLM), which correctly tracks activity without being affected by bot comments or internal updated-at recalculations.

Changes

  • .github/mergify.yml: Remove broken stale/close/remove-stale rules, replace with comment pointing to the workflow
  • .github/workflows/stale.yml: New workflow using actions/stale@v10 running daily at 1:30 AM UTC
    • PRs: stale after 14 days, closed after 16 more days (30 total)
    • Issues: stale after 90 days, closed after 30 more days (120 total)
    • Draft PRs and keep-open labeled items are exempt
    • unstale label added/removed for clean state tracking

Test Plan

After merge, monitor over the next few days:

  1. Old inactive PRs should receive the stale label on the next daily run
  2. PRs that remain inactive for 16 more days should be auto-closed
  3. PRs with new commits or comments should have stale label removed

Summary by CodeRabbit

  • Chores
    • Automated inactive issue and pull request management now runs daily (with manual trigger). Issues are marked stale after 90 days and closed after 30 days; pull requests are marked stale after 14 days and closed after 16 days. Drafts and items labeled keep-open remain exempt; stale labeling and messages are applied automatically.

@CatherineSue
CatherineSue requested a review from slin1237 as a code owner March 18, 2026 03:24
@gemini-code-assist

Copy link
Copy Markdown
Contributor

Summary of Changes

Hello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request addresses several critical bugs in the Mergify configuration that prevented the automatic stale and close lifecycle for inactive pull requests from functioning correctly. The changes ensure that pull requests are properly identified as stale, reminded once, and then automatically closed if they remain inactive, improving repository hygiene by managing old, unmerged work.

Highlights

  • Stale PR Reminder Rule: Added a condition to the stale PR reminder rule to prevent it from re-firing on already-stale pull requests, ensuring the reminder is posted only once per stale period.
  • Stale PR Close Rule: Modified the close rule for stale pull requests to check for the 'stale' label and a shorter inactivity period (16 days) after being labeled stale, effectively closing PRs after approximately 30 days of total inactivity.
  • Remove Stale Label Rule: Updated the rule for removing the 'stale' label to ignore activity from the Mergify bot itself, ensuring that Mergify's comments do not inadvertently remove the stale label.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for GitHub and other Google products, sign up here.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution. ↩

@coderabbitai

coderabbitai Bot commented Mar 18, 2026 •

Copy link
Copy Markdown

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 73ced736-cb1f-4b84-b206-ff9037206aa4

📥 Commits

Reviewing files that changed from the base of the PR and between d29e020 and e3ef4ed.

📒 Files selected for processing (1)
  • .github/workflows/stale.yml

📝 Walkthrough

Walkthrough

Removed Mergify stale-PR rules from .github/mergify.yml and added a daily GitHub Actions workflow .github/workflows/stale.yml that uses actions/stale@v10 to label, message, and auto-close stale issues and pull requests per configured thresholds.

Changes

Cohort / File(s) Summary
Mergify config change
\.github/mergify.yml
Removed three Mergify rules related to stale PR handling (remind on stale PRs, close stale PRs, remove stale label when PR becomes active); replaced with a note pointing to the Actions workflow.
New stale workflow
\.github/workflows/stale.yml
Added daily workflow using actions/stale@v10 to mark/close stale issues and PRs with thresholds (issues: 90/30 days; PRs: 14/16 days), labels, custom messages, exemptions (drafts, keep-open), and write permissions for issues and pull-requests.

Sequence Diagram(s)

sequenceDiagram
    autonumber
    participant Scheduler as "GitHub Scheduler\n(daily)"
    participant Runner as "Actions Runner\n(ubuntu-latest)"
    participant StaleAction as "actions/stale@v10"
    participant Repo as "Repository\n(Issues & PRs)"

    Scheduler->>Runner: trigger workflow
    Runner->>StaleAction: run with config (thresholds, labels, messages)
    StaleAction->>Repo: list issues & PRs
    StaleAction->>Repo: add/modify labels (`stale`, `unstale`)
    StaleAction->>Repo: post stale/close comments
    StaleAction->>Repo: close items meeting thresholds
Loading

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Possibly related PRs

Suggested reviewers

  • key4ng
  • slin1237
  • XinyueZhang369

Poem

"🐇 I hopped through configs, labels in tow,
Quiet rules fell so new flows could grow.
At dawn a workflow wanders to find,
Stale whispers nudged, then gently closed behind.
Hop, label, nudge — automation's glow."

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title directly addresses the main change: fixing Mergify stale/close rules by replacing them with a GitHub Actions workflow. It accurately summarizes the core fix.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/mergify-stale-close-rules
📝 Coding Plan
  • Generate coding plan for human review comments

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions github-actions Bot added the ci CI/CD configuration changes label Mar 18, 2026

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Code Review

This is an excellent fix for a tricky CI problem. Your detailed explanation of the bugs in the stale PR lifecycle is very clear, and the proposed changes correctly address all the identified issues. The logic of using label = stale and adjusting the timeframes seems sound and should make the stale/close process work as intended. I have one suggestion to further simplify one of the rules for better clarity.

Comment thread .github/mergify.yml Outdated

@coderabbitai coderabbitai Bot 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.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
.github/mergify.yml (1)

123-133: ⚠️ Potential issue | 🟡 Minor

The sender != mergify[bot] syntax is valid, but other bot-triggered updates may still remove the stale label.

The condition sender != mergify[bot] correctly filters Mergify's own updates and is syntactically valid. However, the current rule doesn't account for other bots (e.g., dependabot[bot], github-actions[bot]) that may update the PR. If bot-initiated updates shouldn't reset the stale timer, consider filtering them as well:

conditions:
  - updated-at > 14 days ago
  - -closed
  - label = stale
  - sender != mergify[bot]
  - sender != dependabot[bot]
  - sender != github-actions[bot]

Alternatively, review whether allowing non-author collaborators and other bots to remove the stale label aligns with the intent of "Remove stale label when PR becomes active." The description says "by the author," but the condition allows any human user to trigger label removal.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/mergify.yml around lines 123 - 133, The rule currently uses the
condition sender != mergify[bot] alongside updated-at > 14 days ago and label =
stale, but that still allows other bots to clear the stale label; update the
conditions block to either (A) explicitly exclude common bots by adding
additional checks like sender != dependabot[bot] and sender !=
github-actions[bot] (and any other org-specific bots), or (B) more strictly
enforce "by the author" behavior by replacing/augmenting the sender check with
an author = <author> (or equivalent Mergify author condition) so only the PR
author can remove the stale label; adjust the conditions around sender !=
mergify[bot], label = stale, and updated-at > 14 days ago accordingly.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Outside diff comments:
In @.github/mergify.yml:
- Around line 123-133: The rule currently uses the condition sender !=
mergify[bot] alongside updated-at > 14 days ago and label = stale, but that
still allows other bots to clear the stale label; update the conditions block to
either (A) explicitly exclude common bots by adding additional checks like
sender != dependabot[bot] and sender != github-actions[bot] (and any other
org-specific bots), or (B) more strictly enforce "by the author" behavior by
replacing/augmenting the sender check with an author = <author> (or equivalent
Mergify author condition) so only the PR author can remove the stale label;
adjust the conditions around sender != mergify[bot], label = stale, and
updated-at > 14 days ago accordingly.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 341960da-d5f2-4510-899d-365df862e784

📥 Commits

Reviewing files that changed from the base of the PR and between c62672b and 9661a4a.

📒 Files selected for processing (1)
  • .github/mergify.yml

@chatgpt-codex-connector chatgpt-codex-connector Bot 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 9661a4a0f2

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread .github/mergify.yml Outdated
@CatherineSue
CatherineSue force-pushed the fix/mergify-stale-close-rules branch 2 times, most recently from 9c70008 to 7f2c09f Compare March 18, 2026 03:36

@coderabbitai coderabbitai Bot 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.

Actionable comments posted: 4

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In @.github/workflows/stale.yml:
- Around line 3-6: The workflow only triggers on schedule; add a manual trigger
by adding the workflow_dispatch event alongside the existing schedule under the
top-level on key so you can run the stale workflow on demand (update the on
block to include both schedule: - cron: '30 1 * * *' and workflow_dispatch).
Ensure you place workflow_dispatch at the same level as schedule in the YAML so
GitHub Actions recognizes the manual trigger.
- Around line 11-14: Remove the unnecessary "actions: write" permission from the
permissions block in the stale workflow: update the permissions section (the
block containing "issues: write", "pull-requests: write", and "actions: write")
to omit the "actions: write" entry so only "issues: write" and "pull-requests:
write" remain.
- Around line 25-26: Remove the unused bidirectional label configuration by
deleting the labels-to-add-when-unstale and labels-to-remove-when-stale keys
from the stale.yml workflow; locate the entries named
"labels-to-add-when-unstale" and "labels-to-remove-when-stale" and remove them
so the workflow no longer references the unused "unstale" label, simplifying the
workflow while preserving standard staleness behavior.
- Line 17: The workflow reference actions/stale@v10 may require GitHub Actions
runner v2.327.1+ and Node 24; verify the CI environment compatibility for
actions/stale@v10 by checking the repository's runner version (hosted or
self-hosted) and Node runtime used, and if runners are older either upgrade the
runners to v2.327.1+ (or GitHub-hosted images that include Node 24) or change
the workflow to use a compatible tag (e.g., actions/stale@v9) until runners are
upgraded; specifically locate the uses: actions/stale@v10 entry in the workflow
and take one of these corrective actions.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: c2a4a910-1e9a-4b03-a988-19ba36fc5c65

📥 Commits

Reviewing files that changed from the base of the PR and between 9c70008 and 7f2c09f.

📒 Files selected for processing (2)
  • .github/mergify.yml
  • .github/workflows/stale.yml

Comment thread .github/workflows/stale.yml
Comment thread .github/workflows/stale.yml Outdated
Comment thread .github/workflows/stale.yml
Comment thread .github/workflows/stale.yml Outdated
The mergify stale PR rules had three bugs:

1. The stale comment posted at 14 days resets `updated-at`, so the
   30-day close rule never fires — perpetually "updated" by Mergify.
2. The "remove stale label" rule triggers immediately after adding it
   because the comment bumps `updated-at`.
3. The stale rule re-fires on every evaluation even if already labeled.

Additionally, `updated-at` is unreliable — GitHub bumps it for invisible
events like conflict recalculation when main changes.

Replace Mergify stale/close rules with `actions/stale` GitHub Action
(same approach as vLLM), which correctly tracks activity without being
affected by bot comments or internal GitHub updates.

- PRs: stale after 14 days, closed after 16 more days (30 total)
- Issues: stale after 90 days, closed after 30 more days
- Draft PRs and `keep-open` labeled items are exempt

Signed-off-by: Chang Su <chang.s.su@oracle.com>
@CatherineSue
CatherineSue force-pushed the fix/mergify-stale-close-rules branch from 7f2c09f to d29e020 Compare March 18, 2026 03:40

@chatgpt-codex-connector chatgpt-codex-connector Bot 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: d29e02015f

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread .github/workflows/stale.yml

@coderabbitai coderabbitai Bot 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.

Actionable comments posted: 1

♻️ Duplicate comments (1)
.github/workflows/stale.yml (1)

11-14: ⚠️ Potential issue | 🟠 Major

Remove unnecessary actions: write permission.

actions/stale only needs issue/PR write scope; actions: write is broader than required.

🔒 Proposed fix
     permissions:
       issues: write
       pull-requests: write
-      actions: write
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/workflows/stale.yml around lines 11 - 14, The workflow permissions
block grants an unnecessary broad permission—remove the "actions: write" entry
from the permissions map so only the scoped permissions remain; specifically
edit the permissions block containing "issues: write" and "pull-requests: write"
and delete the "actions: write" line to limit access for the stale action.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In @.github/workflows/stale.yml:
- Around line 18-26: The workflow claims to exempt "keep-open" labeled items but
only has exempt-draft-pr: true; add explicit label exemptions by adding the keys
exempt-issue-labels and exempt-pr-labels (or exempt-pr-labels) and set them to
include "keep-open" (prefer a YAML list like ['keep-open']) so both issues and
PRs with the keep-open label are skipped by the stale action; update near the
existing exempt-draft-pr/stale-issue-label settings to keep related config
together.

---

Duplicate comments:
In @.github/workflows/stale.yml:
- Around line 11-14: The workflow permissions block grants an unnecessary broad
permission—remove the "actions: write" entry from the permissions map so only
the scoped permissions remain; specifically edit the permissions block
containing "issues: write" and "pull-requests: write" and delete the "actions:
write" line to limit access for the stale action.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: a880386b-65c2-4a1b-a54a-02d69de3a529

📥 Commits

Reviewing files that changed from the base of the PR and between 7f2c09f and d29e020.

📒 Files selected for processing (2)
  • .github/mergify.yml
  • .github/workflows/stale.yml

Comment thread .github/workflows/stale.yml
Signed-off-by: Chang Su <chang.s.su@oracle.com>
@CatherineSue
CatherineSue merged commit 3cf406d into main Mar 18, 2026
24 of 25 checks passed
@CatherineSue
CatherineSue deleted the fix/mergify-stale-close-rules branch March 18, 2026 03:51

@chatgpt-codex-connector chatgpt-codex-connector Bot 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: e3ef4ed646

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment on lines +19 to +20
operations-per-run: 500
exempt-draft-pr: true

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Preserve the keep-open opt-out in the stale action

This workflow only exempts draft PRs. actions/stale uses exempt-issue-labels / exempt-pr-labels to skip labeled items, and neither is set here, so any issue or PR that maintainers label keep-open will still be marked stale and auto-closed on the normal schedule. That breaks the explicit manual opt-out described in this change for long-lived tracking items and PRs.

Useful? React with 👍 / 👎.

smfirmin pushed a commit to smfirmin/smg that referenced this pull request Mar 20, 2026
smfirmin pushed a commit to smfirmin/smg that referenced this pull request Mar 20, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ci CI/CD configuration changes

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant