kubernetes – Report Tekton pipeline status to GitLab regardless if pipeline failed or succeeded (using gitlab-set-status Task)
kubernetes – Report Tekton pipeline status to GitLab regardless if pipeline failed or succeeded (using gitlab-set-status Task)
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 were 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 were 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 Pipelines 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: