Building Tekton tasks as bundles in Konflux
This document provides a step-by-step guide on how to onboard your Tekton tasks to Konflux, build them as OCI bundles and release them.
Prerequisites
Before you begin, ensure you have the following:
-
A GitHub repository containing your Tekton tasks. Use a flat layout with one YAML file per task, along with supporting files:
task/ └── echo/ ├── echo.yaml ├── CHANGELOG.md ├── README.md ├── USAGE.md └── TROUBLESHOOT.mdIf you maintain multiple version streams, use a subdirectory for the older stream:
task/ └── echo/ ├── 1.x/ │ └── echo.yaml ├── echo.yaml ├── CHANGELOG.md └── README.md -
Konflux GitHub application installed in the repository GitHub App
-
Access to the Konflux environment.
-
Necessary permissions to create and manage components in Konflux.
-
An OCI registry to contain the artifacts
Onboarding Steps
Onboarding tasks to Konflux is similar to onboarding other applications and components, except that you do not need a Containerfile since you are not building container images.
Application, Components and ImageRepository
Tekton tasks are built as standard OCI artifacts in Konflux.
Refer to the Creating applications and components page for information on how to create an Application for your tasks and a Component for each task within this Application, as well as an ImageRepository resource.
|
Once these resources are created, a PR with on-pr and push PipelineRuns is sent to your repository.
However, a conflict can arise when using on-cel-expression to control the execution of a pipeline in conjunction with a GitHub branch protection rule that mandates the pipeline’s successful completion. If the conditions of the on-cel-expression are not met, the pipeline does not run. However, the branch protection rule still expects a "passing" status, causing the check to remain pending and blocking the merge. For example:
The echo-pull-request does not run because the condition in the on-cel-expression is not met, but the GitHub branch protection expects it to run and end successfully before merge. In this case, update the on-cel-expression in the on-pr PipelineRun:
|
Versioning
Each meaningful change to a task requires a version bump. Define version numbers statically in the app.kubernetes.io/version label of the Task YAML. The build pipeline reads this label and sets the org.opencontainers.image.version OCI annotation on the bundle automatically.
For tasks in initial development (0.x):
-
Bump the minor version for breaking changes (for example,
0.1to0.2). -
Bump the patch version for non-breaking changes (for example,
0.1.0to0.1.1).
Once a task is mature, move it to 1.0 and follow Semantic Versioning.
Non-meaningful changes such as formatting or description updates do not require a version bump.
Changelog
Maintain a CHANGELOG.md file for each task at the root of the task directory (for example, task/echo/CHANGELOG.md). Follow the Keep a Changelog format: use a heading for each version with a release date, and group changes under standard categories.
Example:
# Changelog
All notable changes to this project will be documented in this file.
## 0.2.0
### Changed
- BREAKING: Replaced the `verbose` parameter with `log-level` for finer control
over output verbosity. To migrate, replace `verbose: "true"` with
`log-level: "debug"` in your PipelineRun parameters.
### Fixed
- Fixed incorrect exit code when the task times out.
## 0.1.0
### Added
- Initial release of the echo task.
|
Prefix breaking changes with |
Release
Release tasks only when their version number changes. Each released bundle should correspond to a deliberate, versioned change. When merging changes to a task, include a version bump in the app.kubernetes.io/version label and a changelog entry.
By default, Konflux automatically releases every merge. To release only when the version changes, you can either trigger releases manually or use automatic version-based releases.
| Automatic version-based releases, where the build pipeline detects version bumps and skips the release when the version has not changed, are currently in a final stage of development. See Auto-release logic for details. |
Manual releases
To trigger releases manually, set auto-release to "false" in the ReleasePlan. After merging a PR that bumps the task version, trigger the release:
-
Through the Konflux UI: navigate to Applications → select the application → Snapshots → click the three-dot menu on the snapshot → Trigger release.
-
By creating a
ReleaseCR. See Creating a release for details.
Release resources
The release process for bundles includes both the release of Tekton tasks as bundles and updating the list of trusted-tasks OCI artifacts.
This list is used to notify the Conforma policies of your trusted tasks. As a preparation for the release, choose a repository path in your public registry organization to hold this artifact.
The repository should be in the same level as our released tasks. For example, if our tasks are released to <OCI registry>/<Organization>/my-team-tasks, we should publish the list to a public repository named <OCI registry>/<Organization>/my-team-tasks/data-acceptable-bundles
So that the structure will be:
OCI registry/
└── Organization/
└── my-team-tasks/
├── task1
├── task2
├── task3
└── data-acceptable-bundles
To release Tekton tasks as bundles, create the following resources:
-
ReleasePlan in your namespace
Example:
apiVersion: appstudio.redhat.com/v1alpha1
kind: ReleasePlan
metadata:
labels:
release.appstudio.openshift.io/auto-release: "true"
release.appstudio.openshift.io/releasePlanAdmission: my-tasks
release.appstudio.openshift.io/standing-attribution: "true"
name: my-tasks-release-to-quay-konflux-ser
namespace: my-tasks-tenant
spec:
application: my-tasks
target: rhtap-releng-tenant
-
ReleasePlanAdmission in your managed namespace.
Example:
apiVersion: appstudio.redhat.com/v1alpha1
kind: ReleasePlanAdmission
metadata:
name: my-tasks
namespace: rhtap-releng-tenant
labels:
release.appstudio.openshift.io/block-releases: 'false'
pp.engineering.redhat.com/business-unit: application-developer
spec:
applications:
- my-tasks
policy: tekton-bundle-standard
origin: my-tasks-tenant
data:
releaseNotes:
product_name: My-Tasks
product_version: "0.1"
mapping:
registrySecret: <Secret to your registry organization> (1)
defaults:
public: true
pushSourceContainer: false (2)
components:
- name: echo
repository: "quay.io/konflux-ci/my-team-tasks/task-echo"
tags:
- "{{ oci_version }}"
- "{{ oci_version }}-{{ timestamp }}"
pyxis:
secret: pyxis-prod-secret
server: production
intention: production
pipeline:
pipelineRef:
resolver: git
params:
- name: url
value: "https://github.com/konflux-ci/release-service-catalog.git"
- name: revision
value: production
- name: pathInRepo
value: "pipelines/managed/push-tekton-task-bundles-to-external-registry/push-tekton-task-bundles-to-external-registry.yaml"
serviceAccountName: konflux-ci-servicerelease-sa
timeouts:
pipeline: "4h0m0s"
tasks: 4h0m0s
| 1 | Use registrySecret to provide a secret for the release pipeline to make image repositories public. To skip this operation, assign an empty string "". |
| 2 | Set pushSourceContainer to false to prevent releasing source container images. The source image build is irrelevant to a Tekton bundle build. |
|
These resources are required for managing and approving the release of Tekton task bundles.
Post actions
You may want to verify that the tasks are pushed as bundles correctly and that the trusted tasks list was updated. To do so after a release, use Tekton CLI and oras to verify the OCI artifacts.
To get your bundle as a YAML file task definition, run:
tkn bundle list <task's repository url> -o yaml
Example:
tkn bundle list quay.io/konflux-ci/my-team-tasks/task-echo:0.1@sha256:d9a056f1ec3e6a8f60347a91f142ec90a54a324cc7fde3e37336ae35a1521234 -o yaml
To get the list of trusted tasks, run:
oras pull <release repository>/data-acceptable-bundles:latest
Example:
oras pull quay.io/konflux-ci/my-team-tasks/data-acceptable-bundles:latest
The command extracts the list of trusted tasks to data/data/trusted_tekton_tasks.yml in your working directory.
Use onboarded tasks as trusted tasks
To use the onboarded tasks and let Conforma identify them as trusted tasks, update the policies and add the new trusted data sources. Use the data-acceptable-bundles OCI artifact that was created or updated during the release process.
Example of a policy that adds quay.io/konflux-ci/my-team-tasks/data-acceptable-bundles:latest as a trusted source:
apiVersion: appstudio.redhat.com/v1alpha1
kind: EnterpriseContractPolicy
metadata:
name: default
namespace: enterprise-contract-service
spec:
description: Conforma policy with the addition of
oci::quay.io/konflux-ci/my-team-tasks/data-acceptable-bundles:latest as another data source
name: Default
publicKey: k8s://openshift-pipelines/public-key
sources:
- config:
exclude: []
include:
- '@slsa3'
data:
- oci::quay.io/konflux-ci/tekton-catalog/data-acceptable-bundles:latest
- github.com/release-engineering/rhtap-ec-policy//data
- oci::quay.io/konflux-ci/my-team-tasks/data-acceptable-bundles:latest
name: Default
policy:
- oci::quay.io/enterprise-contract/ec-release-policy:git-fe45153@sha256:94b62b263b947a762b08d5aa2715f37ff3ba25ff7462850dba9d9a8eec1b4c49
After completing all the steps above you should now have:
-
A task released as a bundle in your release repository.
-
An OCI artifact named data-acceptable-bundles in your release repository, containing a SHA reference of the latest task release as a trusted task. All previous versions of the task appear with the
expires_onparameter.