feat(flows-yaml): port PR-closed cleanup chain to YAML (pr-closed.yml) #1098
No reviewers
Labels
No labels
area:agents
area:dashboard
area:database
area:design
area:design-review
area:flows
area:infra
area:meta
area:security
area:sessions
area:webhook
area:workdir
security
type:bug
type:chore
type:meta
type:user-story
No milestone
No project
No assignees
2 participants
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
charles/claude-hooks!1098
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "feat/flows-yaml-pr-closed"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Summary
Closes #1093.
Imperative
handlePullRequestClosedinevent-handlers.tsremoved; the four side effects ofpull_request.closed(branch cleanup, dep-row drop, post-merge rebase scan,pr.mergedinternal trigger publish) now live inflows/defaults/pr-closed.ymlbehind a newprClosedcapability.Capability + ops
PrClosedCapabilityinflows-yaml/types.ts; live + shadow bags wire it;LiveCapabilitiesDepsextended withprClosedcleanup_branch— wrapsdomain/workflow/cleanup.ts::cleanupBranchdrop_pr_dependencies— wrapsdb.ts::clearPrDependencieshandle_post_merge_rebase— wrapsevent-handlers.ts::handlePostMergeRebase(kept exported because the janitorunmergeable_pr_rebaserule also calls it)publish_pr_merged— uses the liveTriggerBusbuildLiveCapabilitiesDepsnow takestriggerBusso the liveprClosedcap can publish without a module-level setterFlow
flows/defaults/pr-closed.ymlonpull_request: [closed]: cleanup_branch → drop_pr_dependencies → (if merged) handle_post_merge_rebase → publish_pr_mergedCleanup
handlePullRequestClosedfromevent-handlers.tswebhook.ts:333-335flows-yaml/defaults/__tests__/pr-closed.test.ts)flows.schema.json(26 ops now)Test plan
pr-closed.ymlflow test covers merged + unmerged pathsCo-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Review: APPROVE (CI pending — will merge when green)
Clean port. The four ops are correctly factored, the capability boundary is well-drawn, and the full cleanup of the imperative path is thorough. A few observations worth noting, none blocking.
AC verification
cleanup_branchop (repo, branch, pr_number)drop_pr_dependenciesop (repo, pr_number)handle_post_merge_rebaseop (repo, pr_number, base_ref)publish_pr_mergedop (repo, pr_number); gated byif: event.pr.mergedflows/defaults/pr-closed.ymlonpull_request: [closed]with correct step orderpr-merged.ymlcascade still fireshandlePullRequestClosedfromevent-handlers.tswebhook.ts:333-335Observations
1.
pr-merged.ymlcascade regression (AC item not explicitly covered)The issue AC has:
The
pr-closed.ymlflow test uses a recording stub forprClosed.publishPrMerged— it verifies the op is called, but doesn't wire a real trigger bus, so it can't assertpr-merged.ymlfires in response. The AC item is implicitly covered if the existingpr-merged.ymltests pass as part of the 3252-test suite, but there's no dedicated end-to-end test for the chainpr-closed.yml → publishPrMerged → pr-merged.yml. Worth adding in a follow-up if the cascade ever misbehaves silently; acceptable as-is given the full suite pass.2. Guard condition narrowing on
handle_post_merge_rebaseLegacy code:
if (pr.merged && pr.base?.ref)— bothmergedandbase.refhad to be truthy before calling the rebase handler and publishing the trigger.YAML flow:
if: event.pr.merged— onlymergedis checked. Thebase_refarg is required by the op schema, so ifevent.pr.baseRefever evaluated to null/empty the step would fail validation rather than skip. In practice Forgejo always includesbase.refinpull_request.closedwebhooks, so this is safe — just a subtle difference worth being aware of if the flow is reused in a context wherebaseRefmight be absent.3. Drop-count log removed
Old code logged
pr-deps: cleared ${dropped} outgoing edge(s)whendropped > 0. The newdropPrDependenciesadapter swallows the result silently on success (only warns on error). Low-stakes, but that log was occasionally useful for debugging stale dependency graphs. Could add aconsole.login the success branch of the adapter for parity.4. Error handling correctly moved to capability layer
All three mutating helpers (
cleanupBranchHelper,handlePostMergeRebase,clearPrDependencies) are wrapped with try/catch in themain.tsadapter, matching the legacy "best-effort" semantics exactly.continue-on-error: trueis correctly absent from the YAML steps — errors are already absorbed before they can propagate to the flow runner.5.
buildLiveCapabilitiesDepsrefactorGood call making
triggerBusan explicit parameter instead of reading the module-level_triggerBusslot. This eliminates the only remaining reason for the slot to exist for the PR-closed path and makes the dependency graph explicit.Merge plan
CI is pending — deferring merge to the post-CI gate. Will merge when green (squash) and close #1093.