v2.88.0
Binaries and the merged-pull-request list are on the GitHub releases page.
A bootstrap still spent two stretches waiting on things that did not need waiting for. Each landing waited about 25 s for a GitHub runner to plan a tree that was sitting in the build box. And the first phase waited for the whole task set-up (the epic, its milestones, its tasks) before it did anything, though nothing before the landing reads it. This release removes both waits.
A landing that checks its commit here: checks: local
orun.pr/land@v1 takes checks:
- id: land
uses: orun.pr/land@v1
with:
task: "{{ .phase.hooks.task.outputs.key }}"
branchSlug: "{{ .phase.name }}"
checks: local
-
ci(the default) is what a landing has always done: open the pull request, wait for its CI run, merge. -
localchecks the commit in the box before it is pushed, then merges without waiting for CI. The check is three commands, run on the commit:orun validate;orun planas the pull request plans it, from apull_requestevent made for the commit, so the trigger binding the product's CI would match is the one planned;orun planas the merge's push to the base plans it. That is the convergence a bootstrap watches next, which the PR's CI never compiled.
On a todo product the three take under half a second. A commit that fails them is never pushed, so it never becomes a pull request, and the error names the command and shows its output.
The PR's own CI still runs; nothing waits for it. If the base branch
requires a status check, GitHub refuses the early merge. The landing then
waits for the checks as ci would (up to checkTimeoutSeconds) and merges.
The step reads "Checked here and merged #1 into main." The outputs gain
checked (ci, local, local+ci when a required check was waited for, or
none) and checkSummary, which says what was planned.
A merge asked for seconds after its pull request opened can be refused while GitHub is still working out that the PR is mergeable. Such a refusal (405 "not mergeable", 409 "base branch was modified") is now asked again over about ten seconds before it is reported. A refusal that names a rule, such as a required check or a required review, is not.
The task set-up runs beside the first phase: background: true
A hooks.preInstantiate hook can be marked background: true, and so must
every hook after it. The background is the end of the list, run in order, and
it starts with the run instead of before the first phase:
hooks:
preInstantiate:
- id: epic
uses: orun.task/ensure@v1
background: true
with: { kind: epic, slug: todos-baselining, name: "Todos baselining" }
- id: t01
uses: orun.task/ensure@v1
background: true
with: { kind: task, epic: todos-baselining, milestone: 01-product, name: "Build the product" }
- A hook whose action works on the task plane (
orun.task/ensure@v1,orun.task/rollup@v1,orun.pr/land@v1) waits for the background to finish. It reads what the background made, and two finds-or-creates of one task at once would make it twice. Every other hook (a provider check, the placement, arun:hook, the repository, the secrets) runs while the background is still going. - A background hook that fails stops the run at the next hook, with its own error, and is reported as it fails.
- The run never ends with the background still running.
background is only for uses: hooks in hooks.preInstantiate. A run:
hook would share the product tree with the phase that is writing it.
To get the overlap, a phase looks up its task where it uses it: its task
hook goes from pre to post, just before land. A task hook left in
pre waits for the background at once, which is the old order.