A container image with CLI tools commonly used by Konflux Tasks.
This project implements ADR-0046: Common Task Runner Image.
The Task Runner image consolidates multiple CLI tools into a single container image, simplifying Task creation and reducing the maintenance overhead of managing multiple tool-specific images.
You can use it directly as the runtime image for Konflux Tasks or as a base image for more specialized runner images.
See Installed-Software.md for the complete list of tools and their versions.
Tools must meet the following requirements for inclusion:
- Must be a standalone CLI tool
- Language runtimes are also acceptable (e.g. Python)
- Must be installable hermetically
- Must follow a versioning scheme (preferably semantic versioning)
- Should have release notes or a changelog
Tools are organized under deps/ by installation method:
RPM packages use a lockfile-based approach for hermeticity and reproducibility.
Process:
-
Add the package name to
deps/rpm/rpms.in.yamlunder either:packages- for new packagesreinstallPackages- for packages already in the base image (we want control over their versions)
-
Regenerate the lockfile:
make rpms.lock.yaml
-
Regenerate auto-generated files:
devtool gen --all
The install-rpms.sh script reads the infile and the lockfile and automatically
installs the exact package versions specified.
If the tool is installable via go install, prefer this approach. Compared to
the submodule approach, this results in more accurate SBOMs.
Each tool has its own directory with go.mod/go.sum, which is crucial for independent
version management. Go's MVS
ensures we get the same versions of dependencies used upstream. Combining multiple
tools in one go.mod file would break that.
Process:
-
Create a directory under
deps/go-tools/with the tool name -
Inside, create
go.modandgo.sumthat reference the tool's CLI package. Example:mkdir deps/go-tools/cosign cd deps/go-tools/cosign go mod init github.com/konflux-ci/task-runner/deps/go-tools/cosign go get -tool github.com/sigstore/cosign/v3/cmd/[email protected] go mod tidy
Note: Use
go get -tool(not justgo get). Specify the package with the CLI binary, which is often a sub-package of the module (e.g.github.com/sigstore/cosign/v3/cmd/cosign, notgithub.com/sigstore/cosign/v3). -
Add the tool to
install-tools.sh:install_tool <name> [version_ldflags_attribute]
The
version_ldflags_attributeinjects the version into the binary and is required for tools that use this approach (otherwise tests will fail when checking version output). To find the correct attribute, inspect the tool's upstream build process (often found in the Makefile or build scripts). -
Regenerate auto-generated files:
devtool gen --all
If the tool is not installable with go install, e.g. due to the use of replace
directives in the tool's go.mod or due to incorrectly formatted semver tags,
fall back to git submodules.
Process:
-
Add the submodule and check out a semver(-ish) tag:
cd deps/go-submodules git submodule add <repository-url> <tool-name> cd <tool-name> git checkout v1.2.3
-
In
.gitmodules, set thebranchfield to the current tag (Renovate uses this for updates). If the submodule doesn't use correct semver tags (likeoc), add corresponding Renovate configuration indevtool/renovate.pywith a custom versioning regex. -
Add build commands to
install-submodules.sh -
Regenerate auto-generated files:
devtool gen --all
- Python 3.12+
- uv (Python package manager)
- Podman
Initialize/update git submodules:
make submodulesCreate a virtual environment and install dependencies:
make venv
source .venv/bin/activateThe devtool CLI assists with common development tasks:
devtool ls # List all tools to be installed
devtool gen --all # Generate files (e.g. Installed-Software.md)Locally:
podman build -t task-runner .For production: we use Konflux CI. See the pipelines in .tekton/.
Run tests to verify tool installations:
pytestBy default, tests build the image and tag it localhost/task-runner:test.
To skip rebuilding and test an existing image, set the TEST_IMAGE environment
variable:
# Build once
podman build -t localhost/task-runner:latest .
# Run tests against the existing image
TEST_IMAGE=localhost/task-runner:latest pytest
# Set it in .env for persistent use (if you use direnv or similar shell integration)
echo 'TEST_IMAGE=localhost/task-runner:latest' >> .envTests automatically discover packages and their expected versions using the
code in devtool/software_list.py. If a new package isn't detected properly,
you may need to update the discovery logic there. You may also need to update
test configuration (e.g. version_arg_overrides in tests/test_installed_packages.py
for tools that don't support the standard --version flag).
After modifying deps/rpm/rpms.in.yaml:
make rpms.lock.yamlThis uses rpm-lockfile-prototype to resolve and lock package versions.
The version of the runner image is tracked in the VERSION file.
The Konflux build pipeline automatically sets the org.opencontainer.image.version
annotation (and label as well) on the built image using our custom
.tekton/tasks/get-build-params.yaml Task.
When making a new release, bump the version according to the first matching rule:
- Removed a tool / updated the major version of any tool -> bump the major version
- Added a new tool / updated the minor version of any tool -> bump the minor version
- Otherwise -> bump the patch version
To bump the version automatically based on the changes in installed software, use:
# Assuming the remote for the upstream repo is called 'upstream'
git fetch --tags upstream
devtool prep-releaseThe tool will automatically update the VERSION file and output a markdown list with the changes since the last release. Include this list when creating the GitHub release later.
If there are no relevant changes to the installed software (i.e. the Installed-Software.md
file did not change), the tool will abort without doing any changes. In that case,
if you do want to do a release, please update the VERSION file manually and write
the release notes yourself.
- Determine what has changed since last release and update the VERSION file accordingly (see above).
- Send a PR to update the version.
- Once merged, if the Konflux release succeeds, create a GitHub release. In the
release notes, describe the relevant changes. You can use the output of the
devtool prep-releasecommand. If you don't have that output available, usedevtool diff --base-ref <previous_version> --changelog(if this fails, you may need to fetch tags first).