chrismdp / land-a-pull-request
A pull request lands once CI has run
workflow.yaml
workflow.yaml is AWML 0.6, as it was pushed. The registry draws, checks and fits it converted to AWML 0.8.
# A pull request the app opened lands once CI has run on it. If CI fails, it goes to
# retry-a-build. If CI passes, a code rule decides whether the change is straightforward, by rules
# the maintainer wrote down, reading the reviews' findings and the classifier's verdict, which can
# send a change to review but never skip one. A straightforward change the app sets to merge by
# itself. Otherwise the person who added the label is asked to review it, and merges it from their
# own account, which is their yes. Main's own rule holds every merge until CI has passed.
awml: "0.6"
title: A pull request lands once CI has run
scopes:
- { id: public, label: "public: anyone who reads the repository", processing: any }
parts:
- { id: pushed, kind: trigger, label: "The app pushes the pull request's branch" }
- { id: token, kind: connector, label: "The repository, through its own Actions token", in: public, ref: issue-to-pull-request.yaml#token }
- { id: app, kind: connector, label: "The repository, through its own GitHub App", in: public, ref: issue-to-pull-request.yaml#app }
- { id: patch, kind: context, label: "The change, as a patch, with its pictures, Claude's note and its description for the pull request", in: public, ref: issue-to-pull-request.yaml#patch }
- { id: findings, kind: context, label: "The reviews' findings, each Important, Nit or Pre-existing", in: public, ref: issue-to-pull-request.yaml#findings }
- { id: risk, kind: context, label: "The classifier's verdict and its reasons", in: public, ref: issue-to-pull-request.yaml#risk }
- { id: ci, kind: code, op: check, label: "CI runs every check on the branch", in: public }
- { id: tryfailed, kind: trigger, label: "A try failed", ref: retry-a-build.yaml#tryfailed }
- { id: rules, kind: context, label: "The build rules: what needs a review", in: public }
- { id: judge, kind: code, op: sort, label: "Sort by rule: does the change touch a path that needs review, delete a test, change over 400 lines, leave a finding open, or did the classifier ask for review?", in: public }
- { id: automerge, kind: code, op: do, label: "Set the pull request to merge, saying in its message why it was straightforward", in: public }
- { id: ask, kind: code, op: do, label: "Ask the person who added the label to review the pull request", in: public }
- { id: askout, kind: outside, label: "Request a review: Allow", in: public }
- { id: update, kind: code, op: do, label: "Edit the status comment: whether it merges by itself or waits for review", in: public }
- { id: status, kind: outside, label: "Edit the build's status comment: Allow", in: public }
- { id: merge, kind: person, op: do, label: "Review the pull request, whose CI has passed, and merge it", in: public }
- { id: account, kind: connector, label: "The repository, through the reviewer's own account", in: public }
- { id: held, kind: code, op: sort, label: "Sort by main's rule: has CI passed on the commit the app set to merge?", in: public }
- { id: landauto, kind: code, op: do, label: "Merge the change the app set to merge", in: public }
- { id: mainauto, kind: outside, label: "Merge a straightforward change into main: Allow", in: public }
- { id: main, kind: outside, label: "Merge a change that needed review into main: Ask", in: public }
- { id: afterci, kind: comment, label: "CI finishing on a pull request the app opened starts land.yml, so no review is asked for and nothing merges until CI has a result" }
- { id: terms, kind: comment, label: "Allow, because a merge is undone with git revert, everything in it is already public on its branch, and the maintainer would not be surprised by a change the rule finds straightforward. One the rule sends to review is where they would be, so that merge is Ask" }
- { id: escalate, kind: comment, label: "The classifier can send a change to review but can't skip one, and the agent that wrote the change has no say. The rule reads the patch itself: what it touches, its size and whether it deletes a test (awml #20, #26)" }
- { id: noskip, kind: comment, label: "Main's rule holds every merge, the app's and the maintainer's, until CI passes. Only the maintainer may skip it, to push a release; the app may not" }
- { id: whoasked, kind: comment, label: "The build carries the name of the person who added the label. A build whose label the app added, with no such person, asks the repository's owner" }
lines:
- { from: pushed, to: ci, kind: start, label: "the branch" }
- { from: ci, to: tryfailed, kind: start, label: "[a check fails]" }
- { from: ci, to: judge, kind: start, label: "[all pass]" }
- { from: patch, to: judge, kind: data }
- { from: findings, to: judge, kind: data }
- { from: risk, to: judge, kind: data }
- { from: rules, to: judge, kind: data }
- { from: judge, to: automerge, kind: start, label: "[straightforward]" }
- { from: judge, to: ask, kind: start, label: "[needs a review]" }
- { from: automerge, to: update, kind: start, label: "merges by itself" }
- { from: ask, to: update, kind: start, label: "waits for review" }
- { from: update, to: status, kind: data }
- { from: status, to: token, kind: data }
- { from: ask, to: askout, kind: data }
- { from: askout, to: token, kind: data }
- { from: ask, to: merge, kind: start, label: "the review request" }
- { from: account, to: merge, kind: data, label: "the pull request and CI's result" }
- { from: merge, to: main, kind: data }
- { from: main, to: account, kind: data }
- { from: automerge, to: held, kind: start, label: "the merge, set" }
- { from: held, to: landauto, kind: start, label: "[passed]" }
- { from: landauto, to: mainauto, kind: data }
- { from: mainauto, to: app, kind: data }
- { from: afterci, to: ci, kind: tie }
- { from: terms, to: mainauto, kind: tie }
- { from: escalate, to: judge, kind: tie }
- { from: noskip, to: held, kind: tie }
- { from: whoasked, to: ask, kind: tie }
implementations:
actions:
label: GitHub Actions, ci.yml and land.yml
blocks:
- { id: github, label: "GitHub: pull requests, and main's rule", parts: [pushed, token, app, patch, findings, risk, rules, tryfailed, status, askout, held, landauto, mainauto, account, main] }
- { id: cijob, label: "ci.yml: CI, with a read-only token", platform: actions-code, parts: [ci] }
- { id: findjob, label: "land.yml: apply the rule, with a read-only token", platform: actions-code, parts: [judge] }
- { id: landjob, label: "land.yml: set the merge or ask for review, running nothing from the change", platform: actions-code, parts: [automerge, ask, update] }
- { id: browser, label: "The maintainer's browser", parts: [merge] }