Labels
Overview
Pipeline labels are arbitrary key/value pairs attached to a pipeline manifest that allow you to categorize, organize, and filter pipelines during execution and reporting.
name: "docs: update Golang version throughout the documentation"
# Pipeline labels: key/value pairs used to filter and organize pipelines in Updatecli and Udash.
labels:
ecosystem: go
actions:
default:
kind: github/pullrequest
spec:
# PR labels: applied to the pull request on the SCM (e.g. GitHub). Different from pipeline labels above.
labels:
- dependenciesThese labels can be used for two main purposes:
Filtering pipeline execution - Use labels to run only specific pipelines matching given criteria.
For example, only apply pipelines tagged with
ecosystem: go:updatecli compose apply --labels="ecosystem:go"Pipelines matching the filter will execute. Pipelines without the label or with a different value will be skipped.
Filtering pipeline reports in Udash
Filtering with --labels
The --labels flag is available on every command that runs or renders pipelines:
updatecli pipeline apply|diff|prepare, updatecli compose apply|diff|show,
updatecli manifest show|upgrade, and their deprecated top-level aliases.
Each entry is a key:value pair. Entries can be comma separated, and the flag can be repeated:
# Equivalent forms
updatecli pipeline diff --labels="team:backend,environment:staging"
updatecli pipeline diff --labels="team:backend" --labels="environment:staging"| Form | Matches |
|---|---|
| Pipelines whose |
| Pipelines that define an |
several entries | Only pipelines matching all of them. Filters are combined with a logical AND, there is no OR form. |
Passing no --labels at all runs every pipeline, including the ones that define labels.
Important | A filter is a subset check, not an equality check. A pipeline labelled ecosystem: go and team: backend matches --labels="ecosystem:go". There is no way to require a pipeline to carry only the labels you listed. |
Labels and autodiscovery
Labels set on a manifest declaring the autodiscovery key are copied onto every pipeline that the
crawlers generate. That is the practical way to label discovered updates, since those pipelines are
never written by hand:
name: Discover Golang module updates
labels:
ecosystem: go
monitor: passive
autodiscovery:
crawlers:
golang:Crawlers do not generate labels of their own, so every pipeline a crawler produces carries exactly the labels of the autodiscovery manifest, and nothing else.
That has a practical consequence for the conventions below: labels are uniform across a single
crawler’s output. A value that varies per dependency, such as update.channel, cannot come from one
manifest. Express the distinction by writing one autodiscovery manifest per channel, each with its
own labels:
# patch-only.yaml
labels:
ecosystem: go
update.channel: patch
autodiscovery:
crawlers:
golang:
versionfilter:
kind: semver
pattern: patchRecommended conventions
Important | The conventions below are recommendations, not rules. Updatecli accepts any key/value pair, never validates or rewrites them, and never generates them for you. Nothing here is enforced. It exists so that pipelines written by different people, in different repositories, line up in --labels filters and in Udash dashboards. |
Design principles
Labels group,
pipelineididentifies. A label puts a pipeline into a bucket shared with others. Keep labels low-cardinality and stable over time.One key, one question. Each key should answer a single independent question, so that any combination of them can be filtered or grouped on.
Prefer an existing value over a new one. A small closed set of values is what makes filters work across repositories. Inventing a value per repository defeats the purpose.
Never encode high-cardinality data. The dependency name, the version number, and the file path belong to the
pipelineidand to the target, never to a label.
Formatting
| Rule | Convention |
|---|---|
Key | lowercase, one word, or dotted |
Value | lowercase |
Booleans | the strings |
Unknown or not applicable | omit the label entirely, rather than setting an empty value |
Important | Label matching is exact and case-sensitive. A pipeline labelled Ecosystem: Go never matches --labels="ecosystem:go", and Updatecli does not warn about it. Pick one casing and keep to it. |
Omitting a label is better than giving it an empty value: --labels="ecosystem:" is an existence check rather than a match on the empty string, and Udash rejects labels with an empty value when it stores a report.
Suggested vocabulary
ecosystem
Which package universe the pipeline belongs to.
| Value | Covers |
|---|---|
| Go modules and toolchain |
| Node, npm, yarn, pnpm |
| JVM build dependencies, Maven |
| JVM build dependencies, Gradle |
| Python packages |
| Rust crates |
| .NET |
| Ruby |
| PHP |
| Elixir and Erlang |
| container images, Dockerfiles, compose files |
| Helm charts and values |
| Kubernetes manifests, kustomize |
| GitHub Actions |
| Gitea Actions |
| Terraform and OpenTofu |
| Java, Temurin, JDK runtimes |
| OS packages: apt/deb, rpm, apk |
| Updatecli policies |
| file, http, or shell resources with no specific ecosystem |
Note | These values name the packaging universe rather than the language, which is why the list has go and npm instead of golang and javascript. Language names work just as well as long as everyone in your organisation uses the same ones. Consistency matters more than which list you pick. |
kind
What the updated thing is, independent of the technology.
| Value | Use for |
|---|---|
| a library or package dependency: Go module, npm dependency, Maven artifact, Cargo crate, pip package |
| a language or runtime version: Go, Node, Java, Python, Rust |
| a container base image, the |
| a referenced container image that is not a base image: compose, Kubernetes manifest, Helm values |
| a Helm chart |
| a CI action or step: GitHub Actions, Gitea Actions |
| a Terraform or OpenTofu provider or module |
| a plugin of a host application, such as a Jenkins plugin |
| an Updatecli policy |
| a standalone downloaded tool or binary |
| an application or service version pin, the deployed thing itself |
| arbitrary file or value updates not covered above |
Tip | kind describes the nature of the dependency, never the reference format. Whether a version is a tag or a digest belongs to update.channel. |
update.channel
The track a pipeline is allowed to follow. This is the axis to group on to answer "show me every patch update, everywhere".
| Value | Meaning |
|---|---|
| always move to the newest available version, with no semver constraint |
| major bumps |
| minor bumps |
| patch bumps |
| re-pin an immutable digest for the same tag, with no version change |
| alpha, beta, and release candidate track |
| explicitly the stable channel, for projects shipping both stable and edge |
| rolling, unstable track |
| nightly builds |
| long-term-support track |
The channel describes what the manifest allows, not the size of a bump that happened. A pipeline labelled update.channel: patch keeps that label whether it finds a new version or not.
update.strategy
How the version was selected. Mirrors the resource’s versionfilter.kind. See versionFilter.
Common values: semver, latest, regex, lexical, time.
Note | This label is only useful if it stays a faithful mirror of the spec. If you cannot keep it in sync, omit it rather than ship a misleading one. |
update.channel and update.strategy answer different questions, which is why they are separate keys. versionfilter.kind: latest is a selection strategy, "take whatever is newest"; update.channel: latest is a track, "this pipeline follows the newest release". A pipeline can perfectly well be update.channel: patch with update.strategy: semver.
monitor
How urgently a pipeline should run.
| Value | Meaning |
|---|---|
| always run, detect updates as soon as possible |
| run periodically, some drift is acceptable |
| intentionally frozen, assert this version stays locked |
| human-triggered only, never run in automated CI |
This is the axis most often wired into CI, for example a scheduled workflow running updatecli apply --labels="monitor:active" and a slower one for monitor:passive.
team, owner, component
Ownership and routing. team or owner should hold a team slug rather than a person’s name, and component the service or application a dependency belongs to in a monorepo. Keep all three low-cardinality.
Examples
Not every pipeline is a dependency update, and ecosystem and kind simply do not apply to some of them. Use the axes that make sense and omit the rest.
labels:
ecosystem: go
kind: module
update.channel: patch
update.strategy: semver
monitor: passivelabels:
ecosystem: docker
kind: base-image
update.channel: digest
update.strategy: digest
monitor: activelabels:
ecosystem: helm
kind: chart
update.channel: minor
update.strategy: semver
team: platformlabels:
release: updatecli
monitor: activeTo avoid
Too generic to be useful
update, dependency, pipeline - these describe what Updatecli does by definition; they add no filtering value.
Free-form / inconsistent spellings
Mixing github-actions, GithubActions, github_actions - pick one convention (kebab-case is common) and stick to it. Inconsistency breaks filtering.
Mixed casing
Ecosystem: Go and ecosystem: go are two different labels. Since matching is exact and case-sensitive, and Updatecli never normalises keys or values, a mistyped capital silently excludes the pipeline from every filter that was meant to catch it. Stay lowercase.
Labels that repeat the spec
kind:dockerfile, file:/path/to/go.mod - Updatecli already knows the resource kinds and the files a pipeline touches. Duplicating them into labels adds another thing to keep in sync, for no filtering value that reports do not already provide.
Status-like labels
done, pending, failed - Updatecli and Udash already track state natively; encoding status in labels leads to stale metadata.
Highly volatile values
version:1.2.3 - versions change constantly; labels should be stable identifiers, not point-in-time values.
Overly broad owner labels without structure
john, alice - person names become stale when teams change. Prefer team: or squad: prefixes.
Pull request labels in pipeline labels
dependencies, automerge, bug - these are pull request labels and belong in action.spec.labels, not in the pipeline labels field.
They are applied to the SCM pull request (GitHub, GitLab, etc.) and have no effect on pipeline filtering or Udash dashboards.
See Actions for the correct location.
By CI/CD platform or integration
These labels should be avoided: the risk is executing pipelines outside the expected CI/CD platform. If needed, this information can be detected at runtime. Feel free to open an issue or a PR to implement this feature.
Conclusion
Labels are a powerful tool for organizing and filtering pipelines, but they require thoughtful design to be effective. Use clear, consistent naming conventions that reflect stable dimensions of your projects, teams, and policies.
The vocabulary in Recommended conventions is a starting point, not a requirement. Updatecli enforces none of it. Adopting it simply means your pipelines group the same way as everyone else’s, which is what makes a shared dashboard readable. Where it does not fit, define your own keys and stay consistent with them.