Skip to content

grofers/stale-branches

 
 

Repository files navigation

ci status ci status

Stale Branches

Finds and deletes stale branches. By default it aligns with this definition, but can be configured for other use cases.

When a branch has been inactive for more than the days-before-stale input, it is considered stale. The branch will be deleted once it has been inactive longer than days-before-delete.

  • By default, a stale branch is defined as a branch that:
    • has had no commits in the last 120 days.
    • has no protection rules.
    • is not the default branch of the repository.
    • See inputs for more info.
  • See example workflow.

Usage

Pre-requisites

Create a workflow .yml file in your repository's .github/workflows directory. An example workflow is available below. For more information, reference the GitHub Help Documentation for Creating a workflow file.

Inputs

Inputs are defined in action.yml. None are required.:

Name Description Default
repo-token Token used to authenticate with GitHub's API. Can be passed in using ${{ secrets.GITHUB_TOKEN }}. ${{ github.token }}
days-before-stale Number of days a branch has been inactive before it is considered stale. 120 days
days-before-delete Number of days a branch has been inactive before it is deleted. 180 days
comment-updates A comment with updated information will be added to existing issues each workflow run. false
max-issues This dictates the number of stale branch 🗑️ issues that can exist. Also, the max number of branches that can be deleted per run. 20
tag-committer When an issue is opened, the last committer will be tagged in the comments. false
stale-branch-label Label to be applied to issues created for stale branches.
As of v2, this must be unique to this workflow.
stale branch 🗑️
compare-branches This compares each branch to the repo's default branch.
  • When set to info, additional output describes if the current branch is ahead, behind, diverged, or identical to the default branch.
    image
  • When set to save, this prevents branches from being deleted if they are ahead of or diverged from the default branch.
  • When set to off, no additional calls are made.
off
branches-filter-regex An optional Regex that will be used to filter branches from this action. ''
rate-limit If this is enabled, the action will stop if it exceeds 95% of the GitHub API rate limit. true
pr-check If this is enabled, the action will first check for incoming/outgoing PRs associated with the branch. If a branch has an active pr, it will be ignored. false
dry-run If this is enabled, the action will not delete or tag any branches. false
ignore-issue-interaction If this is enabled, the action will not interact with Github issues. false
include-protected-branches If this is enabled, the action will include protected branches in the process.
Note: When you use this, the token passed to repo-token must include "Administration" repository permissions (read). For details, see https://docs.github.com/en/rest/branches/branch-protection?apiVersion=2022-11-28
false
ignore-commit-messages Comma-separated list of commit messages (or substrings) to ignore when determining commit age. If provided, commits with these messages will be ignored when calculating branch age. e.g. Ignore commits produced by automated workflows.
ignore-committers Comma-separated list of committer usernames to ignore when calculating the most recent commit. ''
ignore-default-branch-commits If true, ignore commits that are also present in the default branch when determining the last meaningful commit. This fetches all default branch commits up to the staleness window (days-before-delete), ensuring robust filtering even for large/active repos. false

Outputs

Outputs are defined in action.yml:

Name Description
stale-branches List of all branches identified as stale during a workflow run.
deleted-branches List of all branches deleted during a workflow run.

Terminal Output Groups

  • Output is grouped by branch.
    • Active branches are green
    • Stale branches are yellow
    • Dead branches are red
    • Skipped branches are blue

image

Example workflow

With defaults

# .github/workflows/stale-branches.yml

name: Stale Branches

on:
  schedule:
    - cron: '0 6 * * 1-5'

permissions:
  issues: write
  contents: write

jobs:
  stale_branches:
    runs-on: ubuntu-latest
    steps:
      - name: Stale Branches
        uses: crs-k/[email protected]

With Inputs

# .github/workflows/stale-branches.yml

name: Stale Branches

on:
  schedule:
    - cron: '0 6 * * 1-5'

permissions:
  issues: write
  contents: write

jobs:
  stale_branches:
    runs-on: ubuntu-latest
    steps:
      - name: Stale Branches
        uses: crs-k/[email protected]
        with:
          repo-token: '${{ secrets.GITHUB_TOKEN }}'
          days-before-stale: 120
          days-before-delete: 180
          comment-updates: false
          max-issues: 20
          tag-committer: false
          stale-branch-label: 'stale branch 🗑️'
          compare-branches: 'info'
          branches-filter-regex: '^((?!dependabot))'
          rate-limit: false
          pr-check: false
          dry-run: false
          ignore-issue-interaction: false
          ignore-commit-messages: ''
          ignore-committers: ''

Ignoring Commits by Message, Committer, and Default Branch

You can use ignore-commit-messages, ignore-committers, and ignore-default-branch-commits together. A commit will be ignored if any of these conditions match:

  • Its message matches any ignored message
  • Its committer matches any ignored committer
  • Its SHA is present in the default branch (e.g., from a merge or rebase) within the staleness window

Note: The action fetches all default branch commits up to the staleness window (days-before-delete), not just a fixed number. This ensures that even old commits in main are ignored if they fall within the relevant window.

This allows you to filter out automated commits, bots, specific users, or commits that are not unique to the feature branch when determining branch staleness.

Example:

with:
  ignore-commit-messages: 'WIP,auto-update'
  ignore-committers: 'dependabot[bot],github-actions[bot]'
  ignore-default-branch-commits: true

This will ignore any commit with a message containing "WIP" or "auto-update", any commit made by the users dependabot[bot] or github-actions[bot], and any commit that is also present in the default branch (such as merges from main).

Contributing

Contributions are welcomed. Please read the contributing.

About

Finds and deletes stale branches

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages

  • TypeScript 98.0%
  • JavaScript 2.0%