Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .spelling
Original file line number Diff line number Diff line change
Expand Up @@ -289,7 +289,9 @@ v3.6.1
v3.6.5
v3.7
v3.7.0
v3.7.15
v4.0
v4.0.6
validator
vendored
versioned
Expand Down
86 changes: 86 additions & 0 deletions docs/fields.md
Original file line number Diff line number Diff line change
Expand Up @@ -315,6 +315,12 @@ Workflow is the definition of a workflow resource

- [`sidecar.yaml`](https://github.com/argoproj/argo-workflows/blob/main/examples/sidecar.yaml)

- [`consumer-input-default.yaml`](https://github.com/argoproj/argo-workflows/blob/main/examples/skipped-output-defaults/consumer-input-default.yaml)

- [`expression-fallback.yaml`](https://github.com/argoproj/argo-workflows/blob/main/examples/skipped-output-defaults/expression-fallback.yaml)

- [`producer-output-default.yaml`](https://github.com/argoproj/argo-workflows/blob/main/examples/skipped-output-defaults/producer-output-default.yaml)

- [`status-reference.yaml`](https://github.com/argoproj/argo-workflows/blob/main/examples/status-reference.yaml)

- [`step-level-timeout.yaml`](https://github.com/argoproj/argo-workflows/blob/main/examples/step-level-timeout.yaml)
Expand Down Expand Up @@ -800,6 +806,12 @@ WorkflowSpec is the specification of a Workflow.

- [`sidecar.yaml`](https://github.com/argoproj/argo-workflows/blob/main/examples/sidecar.yaml)

- [`consumer-input-default.yaml`](https://github.com/argoproj/argo-workflows/blob/main/examples/skipped-output-defaults/consumer-input-default.yaml)

- [`expression-fallback.yaml`](https://github.com/argoproj/argo-workflows/blob/main/examples/skipped-output-defaults/expression-fallback.yaml)

- [`producer-output-default.yaml`](https://github.com/argoproj/argo-workflows/blob/main/examples/skipped-output-defaults/producer-output-default.yaml)

- [`status-reference.yaml`](https://github.com/argoproj/argo-workflows/blob/main/examples/status-reference.yaml)

- [`step-level-timeout.yaml`](https://github.com/argoproj/argo-workflows/blob/main/examples/step-level-timeout.yaml)
Expand Down Expand Up @@ -1266,6 +1278,12 @@ CronWorkflowSpec is the specification of a CronWorkflow

- [`sidecar.yaml`](https://github.com/argoproj/argo-workflows/blob/main/examples/sidecar.yaml)

- [`consumer-input-default.yaml`](https://github.com/argoproj/argo-workflows/blob/main/examples/skipped-output-defaults/consumer-input-default.yaml)

- [`expression-fallback.yaml`](https://github.com/argoproj/argo-workflows/blob/main/examples/skipped-output-defaults/expression-fallback.yaml)

- [`producer-output-default.yaml`](https://github.com/argoproj/argo-workflows/blob/main/examples/skipped-output-defaults/producer-output-default.yaml)

- [`status-reference.yaml`](https://github.com/argoproj/argo-workflows/blob/main/examples/status-reference.yaml)

- [`step-level-timeout.yaml`](https://github.com/argoproj/argo-workflows/blob/main/examples/step-level-timeout.yaml)
Expand Down Expand Up @@ -1570,6 +1588,10 @@ Arguments to a template

- [`scripts-python.yaml`](https://github.com/argoproj/argo-workflows/blob/main/examples/scripts-python.yaml)

- [`consumer-input-default.yaml`](https://github.com/argoproj/argo-workflows/blob/main/examples/skipped-output-defaults/consumer-input-default.yaml)

- [`producer-output-default.yaml`](https://github.com/argoproj/argo-workflows/blob/main/examples/skipped-output-defaults/producer-output-default.yaml)

- [`step-level-timeout.yaml`](https://github.com/argoproj/argo-workflows/blob/main/examples/step-level-timeout.yaml)

- [`steps-daemon-retry-strategy.yaml`](https://github.com/argoproj/argo-workflows/blob/main/examples/steps-daemon-retry-strategy.yaml)
Expand Down Expand Up @@ -2098,6 +2120,12 @@ Outputs hold parameters, artifacts, and results from a step

- [`pod-spec-from-previous-step.yaml`](https://github.com/argoproj/argo-workflows/blob/main/examples/pod-spec-from-previous-step.yaml)

- [`consumer-input-default.yaml`](https://github.com/argoproj/argo-workflows/blob/main/examples/skipped-output-defaults/consumer-input-default.yaml)

- [`expression-fallback.yaml`](https://github.com/argoproj/argo-workflows/blob/main/examples/skipped-output-defaults/expression-fallback.yaml)

- [`producer-output-default.yaml`](https://github.com/argoproj/argo-workflows/blob/main/examples/skipped-output-defaults/producer-output-default.yaml)

- [`suspend-template-outputs.yaml`](https://github.com/argoproj/argo-workflows/blob/main/examples/suspend-template-outputs.yaml)

- [`webhdfs-input-output-artifacts.yaml`](https://github.com/argoproj/argo-workflows/blob/main/examples/webhdfs-input-output-artifacts.yaml)
Expand Down Expand Up @@ -2462,6 +2490,12 @@ Parameter indicate a passed string parameter to a service template with an optio

- [`scripts-python.yaml`](https://github.com/argoproj/argo-workflows/blob/main/examples/scripts-python.yaml)

- [`consumer-input-default.yaml`](https://github.com/argoproj/argo-workflows/blob/main/examples/skipped-output-defaults/consumer-input-default.yaml)

- [`expression-fallback.yaml`](https://github.com/argoproj/argo-workflows/blob/main/examples/skipped-output-defaults/expression-fallback.yaml)

- [`producer-output-default.yaml`](https://github.com/argoproj/argo-workflows/blob/main/examples/skipped-output-defaults/producer-output-default.yaml)

- [`step-level-timeout.yaml`](https://github.com/argoproj/argo-workflows/blob/main/examples/step-level-timeout.yaml)

- [`steps-daemon-retry-strategy.yaml`](https://github.com/argoproj/argo-workflows/blob/main/examples/steps-daemon-retry-strategy.yaml)
Expand Down Expand Up @@ -2762,6 +2796,12 @@ DAGTemplate is a template subtype for directed acyclic graph templates

- [`resubmit.yaml`](https://github.com/argoproj/argo-workflows/blob/main/examples/resubmit.yaml)

- [`consumer-input-default.yaml`](https://github.com/argoproj/argo-workflows/blob/main/examples/skipped-output-defaults/consumer-input-default.yaml)

- [`expression-fallback.yaml`](https://github.com/argoproj/argo-workflows/blob/main/examples/skipped-output-defaults/expression-fallback.yaml)

- [`producer-output-default.yaml`](https://github.com/argoproj/argo-workflows/blob/main/examples/skipped-output-defaults/producer-output-default.yaml)

- [`dag.yaml`](https://github.com/argoproj/argo-workflows/blob/main/examples/workflow-template/dag.yaml)

- [`templates.yaml`](https://github.com/argoproj/argo-workflows/blob/main/examples/workflow-template/templates.yaml)
Expand Down Expand Up @@ -3061,6 +3101,10 @@ Inputs are the mechanism for passing parameters, artifacts, volumes from one tem

- [`scripts-python.yaml`](https://github.com/argoproj/argo-workflows/blob/main/examples/scripts-python.yaml)

- [`consumer-input-default.yaml`](https://github.com/argoproj/argo-workflows/blob/main/examples/skipped-output-defaults/consumer-input-default.yaml)

- [`producer-output-default.yaml`](https://github.com/argoproj/argo-workflows/blob/main/examples/skipped-output-defaults/producer-output-default.yaml)

- [`step-level-timeout.yaml`](https://github.com/argoproj/argo-workflows/blob/main/examples/step-level-timeout.yaml)

- [`steps-daemon-retry-strategy.yaml`](https://github.com/argoproj/argo-workflows/blob/main/examples/steps-daemon-retry-strategy.yaml)
Expand Down Expand Up @@ -3902,6 +3946,12 @@ ValueFrom describes a location in which to obtain the value to a parameter

- [`secrets.yaml`](https://github.com/argoproj/argo-workflows/blob/main/examples/secrets.yaml)

- [`consumer-input-default.yaml`](https://github.com/argoproj/argo-workflows/blob/main/examples/skipped-output-defaults/consumer-input-default.yaml)

- [`expression-fallback.yaml`](https://github.com/argoproj/argo-workflows/blob/main/examples/skipped-output-defaults/expression-fallback.yaml)

- [`producer-output-default.yaml`](https://github.com/argoproj/argo-workflows/blob/main/examples/skipped-output-defaults/producer-output-default.yaml)

- [`suspend-template-outputs.yaml`](https://github.com/argoproj/argo-workflows/blob/main/examples/suspend-template-outputs.yaml)

- [`event-consumer-workfloweventbinding.yaml`](https://github.com/argoproj/argo-workflows/blob/main/examples/workflow-event-binding/event-consumer-workfloweventbinding.yaml)
Expand Down Expand Up @@ -4182,6 +4232,12 @@ DAGTask represents a node in the graph during DAG execution Note: CEL validation

- [`resubmit.yaml`](https://github.com/argoproj/argo-workflows/blob/main/examples/resubmit.yaml)

- [`consumer-input-default.yaml`](https://github.com/argoproj/argo-workflows/blob/main/examples/skipped-output-defaults/consumer-input-default.yaml)

- [`expression-fallback.yaml`](https://github.com/argoproj/argo-workflows/blob/main/examples/skipped-output-defaults/expression-fallback.yaml)

- [`producer-output-default.yaml`](https://github.com/argoproj/argo-workflows/blob/main/examples/skipped-output-defaults/producer-output-default.yaml)

- [`dag.yaml`](https://github.com/argoproj/argo-workflows/blob/main/examples/workflow-template/dag.yaml)

- [`templates.yaml`](https://github.com/argoproj/argo-workflows/blob/main/examples/workflow-template/templates.yaml)
Expand Down Expand Up @@ -4809,6 +4865,12 @@ _No description available_

- [`secrets.yaml`](https://github.com/argoproj/argo-workflows/blob/main/examples/secrets.yaml)

- [`consumer-input-default.yaml`](https://github.com/argoproj/argo-workflows/blob/main/examples/skipped-output-defaults/consumer-input-default.yaml)

- [`expression-fallback.yaml`](https://github.com/argoproj/argo-workflows/blob/main/examples/skipped-output-defaults/expression-fallback.yaml)

- [`producer-output-default.yaml`](https://github.com/argoproj/argo-workflows/blob/main/examples/skipped-output-defaults/producer-output-default.yaml)

- [`suspend-template-outputs.yaml`](https://github.com/argoproj/argo-workflows/blob/main/examples/suspend-template-outputs.yaml)

- [`event-consumer-workfloweventbinding.yaml`](https://github.com/argoproj/argo-workflows/blob/main/examples/workflow-event-binding/event-consumer-workfloweventbinding.yaml)
Expand Down Expand Up @@ -5198,6 +5260,12 @@ ObjectMeta is metadata that all persisted resources must have, which includes al

- [`sidecar.yaml`](https://github.com/argoproj/argo-workflows/blob/main/examples/sidecar.yaml)

- [`consumer-input-default.yaml`](https://github.com/argoproj/argo-workflows/blob/main/examples/skipped-output-defaults/consumer-input-default.yaml)

- [`expression-fallback.yaml`](https://github.com/argoproj/argo-workflows/blob/main/examples/skipped-output-defaults/expression-fallback.yaml)

- [`producer-output-default.yaml`](https://github.com/argoproj/argo-workflows/blob/main/examples/skipped-output-defaults/producer-output-default.yaml)

- [`status-reference.yaml`](https://github.com/argoproj/argo-workflows/blob/main/examples/status-reference.yaml)

- [`step-level-timeout.yaml`](https://github.com/argoproj/argo-workflows/blob/main/examples/step-level-timeout.yaml)
Expand Down Expand Up @@ -5815,6 +5883,12 @@ A single application container that you want to run within a pod.

- [`sidecar.yaml`](https://github.com/argoproj/argo-workflows/blob/main/examples/sidecar.yaml)

- [`consumer-input-default.yaml`](https://github.com/argoproj/argo-workflows/blob/main/examples/skipped-output-defaults/consumer-input-default.yaml)

- [`expression-fallback.yaml`](https://github.com/argoproj/argo-workflows/blob/main/examples/skipped-output-defaults/expression-fallback.yaml)

- [`producer-output-default.yaml`](https://github.com/argoproj/argo-workflows/blob/main/examples/skipped-output-defaults/producer-output-default.yaml)

- [`status-reference.yaml`](https://github.com/argoproj/argo-workflows/blob/main/examples/status-reference.yaml)

- [`step-level-timeout.yaml`](https://github.com/argoproj/argo-workflows/blob/main/examples/step-level-timeout.yaml)
Expand Down Expand Up @@ -6835,6 +6909,12 @@ ImageVolumeSource represents a image volume resource.

- [`sidecar.yaml`](https://github.com/argoproj/argo-workflows/blob/main/examples/sidecar.yaml)

- [`consumer-input-default.yaml`](https://github.com/argoproj/argo-workflows/blob/main/examples/skipped-output-defaults/consumer-input-default.yaml)

- [`expression-fallback.yaml`](https://github.com/argoproj/argo-workflows/blob/main/examples/skipped-output-defaults/expression-fallback.yaml)

- [`producer-output-default.yaml`](https://github.com/argoproj/argo-workflows/blob/main/examples/skipped-output-defaults/producer-output-default.yaml)

- [`status-reference.yaml`](https://github.com/argoproj/argo-workflows/blob/main/examples/status-reference.yaml)

- [`step-level-timeout.yaml`](https://github.com/argoproj/argo-workflows/blob/main/examples/step-level-timeout.yaml)
Expand Down Expand Up @@ -7128,6 +7208,12 @@ EnvVarSource represents a source for the value of an EnvVar.

- [`secrets.yaml`](https://github.com/argoproj/argo-workflows/blob/main/examples/secrets.yaml)

- [`consumer-input-default.yaml`](https://github.com/argoproj/argo-workflows/blob/main/examples/skipped-output-defaults/consumer-input-default.yaml)

- [`expression-fallback.yaml`](https://github.com/argoproj/argo-workflows/blob/main/examples/skipped-output-defaults/expression-fallback.yaml)

- [`producer-output-default.yaml`](https://github.com/argoproj/argo-workflows/blob/main/examples/skipped-output-defaults/producer-output-default.yaml)

- [`suspend-template-outputs.yaml`](https://github.com/argoproj/argo-workflows/blob/main/examples/suspend-template-outputs.yaml)

- [`event-consumer-workfloweventbinding.yaml`](https://github.com/argoproj/argo-workflows/blob/main/examples/workflow-event-binding/event-consumer-workfloweventbinding.yaml)
Expand Down
2 changes: 2 additions & 0 deletions docs/lifecyclehook.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ In other words, a `LifecycleHook` functions like an [exit handler](https://githu
- [`templateRef`](fields.md#templateref)
- [`arguments`](https://github.com/argoproj/argo-workflows/blob/main/examples/conditionals.yaml)

Hook arguments and expressions that reference outputs of a skipped or omitted step resolve according to [Outputs of Skipped and Omitted Nodes](variables.md#outputs-of-skipped-and-omitted-nodes).

## Unsupported conditions

- [`outputs`](fields.md#outputs) are not usable since `LifecycleHook` executes during execution time and `outputs` are not produced until the step is completed. You can use outputs from previous steps, just not the one you're hooking into. If you'd like to use outputs create an exit handler instead - all the status variable are available there so you can still conditionally decide what to do.
Expand Down
13 changes: 13 additions & 0 deletions docs/upgrading.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,19 @@ This variable controlled whether to write workflow updates back to the informer
Alternative mechanisms now prevent reprocessing, making both behaviors unnecessary.
If you have this variable set, it can be safely removed from your configuration.

## Upgrading to v4.0.6 and v3.7.15

### Outputs of skipped and omitted steps and tasks now resolve

In v4.0.5, v3.7.14, and earlier, referencing an output parameter of a step or task that was Skipped (its `when` condition was false) or Omitted (its `depends` condition was not satisfied) could leave the consumer stuck: simple tag references requeued forever and expression references failed.

These references now resolve.
If the producing template declares a `valueFrom.default` for the output, references resolve to that default.
Otherwise the output is treated as absent: simple tags substitute an empty string, an argument that is purely such a reference lets the consuming input's `default` apply, and expression tags see `nil` so `??` fallbacks work.
An expression that does not handle the `nil` (for example a bare `{{= tasks.producer.outputs.parameters.msg}}` without `??`) fails the node with an error instead of leaving the workflow stuck.

See [Outputs of Skipped and Omitted Nodes](variables.md#outputs-of-skipped-and-omitted-nodes) for the full rules.

## Upgrading to v4.0

### Deprecations
Expand Down
27 changes: 25 additions & 2 deletions docs/variables.md
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,7 @@ sprig.trim(inputs.parameters['my-string-param'])
| `steps.<STEPNAME>.outputs.parameters.<NAME>` | Output parameter of any previous step. When the previous step uses `withItems` or `withParams`, this contains a JSON array of the output parameter values of each invocation |
| `steps.<STEPNAME>.outputs.artifacts.<NAME>` | Output artifact of any previous step |

**Note:** If a step was Skipped (its `when` condition was false), output parameters and results from that step resolve to empty strings.
**Note:** If a step was Skipped (its `when` condition was false), references to its outputs resolve according to the rules in [Outputs of Skipped and Omitted Nodes](#outputs-of-skipped-and-omitted-nodes).

### DAG Templates

Expand All @@ -173,7 +173,30 @@ sprig.trim(inputs.parameters['my-string-param'])
| `tasks.<TASKNAME>.outputs.parameters.<NAME>` | Output parameter of any previous task. When the previous task uses `withItems` or `withParams`, this contains a JSON array of the output parameter values of each invocation |
| `tasks.<TASKNAME>.outputs.artifacts.<NAME>` | Output artifact of any previous task |

**Note:** If a task was Skipped (its `when` condition was false) or Omitted (its `depends` condition was not satisfied), output parameters and results from that task resolve to empty strings.
**Note:** If a task was Skipped (its `when` condition was false) or Omitted (its `depends` condition was not satisfied), references to its outputs resolve according to the rules in [Outputs of Skipped and Omitted Nodes](#outputs-of-skipped-and-omitted-nodes).

### Outputs of Skipped and Omitted Nodes

> v3.7.15, v4.0.6, and after

A step or task that was Skipped (its `when` condition was false) or Omitted (its `depends` condition was not satisfied) never ran, so it produced no outputs.
References to its declared output parameters and `outputs.result` resolve as follows:

1. If the producing template declares a `valueFrom.default` for the output parameter, every reference resolves to that default.
1. Otherwise the output is *absent*, which is not the same as an empty string:
* A simple tag such as `{{steps.producer.outputs.parameters.msg}}` substitutes the empty string.
* If an argument consists solely of such a reference and the consuming template's input parameter declares a `default`, the argument is omitted so that input default applies.
* An expression tag sees the value as `nil`. Use the `??` operator to choose a fallback, e.g. `{{= steps.producer.outputs.parameters.msg ?? 'fallback'}}`.
* An expression that does not handle the `nil` fails the node with an error: a bare `{{= steps.producer.outputs.parameters.msg}}`, or an operation on it such as `+ '-suffix'`.

These rules apply wherever the reference appears: step and task arguments, `when` clauses, [`LifecycleHook`](lifecyclehook.md) and exit handler arguments and expressions, and the enclosing template's `outputs.parameters`.
In template outputs, a `valueFrom.default` declared on the aggregating output parameter applies when its `valueFrom.parameter` reference is absent or its `valueFrom.expression` fails.

A legitimately empty output is **not** absent: if the producer ran and wrote an empty string, `??` does not fire and the empty string is substituted.
For the same reason, an expression comparison such as `{{= steps.producer.outputs.parameters.msg == ''}}` is false when the producer was skipped, because `nil` is not equal to `''`.
Declare `valueFrom.default: ""` on the producer's output if you want a skipped output to behave exactly like an empty one.

See the [skipped output defaults examples](https://github.com/argoproj/argo-workflows/tree/main/examples/skipped-output-defaults) for runnable workflows demonstrating each rule.

### HTTP Templates

Expand Down
3 changes: 3 additions & 0 deletions docs/walk-through/output-parameters.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,9 @@ spec:
DAG templates use the tasks prefix to refer to another task, for example `{{tasks.generate-parameter.outputs.parameters.hello-param}}`.

If the producing step or task was skipped or omitted, you can declare a `valueFrom.default` on its output parameter to provide a value for that case.
See [Outputs of Skipped and Omitted Nodes](../variables.md#outputs-of-skipped-and-omitted-nodes) for how such references resolve.

## `result` output parameter

For script and container templates, the `result` output parameter captures up to 256 kb of the standard output.
Expand Down
Loading