Repository navigation
feat(ci): nightly merged-branch prune across the account, dry run by default - #8
Conversation
…default Adds scripts/prune-merged-branches.sh (byte-identical to the copy in TanksterAI/.github) and .github/workflows/branch-prune.yml, which sweeps every repository rishitank owns. Deletes only branches merged at their current tip; everything else is reported. Nightly runs stay dry unless the PRUNE_APPLY variable is `true`; without the PRUNE_TOKEN secret the job explains how to create it and exits green. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012rYJxu978iUSGFZ1UuqTsi
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configuration
📒 Files selected for processing (2)
Included review availability: This review used your included allowance. Your plan provides up to 1 included review per hour; 0 remain after this review. 📜 Recent review details🔇 Additional comments (5)
📝 SummarySummary by CodeRabbit
WalkthroughAdds a scheduled and manually dispatchable workflow to scan repositories for merged branches. The script classifies branches, checks deletion conditions, optionally deletes eligible branches, and writes JSON and Markdown reports. ChangesMerged branch pruning
Priority: ⬇️ Low Estimated code review effort: 4 (Complex) | ~45 minutes Change: Feature Sequence Diagram(s)sequenceDiagram
participant Workflow as branch-prune.yml
participant Script as prune-merged-branches.sh
participant GitHubAPI as GitHub API
participant Artifact as Report artifact
Workflow->>Script: Pass owner, mode, and report path
Script->>GitHubAPI: List repositories and inspect branch refs
GitHubAPI-->>Script: Return repository and ref data
Script->>GitHubAPI: Delete eligible refs in apply mode
GitHubAPI-->>Script: Return deletion result
Script-->>Workflow: Write report
Workflow->>Artifact: Upload report when available
Merge Risk: ⚪ Minimal · up to No actionable issue was established that would prevent merging after normal checks. 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)✅ Passed checks (4 passed)Full details: Docstring CoverageExplanation Docstring coverage is 50.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 6 functions across 1 files. (1 skipped: 1 unsupported.)
✨ Finishing Touches 💡 1📝 Generate docstrings 💡
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Apprentice, the branches meet the night, Comment |
A workflow with only schedule and workflow_dispatch triggers cannot be dispatched until it is on the default branch (the dispatch API returns 404). One pull_request run registers it and exercises the no-token path; the next commit removes the trigger again. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012rYJxu978iUSGFZ1UuqTsi
The workflow is registered now, so it can be dispatched on this branch. Back to schedule + workflow_dispatch only: a PR-triggered run would follow PRUNE_APPLY and could delete from a feature branch. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012rYJxu978iUSGFZ1UuqTsi
rishitank
left a comment
There was a problem hiding this comment.
Self-review by Claude (head a6a8271). I read both changed files in full.
scripts/prune-merged-branches.sh
This is blob 9360696e, byte-identical to the copy merged today as TanksterAI/.github#17. That copy has a real apply run (TanksterAI run 37945894623): 36 repos, 19 deleted, 0 failed, 0 unreadable. I reviewed it line by line there:
- strict
--mode; - the empty-list refusal;
- full pagination;
- merged-at-current-tip with
head_repo == R; - an open PR as head or base keeps the branch;
- the rules endpoint: 404 or the plan 403 means none, anything else means keep;
@uri-encoded re-read before acting;- read-back after DELETE.
--user lists user/repos?affiliation=owner and filters to owner, so collaborator repos are never touched.
.github/workflows/branch-prune.yml
- Triggers are schedule and workflow_dispatch only. The temporary
pull_requesttrigger used to register the workflow was removed in a6a8271, so a PR run can never followPRUNE_APPLY. - Workflow
permissions: {}. The job hascontents: readand pins checkout by SHA (3d3c42e = v7.0.1) withpersist-credentials: false. - upload-artifact is pinned at 043fb46 (= v7.0.1).
- A queued, non-cancelling concurrency group.
- Mode:
- dispatch follows the
modeinput, which defaults to dry-run; - schedule applies only when the
PRUNE_APPLYvariable is literallytrue.
- dispatch follows the
- Without
PRUNE_TOKEN, a notice and a step summary with setup steps, and the job exits green. The token is only ever read throughenv. runs-on: ubuntu-latestis correct for a personal repo: there is no CI_RUNNER rule here.
CI: actionlint, Renovate presets and CodeRabbit are green. There are 0 review threads.
Result: no defects found and no fixes needed.
For Rishi: nothing runs for real until the PRUNE_TOKEN secret exists, created with the permissions listed in the workflow summary.
Why
Branches from PRs merged before
delete_branch_on_mergewas switched on stay around forever, and nothing cleans them up. #7 deletes a PR's head branch as it merges, going forward. This PR clears the existing backlog across every repository the account owns, and anything #7 misses later. It uses narrow rules that only ever remove a pointer whose commits are already in the base branch.This is the same design as TanksterAI/.github#17.
scripts/prune-merged-branches.shis byte-identical in both repos (blob9360696e).What changed
scripts/prune-merged-branches.sh(new). Depends onghandjqand fails loudly if either is missing. It walksuser/repos?affiliation=owner, filtered to ownerrishitank, and paginates everything..github/workflows/branch-prune.yml(new):scheduleat17 4 * * *, andworkflow_dispatchwith amodeinput (dry-runby default, orapply).ubuntu-latestwithpermissions: contents: read. Checkout is SHA-pinned withpersist-credentials: false. A concurrency group queues runs and never cancels them.branch-prune-reportartifact and writes a markdown table to the step summary.Safety rules (all must hold, or the branch is report-only)
The repository must not be archived and must not be a fork. A branch can be deleted only when all of these hold:
deletionrule to it.^(main|master|develop|staging|test|gh-pages|v[0-9][0-9.]*|deploy-.*|release/.*)$.How deletion works in apply mode:
DELETE repos/R/git/refs/heads/<urlencoded B>. A 422 or 404 means the branch is already gone.Report-only categories are
keep/protected,open,no-pr,closed-unmergedandmerged-but-moved.When it deletes
PRUNE_APPLYis exactlytruemodeinput; defaultdry-runPRUNE_TOKENsecret missingHow to enable
PRUNE_TOKEN.branch-pruneby hand withmode: dry-runand read the report.PRUNE_APPLY=true, or dispatch once withmode: apply.Checks
ghcovering every category, both 403 cases, a tip moving mid-run, 422 and 500 on delete, and an unreadable repo.🤖 Generated with Claude Code
https://claude.ai/code/session_012rYJxu978iUSGFZ1UuqTsi