Update pull requests when their base moves, merge them on approval #18
No reviewers
Labels
No labels
Compat/Breaking
Kind/Bug
Kind/Documentation
Kind/Enhancement
Kind/Feature
Kind/Security
Kind/Testing
Meta/Campaign
Meta/Epic
Meta/Session
Priority/Critical
Priority/High
Priority/Low
Priority/Medium
Reviewed/Confirmed
Reviewed/Curated
Reviewed/Duplicate
Reviewed/Invalid
Reviewed/Won't Fix
Scope/Campaign
Status/Abandoned
Status/Blocked
Status/Conflicted
Status/In Progress
Status/In Review
Status/Need Grooming
Status/Need More Info
Status/Ready
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
Ting/Jostoph!18
Loading…
Reference in a new issue
No description provided.
Delete branch "agent.teyla/auto-update-and-merge"
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?
Closes #17. Stacked on #16 — merge that first; this branch is based on it, so the diff against
mainshows both commits. Only3bb4156belongs to this PR.Two rules the substrate already supported and nobody had written. Both are Datalog in
src/policy.rs, both declare effects and perform nothing.Merging on approval
On an approving review of a non-draft pull request, declare the merge —
rebasewhen it carries thecuratedlabel,squashwhen it does not.Ting/Ting#4 curates history into logical commits before the PR, so a curated branch deserves to be replayed: the commits that were curated are the commits that land. A branch without the label is exploratory session work, and replaying it publishes exactly the noise curation exists to remove, so it is folded into one. The label is the author asserting they did the work; the steward reads it, it does not award it.
head_commit_idis the load-bearing field, not a detail. An approval is of a commit, not of a branch name. Without it, a push landing between the review and the merge is merged unreviewed — and the steward would have been the thing that asked for it. With it, Forgejo refuses rather than quietly taking the wrong tree. There is a test whose entire job is that property.Drafts are excluded: a draft is not finished being written, and an approval on one is not a request to land it.
Keeping pull requests current
On a push to a base branch, declare that open pull requests based on it be updated — by
rebase, nevermerge, because updating by merge writes a merge commit into the branch whose history the estate curates and whose merge styles #5 turns off.Which pull requests those are is not in the payload and does not need to be: the steward declares what must become true; finding them is the executor's work. This fires alongside the protected-push denial when the base is
main, and both conclusions are true at once — who pushed is one question, what must follow is another, and resolution is the substrate's job.Two declarations that cannot disagree
nix/policy.nixnow takesmergeStylesfromnix/forgejo.nixinstead of restating it, so the styles the rules may declare cannot fall outside the styles the estate's repos allow. Restating them would let #5 turn a style off for the repos while the steward went on asking for it — and the failure would surface at the forge, on a real pull request, at merge time. Forgejo'sDovalues and its per-repo allow flags are two vocabularies for one thing, andallowFlagForis the only place they meet.That is why this PR is stacked:
mergeStylesarrives in #16.What I could not verify, and what I did about it
Forgejo's wire name for an approving review is unverified from this estate. There is no webhook on any repo to read the delivery header off, and the swagger does not enumerate hook event names. So it is a crystallized parameter, not rule logic —
approval_kindslists both plausible spellings, and getting it wrong costs a Nix eval rather than a rebuild. The same reasoning covers the label name and both styles.The hook-config spelling (
pull_request_review_approved, added to the declaredevents) is a third name and is unverified for the same reason. Confirm both against a real delivery when the webhook is first provisioned, and delete whicheverapproval_kindsentry never arrives.In scope
merge_with/approved/pr_curated/pr_draft/pr_headrules and the two conclusions that carry effects.base_refs,approval_kinds,curated_label,merge_style_curated,merge_style_uncuratedas crystallized parameters; policy schema 2 → 3.pull_request_review_approvedon the declared webhook.Out of scope
checks.module-evaluatesfails the build if its unit grows one. Execution is the extension this repo has named since PR #2.Boundary
A schema bump means a deployed steward running v2 parameters refuses to start rather than silently gating less — which is the intent, and is already covered by
a_future_schema_version_is_refused.The update effect names a base branch, not a list of pull requests. That is deliberate (the payload has no such list), but it does mean the effect is coarser than the others: an executor acting on it must enumerate, and enumerating is where it could act on a PR nobody asked about. Worth keeping in view when the executor is built.
Acceptance
cargo test— 31 pass (was 19), 12 new. ✅cargo clippy --all-targets -- -D warningsclean;cargo fmt --checkclean. ✅nix flake check— green, 10 checks, including the policy-drift check against the regeneratedpolicy/ting.json. ✅Do: rebase, naming repository and index16. ✅Do: squash. ✅curated-ish) does not count as curation. ✅refs/heads/fastlane→ one update effect,style: rebase, naming repository and base; push torefs/heads/tango/17-something→ nothing. ✅allow_squash_merge = falseinnix/forgejo.nixmakesnix build .#policyfail withTing's policy would declare merge style(s) the estate's repos do not allow: squash.— then reverted to green. ✅Verified with
--override-input jostoph-rs path:…, as #13 has not merged.