In the Konflux environment, mintmaker creates "Konflux References Update" PRs for each repository's active release branches. Using the server foundation squad (which owns 10 repositories) as an example, if we set the renovate schedule to run daily, we need to handle 10×5 = 50 PRs (including z stream branches). This takes hours even if we just click the button to merge these PRs, and becomes even more time-consuming when PRs require migrations.
Since the PipelineSpec of each PipelineRun in Tekton files across repositories is essentially the same, we can centralize these common tasks into reusable pipelines. This repository provides common build pipelines that other repositories can reference using Tekton's PipelineRef feature, reducing the maintenance burden from 50+ daily PRs to just 1 PR in this central repository. As more repositories adopt these common pipelines, the efficiency improvement scales significantly.
This repository contains the following pipelines:
pipelines/common.yaml: The main common build pipeline for multi-platform container images. It aligns with docker-build-multi-platform-oci-ta pipeline and is used by most repositories.pipelines/common-oci-ta.yaml: A common pipeline for single-platform container image. It aligns with docker-build-oci-ta pipeline and is used by bundle repositories that do not require multi-platform builds, such asmulticluster-global-hub-operator-bundle.pipelines/common-fbc.yaml: A common pipeline for FBC (File-Based Catalogs) builds. It aligns with fbc-builder pipeline and is used by repositories that build FBCs, such asmulticluster-global-hub-operator-catalog.
For backward compatibility, MCE version-specific pipeline paths (pipelines/common_mce_2.X.yaml) are provided as symbolic links to pipelines/common.yaml. Repositories referencing these paths will continue to work without changes.
The pipelines implement a comprehensive container build workflow:
- Initialization: Validate build parameters and determine if build should proceed
- Source Management: Clone repository using OCI artifacts for trusted builds
- Product Metadata: Fetch product metadata and generate image labels (see Automatic Image Label Injection)
- Dependency Management: Prefetch dependencies using Cachi2 for hermetic builds
- Multi-Platform Build: Build container images across multiple architectures (x86_64, arm64, ppc64le, s390x)
- Image Index: Create OCI image index for multi-platform manifests
- Security Scanning: Comprehensive security checks including:
- Clair vulnerability scanning
- SAST (Snyk, Coverity, Shell, Unicode)
- Deprecated base image checks
- RPM signature verification
- Malware scanning (ClamAV)
- Source Image: Build source images for compliance
- Metadata: Apply tags and push Dockerfile for traceability
The fetch-product-metadata task automatically generates and injects Red Hat required image labels (cpe, name, version) into container images at build time. Downstream repositories no longer need to hardcode or manually update these labels in their Dockerfiles.
The task runs in two steps:
Step 1 — Parse output image: Extracts component, product (acm/mce), and version from the Konflux output-image parameter (e.g. registration-operator-mce-217 → component=registration-operator, product=mce, version=2.17).
Step 2 — Fetch metadata from bundle repository: Clones the corresponding bundle repository ({product}-operator-bundle at branch {backplane|release}-{version}) and extracts:
| Label | Source | Example |
|---|---|---|
cpe |
Generated from product, version, and RHEL version | cpe:/a:redhat:multicluster_engine:2.17::el9 |
name |
config/{product}-manifest-gen-config.json → image-namespace/publish-name |
multicluster-engine/registration-operator-rhel9 |
version |
Z_RELEASE_VERSION file |
v2.17.1 |
These labels are passed as the LABELS parameter to the buildah-remote-oci-ta build task, which applies them to the final container image via --label flags. Labels injected by the pipeline override any same-named labels in the Dockerfile.
Before (manual, error-prone):
# Hardcoded — must be updated every release
LABEL cpe="cpe:/a:redhat:multicluster_engine:2.11::el9"
LABEL name="multicluster-engine/registration-operator-rhel9"
LABEL version="v2.11.0"After (automatic):
# These labels are now injected by the pipeline at build time.
# You can either use empty placeholders or omit them entirely.
LABEL cpe=""Other labels that are not auto-injected (e.g., summary, description, io.k8s.display-name, com.redhat.component, io.openshift.tags) should still be maintained in the Dockerfile as they are component-specific.
| Label | Auto-injected? | Where to maintain |
|---|---|---|
cpe |
Yes | Pipeline (no action needed) |
name |
Yes | Pipeline (no action needed) |
version |
Yes | Pipeline (no action needed) |
summary |
No | Dockerfile |
description |
No | Dockerfile |
com.redhat.component |
No | Dockerfile |
io.k8s.display-name |
No | Dockerfile |
io.k8s.description |
No | Dockerfile |
io.openshift.tags |
No | Dockerfile |
Choose the appropriate pipeline based on your project requirements:
- Multi-platform builds: Use
pipelines/common.yaml - Single-platform bundles: Use
pipelines/common-oci-ta.yaml - File-Based Catalogs: Use
pipelines/common-fbc.yaml
.
├── pipelines/
│ ├── common.yaml # Main common build pipeline for multi-platform container images
│ ├── common-fbc.yaml # Common build pipeline for File-Based Catalogs
│ ├── common-oci-ta.yaml # Common build pipeline for single-platform container images
│ └── common_mce_*.yaml # Symlinks to common.yaml for backward compatibility
├── tasks/
│ └── fetch-product-metadata/ # Custom task for auto-generating image labels
├── v4.13/* # FBC build files for OpenShift 4.13
├── .tekton/ # Konflux configuration for this project
│ ├── common-pipeline-*-pull-request.yaml # PR configurations for all pipelines
│ └── common-pipeline-*-push.yaml # Push configurations for all pipelines
├── .github/workflows/
│ ├── update-tekton-task-bundles.yaml # Workflow to auto-update task bundles
│ └── auto-merge-automated-updates.yaml # Workflow to auto-merge automated updates
└── update-tekton-task-bundles.sh # Update scriptThe pipelines in this repository are self-testing: the .tekton/ configuration files reference the pipeline definitions from the pipelines/ directory. This means every change to a pipeline automatically triggers corresponding build and EC (Enterprise Contract) checks, ensuring that updated pipelines are validated and usable before being merged.
For example, in .tekton/common-pipeline-pull-request.yaml:
...
# ensure common.yaml is built and tested whenever it changes
pipelinesascode.tekton.dev/on-cel-expression: event == "pull_request" && target_branch
== "main" && ("pipelines/common.yaml".pathChanged() || ".tekton/common-pipeline-pull-request.yaml".pathChanged())
...
pipelineRef:
resolver: git
params:
- name: url
value: "https://github.com/stolostron/konflux-build-catalog.git"
- name: revision
value: '{{revision}}' # Uses the commit hash of the PR branch
- name: pathInRepo
value: pipelines/common.yamlThis project includes two complementary GitHub Actions workflows for fully automated updates:
Runs daily at 02:00 UTC and:
- Automatically checks for the latest versions of Tekton task bundles
- Updates task references in pipeline files (
common.yaml,common-fbc.yaml,common-oci-ta.yaml) - Creates a PR with the
automated-updatelabel if there are updates
Runs daily at 04:00 UTC (2 hours after the update workflow) and:
- Identifies PRs with the
automated-updatelabel - Verifies that all status checks are passing and the PR is mergeable
- Automatically merges qualifying PRs using squash merge
- Deletes the merged branch automatically
This two-step process ensures that Tekton task bundle updates are not only created but also automatically merged when all validation checks pass, providing a fully hands-off update experience. You can also manually trigger either workflow as needed.
Replace the pipelineSpec section to pipelineRef in your repository's .tekton/*.yaml files with:
pipelineRef:
resolver: git
params:
- name: url
value: "https://github.com/stolostron/konflux-build-catalog.git"
- name: revision
value: main
- name: pathInRepo
value: pipelines/common.yamlFollow this PR to understand how to update your repository: stolostron/managedcluster-import-controller#730
# Update all bundle references to latest versions
bash update-tekton-task-bundles.sh pipelines/common.yaml
# Update multiple pipeline files at once
bash update-tekton-task-bundles.sh pipelines/common.yaml pipelines/common-fbc.yaml
# Update all pipeline files
bash update-tekton-task-bundles.sh pipelines/*.yaml# Validate YAML syntax for single file
yq eval pipelines/common.yaml > /dev/null
# Validate all pipeline files
for file in pipelines/*.yaml; do yq eval "$file" > /dev/null && echo "$file: OK"; done# Sync all pipelines from konflux-ci/build-definitions
python3 sync_upstream_pipeline.py
# Sync a specific pipeline file
python3 sync_upstream_pipeline.py pipelines/common.yaml
# Dry-run to preview changes without writing
python3 sync_upstream_pipeline.py --dry-runThe sync_upstream_pipeline.py script synchronizes local pipeline files with their upstream counterparts from konflux-ci/build-definitions while preserving local customizations. It's configured using the upstream-map.yaml.
Exit codes:
0- No changes detected200- At least one pipeline file was updated1- Error occurred (e.g., missing mapped file)
The pipeline_file matrix in .github/workflows/update-tekton-task-bundles.yaml is dynamically generated from the pipelines/ directory (excluding symlinks). New pipeline files are automatically picked up by the workflow without manual matrix updates.
CRITICAL: Files in .tekton/ directory are linked to specific pipeline files through the pipelinesascode.tekton.dev/on-cel-expression annotation. When adding, renaming, or modifying pipeline files, you MUST ensure the corresponding .tekton files reference the correct pipeline file paths.
Example CEL expression patterns:
# For pipelines/common.yaml
pipelinesascode.tekton.dev/on-cel-expression: event == "pull_request" && target_branch == "main" && ("pipelines/common.yaml".pathChanged() || ".tekton/common-pipeline-pull-request.yaml".pathChanged())
# For pipelines/common-fbc.yaml
pipelinesascode.tekton.dev/on-cel-expression: event == "pull_request" && target_branch == "main" && ("pipelines/common-fbc.yaml".pathChanged() || ".tekton/common-pipeline-fbc-pull-request.yaml".pathChanged())If you rename pipelines/common.yaml to pipelines/new-name.yaml, update ALL related .tekton files to reference the new path in their CEL expressions.
| Document | Description |
|---|---|
| docs/common-pipeline-configurations.md | Special pipeline configuration parameters |
| playbook/how-to-handle-a-migration-issue.md | How to handle a Tekton task migration issue |
- Tekton Pipelines - Kubernetes-native CI/CD
- Buildah - Container build tool
- OCI Artifacts - Trusted artifact storage
- Multi-Platform Controller - Cross-platform builds
- Security Scanning - Clair, Snyk, Coverity integration