~ knotless Search/
↑↓ move↵ open⇧↵ all results

chadtmiller.com/knotless

git that lives in your Atmosphere account

knotless.dev
1 collaborator

knotless 0.13.0 Latest 2 packages, 1 image

1
10

A workflow step can run only at some refs

Merged
Merged chadtmiller.com asked to merge into main from chadtmiller.com/knotless:run/step-on

What changes

A step's on. A workflow step, or a step in a step file, may name on: {refs: [...]}, matched as on.push.refs are (workflow::matches): exactly, or as a prefix before a final *. refs is required and non-empty, and on refuses any other key, so paths can come later. Both workflow::parse and uses::parse_step check it, through Step::invalid.

What it matches. The ref a push moved, or the one a run asked for by name is at. A pull's run and a merge-queue batch's run match no ref. KNOTLESS_RUN_REF is a pull's head branch there, which a fork may call main, and a batch's base branch, not moved yet. Matching either would run a step meant for main before anything landed. So a step for refs/heads/main runs only at the push that lands the change.

A step left out is not run. The log says why under its ==> <step> line (==> skipped, as refs/heads/x is not refs/heads/main, or as a pull's run is at no ref of the repository's). Its check lists it skipped, as a step after a failure is, and the run still passes. Progress is sent as for a step that ended.

Reuse. A run that left a step out is not kept for the push that lands its pull or batch to reuse, nor are its cache layers kept for it. That push runs the workflow itself, with the steps for its ref. Otherwise a batch's pass would stand in for main's run and the main-only step would never run.

Shared steps. On a uses step, on holds for every step it expands to (Step::within), and a step in the step file may have its own. Both must match, and so on down nested shared steps.

Why

Steps gate themselves in shell today ([ "$KNOTLESS_RUN_REF" = refs/heads/main ] || exit 0), which a shared step cannot be wrapped in short of an input of its own, such as wait-for-checks's only-on.

How it was checked

Unit tests in workflow.rs (parsing, matching, within), uses.rs (expansion carries on), and knotless-run's ref_at. a_workflow_uses_a_shared_step in tests/run.rs now runs a gated workflow at main and at another branch: own steps, a uses step with on, and a step file's own on. Left to CI.

Shortcomings

.knotless/workflows/*.yml still gate in shell. Another pull is moving them onto shared steps, and changing them here would conflict. A workflow with an on step loses pull-pass reuse on the landing push whenever a step was left out, which is every pull and batch run of it.

🤖 Generated with Claude Code

Approved

This adds on: {refs: [...]} to workflow steps and to steps in shared step files. A step is skipped unless the ref a push moved, or the ref a run was asked for at, matches it. A pull's run and a merge-queue batch's run match no ref. Skipped steps are logged with a reason and listed skipped, and the run still passes.

I read the diff against AGENTS.md and found nothing that must change:

  • Parsing: an on that names no refs is refused in Step::invalid, and deny_unknown_fields rejects other keys.
  • Nested shared steps: on is carried through expand as within, so every enclosing on has to match, which fits the stated behaviour.
  • Reuse: a run that skipped a step is not kept for the landing push, and its layers are not kept either. I checked the warms branch, which is not gated. It only applies to pulls_only repositories, where pushes never take kept passes, so it does not affect this.
  • Docs and changeset: the reference, the runner and reusable-workflows design pages, and a change file are all updated.

I did not run the tests. The body says they are left to CI, so check that check and test pass before merging.

Merged as 5bf7b54