We're already using the gitlab-set-status
Task from Tekton Hub to report our Tekton Pipeline's status back into our GitLab instance (here's our EKS setup & Tekton installment and a example project on gitlab.com). Our pipeline.yml
looks like this and currently reports the STATE
success every time the Tekton Pipeline runs:
apiVersion: tekton.dev/v1beta1
kind: Pipeline
metadata:
name: buildpacks-test-pipeline
spec:
params:
- name: IMAGE
type: string
description: image URL to push
- name: SOURCE_URL
type: string
description: A git repo url where the source code resides.
- name: REPO_PATH_ONLY
type: string
description: GitLab group & repo name only (e.g. jonashackt/microservice-api-spring-boot)
- name: SOURCE_REVISION
description: The branch, tag or SHA to checkout.
default: ""
- name: GITLAB_HOST
type: string
description: Your GitLabs host only (e.g. gitlab.com)
- name: TEKTON_DASHBOARD_HOST
type: string
description: The Tekton dashboard host name only
workspaces:
- name: source-workspace # Directory where application source is located. (REQUIRED)
- name: cache-workspace # Directory where cache is stored (OPTIONAL)
tasks:
- name: fetch-repository # This task fetches a repository from github, using the `git-clone` task you installed
taskRef:
name: git-clone
workspaces:
- name: output
workspace: source-workspace
params:
- name: url
value: "$(params.SOURCE_URL)"
- name: revision
value: "$(params.SOURCE_REVISION)"
- name: subdirectory
value: ""
- name: deleteExisting
value: "true"
- name: buildpacks # This task uses the `buildpacks` task to build the application
taskRef:
name: buildpacks
runAfter:
- fetch-repository
workspaces:
- name: source
workspace: source-workspace
- name: cache
workspace: cache-workspace
params:
- name: APP_IMAGE
value: "$(params.IMAGE)"
- name: BUILDER_IMAGE
value: paketobuildpacks/builder:base # This is the builder we want the task to use (REQUIRED)
- name: report-pipeline-end-to-gitlab
taskRef:
name: "gitlab-set-status"
runAfter:
- buildpacks
params:
- name: "STATE"
value: "success"
- name: "GITLAB_HOST_URL"
value: "$(params.GITLAB_HOST)"
- name: "REPO_FULL_NAME"
value: "$(params.REPO_PATH_ONLY)"
- name: "GITLAB_TOKEN_SECRET_NAME"
value: "gitlab-api-secret"
- name: "GITLAB_TOKEN_SECRET_KEY"
value: "token"
- name: "SHA"
value: "$(params.SOURCE_REVISION)"
- name: "TARGET_URL"
value: "$(params.TEKTON_DASHBOARD_HOST)/#/namespaces/default/pipelineruns/$(context.pipelineRun.name)"
- name: "CONTEXT"
value: "tekton-pipeline"
- name: "DESCRIPTION"
value: "Finished building your commit in Tekton"
How can we enhance our Tekton Pipeline to report the status correctly and regardless of any failure or success to GitLab?
In v0.14 Tekton introduced the so called finally
Tasks, which run at the end of every Pipeline
- regardless which Task failed or succeeded. As the docs state:
finally tasks are guaranteed to be executed in parallel after all PipelineTasks under tasks have completed regardless of success or error.
In general finally
tasks look like this:
spec:
tasks:
- name: tests
taskRef:
name: integration-test
finally:
- name: cleanup-test
taskRef:
name: cleanup
But how do we create the corresponding STATE
in our gitlab-set-status
Task? With using when
expressions inside our finally
tasks we can run our gitlab-set-status
Task based on the overall Pipeline status (or Aggregate Pipeline status):
finally:
- name: notify-any-failure # executed only when one or more tasks fail
when:
- input: $(tasks.status)
operator: in
values: ["Failed"]
taskRef:
name: notify-failure
We grab the Aggregate Execution Status by simply using $(tasks.status)
. This variable is stated to have those 4 possible status:
Succeeded
("all tasks have succeeded")Completed
("all tasks completed successfully including one or more skipped tasks")-> which could be translated into the gitlab-set-status
Tasks STATE
value success
.
Failed
("one ore more tasks failed")None
("no aggregate execution status available (i.e. none of the above), one or more tasks could be pending/running/cancelled/timedout")-> which could both be translated into the gitlab-set-status
Tasks STATE
value failed
. For None
this is only valid, since we're in a finally task
, since pending/running
could otherwise also mean that a Pipeline is in a good state.
Having 4 states we need to check in our when
expressions, do we need to implement a separate finally Task for each of them? No, since luckily the when
expressions "values is an array of string values.". So we're able to do
when:
- input: $(tasks.status)
operator: in
values: [ "Failed", "None" ]
and
when:
- input: $(tasks.status)
operator: in
values: [ "Succeeded", "Completed" ]
Finally this results in our Tekton Pipeline's locking like this (and implementing 2 finally tasks report-pipeline-failed-to-gitlab
and report-pipeline-success-to-gitlab
):
...
finally:
- name: report-pipeline-failed-to-gitlab
when:
- input: $(tasks.status)
operator: in
values: [ "Failed", "None" ] # see aggregated status https://tekton.dev/docs/pipelines/pipelines/#using-aggregate-execution-status-of-all-tasks
taskRef:
name: "gitlab-set-status"
params:
- name: "STATE"
value: "failed"
- name: "GITLAB_HOST_URL"
value: "$(params.GITLAB_HOST)"
- name: "REPO_FULL_NAME"
value: "$(params.REPO_PATH_ONLY)"
- name: "GITLAB_TOKEN_SECRET_NAME"
value: "gitlab-api-secret"
- name: "GITLAB_TOKEN_SECRET_KEY"
value: "token"
- name: "SHA"
value: "$(params.SOURCE_REVISION)"
- name: "TARGET_URL"
value: "$(params.TEKTON_DASHBOARD_HOST)/#/namespaces/default/pipelineruns/$(context.pipelineRun.name)"
- name: "CONTEXT"
value: "tekton-pipeline"
- name: "DESCRIPTION"
value: "An error occurred building your commit in Tekton"
- name: report-pipeline-success-to-gitlab
when:
- input: $(tasks.status)
operator: in
values: [ "Succeeded", "Completed" ] # see aggregated status https://tekton.dev/docs/pipelines/pipelines/#using-aggregate-execution-status-of-all-tasks
taskRef:
name: "gitlab-set-status"
params:
- name: "STATE"
value: "success"
- name: "GITLAB_HOST_URL"
value: "$(params.GITLAB_HOST)"
- name: "REPO_FULL_NAME"
value: "$(params.REPO_PATH_ONLY)"
- name: "GITLAB_TOKEN_SECRET_NAME"
value: "gitlab-api-secret"
- name: "GITLAB_TOKEN_SECRET_KEY"
value: "token"
- name: "SHA"
value: "$(params.SOURCE_REVISION)"
- name: "TARGET_URL"
value: "$(params.TEKTON_DASHBOARD_HOST)/#/namespaces/default/pipelineruns/$(context.pipelineRun.name)"
- name: "CONTEXT"
value: "tekton-pipeline"
- name: "DESCRIPTION"
value: "Finished building your commit in Tekton"
Executing our Tekton Pipeline should now be reported correctly to our GitLab. Failures look like this:
Succeeded Pipelines look like this: