Skip to content
Latchkey

How to Run a Nightly Cleanup of Stale Branches in GitHub Actions

A nightly scheduled job can list merged branches with the gh CLI and delete the ones past a cutoff.

Run on schedule, then use the gh CLI (preinstalled on runners) to find branches merged into the default branch and delete them, skipping protected ones.

Steps

  • Trigger the workflow on a nightly cron.
  • Grant contents: write so the job can delete refs.
  • Use gh api or git branch --merged to find candidates, then delete them.

Workflow

.github/workflows/ci.yml
on:
  schedule:
    - cron: '0 2 * * *'
permissions:
  contents: write
jobs:
  prune:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 0
      - run: |
          for b in $(git branch -r --merged origin/main | grep -v 'origin/main' | sed 's|origin/||'); do
            git push origin --delete "$b" || true
          done
        env:
          GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}

Gotchas

  • Protected branches reject deletion; the || true keeps the loop going.
  • Test with a dry run first so you do not delete an active branch by mistake.

Related guides

Run this faster and cheaper on Latchkey managed runners. Start free →