Skip to content

Commit

Permalink
Add intial skeleton docs for conditions
Browse files Browse the repository at this point in the history
Signed-off-by: Dibyo Mukherjee <dibyo@google.com>
  • Loading branch information
dibyom committed Jul 30, 2019
1 parent e33c7ad commit 2742dde
Show file tree
Hide file tree
Showing 7 changed files with 105 additions and 11 deletions.
50 changes: 50 additions & 0 deletions docs/conditions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
# Conditions

This document defines `Conditions` and their capabilities.

*NOTE*: This feature is currently a WIP being tracked in [#1137](https://github.com/tektoncd/pipeline/issues/1137)

---

- [Syntax](#syntax)
- [Check](#check)
- [Examples](#examples)

## Syntax

To define a configuration file for a `Condition` resource, you can specify the
following fields:

- Required:
- [`apiVersion`][kubernetes-overview] - Specifies the API version, for example
`tekton.dev/v1alpha1`.
- [`kind`][kubernetes-overview] - Specify the `Condition` resource object.
- [`metadata`][kubernetes-overview] - Specifies data to uniquely identify the
`Condition` resource object, for example a `name`.
- [`spec`][kubernetes-overview] - Specifies the configuration information for
your `Condition` resource object. In order for a `Condition` to do anything,
the spec must include:
- [`check`](#check) - Specifies a container that you want to run for evaluating the condition

[kubernetes-overview]:
https://kubernetes.io/docs/concepts/overview/working-with-objects/kubernetes-objects/#required-fields

### Check

The `check` field is required. You define a single check to define the body of a `Condition`. The
check must specify a container image that adheres to the [container contract](./container-contract.md). The container image
runs till completion. The container must exit successfully i.e. with an exit code 0 for the
condition evaluation to be successful. All other exit codes are considered to be a condition check
failure.

## Examples

For complete examples, see
[the examples folder](https://github.com/tektoncd/pipeline/tree/master/examples).

---

Except as otherwise noted, the content of this page is licensed under the
[Creative Commons Attribution 4.0 License](https://creativecommons.org/licenses/by/4.0/),
and code samples are licensed under the
[Apache 2.0 License](https://www.apache.org/licenses/LICENSE-2.0).
24 changes: 24 additions & 0 deletions docs/pipelines.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@ following fields:
- [`retries`](#retries) - Used when the task is wanted to be executed if
it fails. Could a network error or a missing dependency. It does not
apply to cancellations.
- [`conditions`](#conditions) - Used when a task is to be executed only if the specified
conditons are evaluated to be true.

[kubernetes-overview]:
https://kubernetes.io/docs/concepts/overview/working-with-objects/kubernetes-objects/#required-fields
Expand Down Expand Up @@ -285,6 +287,28 @@ In this example, the task "build-the-image" will be executed and if the first
run fails a second one would triggered. But, if that fails no more would
triggered: a max of two executions.


#### conditions

Sometimes you will need to run tasks only when some conditions are true. The `conditions` field
allows you to list a series of references to [`Conditions`](./conditions.md) that are run before the task
is run. If all of the conditions evaluate to true, the task is run. If any of the conditions are false,
the Task is not run. Its status.ConditionSucceeded is set to False with the reason set to `ConditionCheckFailed`.
However, unlike regular task failures, condition failures do not automatically fail the entire pipeline
run -- other tasks that are not dependent on the task (via `from` or `runAfter`) are still run.

```yaml
tasks:
- name: conditional-task
taskRef:
name: build-push
conditions:
- conditionRef: my-condition
```

In this example, `my-condition` refers to a [Condition](#conditions) custom resource. The `build-push`
task will only be executed if the condition evaluates to true.

## Ordering

The [Pipeline Tasks](#pipeline-tasks) in a `Pipeline` can be connected and run
Expand Down
28 changes: 20 additions & 8 deletions pkg/apis/pipeline/register.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,25 @@ limitations under the License.

package pipeline

// GroupName is the Kubernetes resource group name for Pipeline types.
const (
GroupName = "tekton.dev"
TaskLabelKey = "/task"
TaskRunLabelKey = "/taskRun"
PipelineLabelKey = "/pipeline"
PipelineRunLabelKey = "/pipelineRun"
PipelineTaskLabelKey = "/pipelineTask"
PipelineRunConditionCheckKey = "/pipelineConditionCheck"
// GroupName is the Kubernetes resource group name for Pipeline types.
GroupName = "tekton.dev"

// TaskLabelKey is used as the label identifier for a task
TaskLabelKey = "/task"

// TaskRunLabelKey is used as the label identifier for a TaskRun
TaskRunLabelKey = "/taskRun"

// PipelineLabelKey is used as the label identifier for a Pipeline
PipelineLabelKey = "/pipeline"

// PipelineRunLabelKey is used as the label identifier for a PipelineRun
PipelineRunLabelKey = "/pipelineRun"

// PipelineRunLabelKey is used as the label identifier for a PipelineTask
PipelineTaskLabelKey = "/pipelineTask"

// ConditionCheck is used as the label identifier for a ConditionCheck
ConditionCheckKey = "/conditionCheck"
)
2 changes: 1 addition & 1 deletion pkg/reconciler/v1alpha1/pipelinerun/pipelinerun.go
Original file line number Diff line number Diff line change
Expand Up @@ -620,7 +620,7 @@ func (c *Reconciler) updateLabelsAndAnnotations(pr *v1alpha1.PipelineRun) (*v1al

func (c *Reconciler) makeConditionCheckContainer(rprt *resources.ResolvedPipelineRunTask, rcc *resources.ResolvedConditionCheck, pr *v1alpha1.PipelineRun) (*v1alpha1.ConditionCheck, error) {
labels := getTaskrunLabels(pr, rprt.PipelineTask.Name)
labels[pipeline.GroupName+pipeline.PipelineRunConditionCheckKey] = rcc.ConditionCheckName
labels[pipeline.GroupName+pipeline.ConditionCheckKey] = rcc.ConditionCheckName

tr := &v1alpha1.TaskRun{
ObjectMeta: metav1.ObjectMeta{
Expand Down
4 changes: 2 additions & 2 deletions pkg/reconciler/v1alpha1/pipelinerun/pipelinerun_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1362,7 +1362,7 @@ func TestReconcileWithFailingConditionChecks(t *testing.T) {
tb.TaskRunOwnerReference("kind", "name"),
tb.TaskRunLabel(pipeline.GroupName+pipeline.PipelineLabelKey, "test-pipeline-run-with-conditions"),
tb.TaskRunLabel(pipeline.GroupName+pipeline.PipelineRunLabelKey, "test-pipeline"),
tb.TaskRunLabel(pipeline.GroupName+pipeline.PipelineRunConditionCheckKey, conditionCheckName),
tb.TaskRunLabel(pipeline.GroupName+pipeline.ConditionCheckKey, conditionCheckName),
tb.TaskRunSpec(tb.TaskRunTaskSpec()),
tb.TaskRunStatus(tb.StatusCondition(apis.Condition{
Type: apis.ConditionSucceeded,
Expand Down Expand Up @@ -1429,7 +1429,7 @@ func makeExpectedTr(condName, ccName string) *v1alpha1.TaskRun {
tb.TaskRunLabel("tekton.dev/pipeline", "test-pipeline"),
tb.TaskRunLabel(pipeline.GroupName+pipeline.PipelineTaskLabelKey, "hello-world-1"),
tb.TaskRunLabel("tekton.dev/pipelineRun", "test-pipeline-run"),
tb.TaskRunLabel("tekton.dev/pipelineConditionCheck", ccName),
tb.TaskRunLabel("tekton.dev/conditionCheck", ccName),
tb.TaskRunAnnotation("PipelineRunAnnotation", "PipelineRunValue"),
tb.TaskRunSpec(
tb.TaskRunTaskSpec(tb.Step("condition-check-"+condName, "foo", tb.Args("bar"))),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ import (
)

const (
// unnamedCheckNamePrefix is the prefix added to the name of a condition's
// spec.Check.Image if the name is missing
unnamedCheckNamePrefix = "condition-check-"
)

Expand Down
6 changes: 6 additions & 0 deletions test/builder/pipeline_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,9 @@ func TestPipelineRun(t *testing.T) {
apis.Condition{Type: apis.ConditionSucceeded}),
tb.PipelineRunStartTime(startTime),
tb.PipelineRunCompletionTime(completedTime),
tb.PipelineRunTaskRunsStatus("trname", &v1alpha1.PipelineRunTaskRunStatus{
PipelineTaskName: "task-1",
}),
), tb.PipelineRunLabel("label-key", "label-value"))
expectedPipelineRun := &v1alpha1.PipelineRun{
ObjectMeta: metav1.ObjectMeta{
Expand Down Expand Up @@ -153,6 +156,9 @@ func TestPipelineRun(t *testing.T) {
},
StartTime: &metav1.Time{Time: startTime},
CompletionTime: &metav1.Time{Time: completedTime},
TaskRuns: map[string]*v1alpha1.PipelineRunTaskRunStatus{
"trname": {PipelineTaskName: "task-1"},
},
},
}
if d := cmp.Diff(expectedPipelineRun, pipelineRun); d != "" {
Expand Down

0 comments on commit 2742dde

Please sign in to comment.