Skip to content

feat(maintenance): auto-sweep stale branches after merge + periodic sweep #146

@hadamrd

Description

@hadamrd

Problem

After every merge the loop accumulates branches indefinitely:

  • This session: 115+ branches on hadamrd/forge-loop, 46 still on remote after merges.
  • Loop already uses gh pr merge --squash --auto --delete-branch on its auto-merge path, but NOT all merge paths go through that — and the local branch in the operator's checkout never gets deleted.
  • Operator must manually run git push origin --delete <br> loops + git branch -D loops. Painful + error-prone (one slip and a non-merged branch dies).

Acceptance

  1. Per-merge cleanup (already partial): every successful auto-merge MUST delete the remote branch. Add the same to admin-merge and rescue-merge paths.
  2. Per-tick sweep: every Nth tick (default 20), call the new sweep:
    • List remote branches matching loop/*, feat/*, fix/*, refactor/*, chore/*, test/*, docs/*.
    • For each: query the GitHub API for the PR. If state is MERGED or CLOSED (and > 7 days old, configurable), delete the remote branch via gh api -X DELETE.
    • Local branch cleanup: any branch with no remote tracking ref + last commit older than 30 days → delete.
  3. Emit typed event branch_sweep_done with counts (deleted/skipped/error).
  4. forge-loop sweep branches CLI command for manual runs.

Test plan

  • Unit: mock GhClient with mixed MERGED/CLOSED/OPEN PRs; assert correct delete calls.
  • Adversarial: a branch with no PR at all (orphan) — don't crash, log + skip.
  • Adversarial: gh API rate limit during sweep — back off + resume, don't hammer.
  • Regression: a branch that has an OPEN PR is NEVER deleted.

File pointers

  • src/forge_loop/branch_sweep.py (new)
  • src/forge_loop/runner/tick.py — call sweep on the maintenance_every_n_ticks cadence
  • src/forge_loop/cli.pysweep branches subcommand
  • src/forge_loop/settings.pymaintenance.branch_sweep_every_n_ticks (default 20), maintenance.branch_min_age_days (default 7)
  • tests/test_branch_sweep.py (new)

Customer story

A platform team runs forge-loop on their repo for a week. Without this, they have 200+ stale branches in their list. With this, the branch list stays clean — only OPEN PRs and the default branch.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions