v2.62.0
Released 2026-09-28. One minor release, three changes, all about selecting and ordering exactly what a change needs.
Binaries and the merged-pull-request list are on the GitHub releases page.
A dependency edge can set its own mode
A subscription's dependencyMode and dependencyRules set enforced or
advisory for every edge of a lane at once. A deploy lane that must wait on a
migration but not on its peer services had to choose one for all of them.
A dependsOn item now takes an optional mode (enforced, advisory or
disabled, the values dependencyMode accepts) and modeRules keyed by
triggerRef, first match wins:
dependsOn:
- component: db-migrate
mode: enforced
- component: peer-worker
mode: advisory
- component: identity-schema
mode: advisory
modeRules:
- mode: enforced
when: { triggerRef: github-push-main }
For one edge, a matching modeRules entry wins, then mode, then the lane's
own resolution (subscription rules, subscription dependencyMode, the
environment's, enforced). An edge with neither keeps today's behaviour.
Unknown modes, and a triggerRef no trigger binding declares, are rejected
at validation. See dependency rules.
change.inputs: files outside a component that change it
A changed file selects the component whose directory owns it. Files at the
root of a repository — a lockfile, turbo.json, shared tooling — belong to
no component, so under --changed they selected nothing. A component can now
list repository-root-relative globs next to change.watches:
spec:
change:
watches: [environments]
inputs:
- pnpm-lock.yaml
- turbo.json
- tooling/eslint/**
A changed file matching one selects the component as a direct change, and the
selection spreads over dependsOn input: true edges exactly as for an owned
file. ** crosses directories. Absolute paths, .. segments, backslashes and
malformed globs are rejected (component.spec.change.inputs.invalid).
--explain names the pattern that matched. Path ownership is unchanged, and a
component without inputs keeps its manifest hash. See
change detection.
--changed plans against the working tree's catalog
--changed refreshes the catalog before selecting, but the refresh reused a
cached snapshot keyed on git's view of the tree. A manifest git could not
see — a nested component.yml, one in an ignored directory, any edit outside
a git repository — left --changed planning against the old graph. The cache
key now includes a digest of every discovered manifest and intent.yaml, so
any manifest change rebuilds it; a fresh snapshot is still a cache hit. When a
refresh changes the component graph, --changed says so on stderr:
orun: catalog was stale (1 component added); refreshed from the working tree
plan --changed --no-catalog-refresh uses the snapshot as it is, warns when it
was not built from the working tree, and stops when there is none, naming
orun catalog refresh.