v2.8.0
Release notes for orun v2.8.0.
Highlights
- Trigger-aware dependency policy (
dependencyMode/dependencyRules). Components and environments can now declare whetherdependsOnedges areenforced(default, blocks the executor),advisory(recorded as metadata on the plan but non-blocking) ordisabled(omitted), conditional on which trigger fired. Fast parallel pull-request validation without weakening the semantics of merge or release plans.
New: dependency rules
Three modes, all resolved at plan time so the compiled DAG remains the single audit artifact:
| Mode | DAG behavior | Typical use |
|---|---|---|
enforced | normal dependsOn edges | merges, releases, prod deploys |
advisory | edges recorded as advisoryDependsOn, not blocking | PR validation, previews |
disabled | edge omitted entirely | explicit independence / bypass |
Set a global default on an environment, override per component subscription,
and use first-match-wins dependencyRules for trigger-conditional behavior:
environments:
dev-preview:
activation:
triggerRefs: [github-pull-request]
dependencyMode: advisory
staging:
activation:
triggerRefs: [github-push-main]
dependencyMode: enforced
components:
- name: api
subscribe:
environments:
- name: dev-preview
profile: plan-only
dependencyMode: advisory
dependencyRules:
- mode: enforced
when:
triggerRef: github-push-main
Precedence
subscription.dependencyRules (first match wins) → subscription.dependencyMode
→ environment.dependencyMode → built-in enforced. The selected layer is
recorded on every job as dependencySource for plan-time auditability.
Plan output
For pull-request:
{
"id": "api@dev-preview.verify",
"dependsOn": [],
"advisoryDependsOn": ["database@dev-preview.verify"],
"dependencyMode": "advisory",
"dependencySource": "subscription-rule",
"dependencyRuleTriggerRef": "github-pull-request"
}
For push-to-main:
{
"id": "api@staging.verify",
"dependsOn": ["database@staging.verify"],
"dependencyMode": "enforced",
"dependencySource": "environment"
}
Viewer
orun plan --view dag annotates the environment header when a non-enforced
mode is active. orun plan --view dependencies distinguishes blocking from
advisory edges so reviewers can see what would normally block even on a
non-blocking PR plan.
Validation
orun validate now rejects:
dependencyModevalues outsideenforced | advisory | disabled.dependencyRules[].modeempty or invalid.dependencyRules[].when.triggerRefnot present inautomation.triggerBindings.
Why a separate axis from profile rules
Profile rules change what runs inside a job; dependency rules change whether one job waits for another. Keeping these axes independent keeps the plan DAG deterministic and reviewable. The clean split is:
TriggerBinding → which envs/components are planned
ProfileRules → which execution profile a job uses
DependencyRules → which dependency edges are enforced
Plan DAG → explicit, reviewable result
See Dependency rules for the full reference.
Compatibility
- Fully backward compatible. Components and environments without
dependencyModecontinue to behave exactly as before (enforcedis the implicit default). - New
PlanJobfields (advisoryDependsOn,dependencyMode,dependencySource,dependencyRuleTriggerRef) are allomitempty— existing plan consumers that ignore unknown fields are unaffected. - Executor semantics unchanged. The planner is the only component that
needs to understand the new modes; the executor still consumes the
dependsOnlist exactly as before.