How do you implement conditional execution with When Expressions in Tekton?
Quick Answer
When Expressions in Tekton allow you to conditionally skip Tasks in a Pipeline by evaluating an input value against a set of allowed values using the In or NotIn operators, enabling branching logic such as skipping deployment when tests fail or running specific tasks only for certain branches.
Detailed Answer
Think of When Expressions like a bouncer at a club entrance. Before each Task is allowed to execute, the bouncer checks the guest list. If the Task passes the check, it enters and runs. If it fails the check, it is politely turned away and marked as skipped rather than failed. This skip behavior is important because it means the overall Pipeline can still succeed even when some Tasks are conditionally skipped, unlike a failed Task which would cause the Pipeline to fail.
When Expressions are defined at the Task level within a Pipeline using the when field. Each when expression consists of three parts: an input value that can be a static string or a variable reference, an operator which is either In or NotIn, and a values array containing the allowed or disallowed strings to compare against. The input is evaluated against the values list using the specified operator. If all when expressions on a Task evaluate to true, the Task executes. If any single when expression evaluates to false, the entire Task is skipped. The input field commonly references Pipeline parameters using $(params.paramname), Task results using $(tasks.taskname.results.resultname), or context variables like $(context.pipeline.name). This makes when expressions dynamic and responsive to runtime values rather than being hardcoded at definition time.
In production pipelines, when expressions enable sophisticated branching patterns without requiring separate Pipeline definitions for each workflow variation. Consider a CI/CD pipeline for the checkout-service where the team wants to run integration tests only on pull request branches but skip them on feature branches to save cluster resources. A when expression with input $(params.branch) operator In values ["refs/heads/main", "refs/heads/release/*"] on the integration-test Task ensures that only main and release branches get the full test suite. For the deploy-to-staging Task, a when expression checks that the preceding security-scan Task produced a result of pass using input $(tasks.security-scan.results.status) operator In values ["pass"]. If the scan found critical vulnerabilities and reported fail, the deployment Task is skipped entirely, preventing vulnerable code from reaching any environment.
The behavior of downstream Tasks when an upstream Task is skipped deserves special attention. In Tekton v0.44 and later, you can configure the scope-when-expressions-to-task feature flag to control whether a skipped Task causes its downstream dependents to also be skipped. With this flag set to true, only the Task with the failing when expression is skipped, and downstream Tasks that depend on it via runAfter but do not reference its results will still execute. Without this flag, the default behavior cascades the skip to all downstream Tasks, effectively creating a short-circuit in the Pipeline. Understanding this distinction is crucial for designing pipelines where some branches should continue even when a conditional Task is skipped. For instance, in an order-processing-service pipeline, you might want the notification Task to run regardless of whether the optional performance-test Task was skipped.
A common mistake is trying to use when expressions for complex boolean logic with AND and OR combinations. When expressions only support simple equality checks with In and NotIn operators. If you need to evaluate whether a branch is main AND the test result is pass, you add two separate when expressions to the same Task, because multiple when expressions are evaluated with AND logic. For OR logic, you must restructure your Pipeline or use a preceding Task that evaluates the complex condition and writes a single result that the when expression can check. Another gotcha is that skipped Tasks do not produce results, so any downstream Task referencing results from a potentially skipped Task will fail with a missing result error. Always design your Pipeline DAG so that Tasks consuming results only depend on Tasks that are guaranteed to execute. Use the tkn pipelinerun describe command to inspect which Tasks were skipped and why, which is invaluable for debugging conditional execution flows in production.