Description

Updatecli orders execution at two different levels:

  • between manifests, with the root keys id and dependson, described on this page

  • between the resources of one manifest, with the resource key dependson, described in Resource ordering

The two are independent: dependson at the root of a manifest refers to other manifests, while dependson inside a source, condition, or target refers to other resources of the same manifest.

Manifest ordering

By default, Updatecli treats each manifest as an independent pipeline and does not guarantee ordering. When you run multiple manifests, Updatecli can order them explicitly before execution.

Manifest ordering is controlled with two root keys:

  • id: declares the manifest identifier that other manifests can depend on

  • dependson: lists the manifest IDs that must run first

This is useful when one manifest prepares data, policies, or files that another manifest relies on.

Important

id and dependson only affect the execution order of manifests.

They do not change:

  • branch naming

  • pull request grouping

  • workflow grouping

For those behaviors, keep using pipelineid.

Parameters

id

The id key defines a manifest dependency identifier.

name: Base image updates
id: base-images

Use id when another manifest must wait for this one to complete.

Note

Multiple manifests may intentionally share the same id. When another manifest depends on that id, Updatecli waits for all matching manifests to run first.

dependson

The dependson key lists the manifest IDs that must be executed before the current manifest.

name: Application updates
id: app
dependson:
  - base-images
  - shared-policies

Each entry in dependson must reference an existing manifest id.

Example

In this example, the application manifest only runs after the base image manifest has been evaluated.

manifests/base.yaml
name: Base image updates
id: base-images

sources:
  alpine:
    name: Get latest Alpine version
    kind: dockerimage
    spec:
      image: alpine
      tag: latest

targets:
  dockerfile:
    name: Update Dockerfile base image
    kind: dockerfile
    spec:
      file: Dockerfile
      instruction: FROM
manifests/app.yaml
name: Application updates
id: app
dependson:
  - base-images

sources:
  version:
    name: Get latest release
    kind: githubrelease
    spec:
      owner: updatecli
      repository: updatecli

targets:
  yaml:
    name: Update application version
    kind: yaml
    spec:
      file: values.yaml
      key: $.image.tag

If you run Updatecli against the manifests/ directory, it executes base.yaml before app.yaml.

Behavior

Shared IDs

If multiple manifests share the same id, a dependency waits for all of them.

# policies/a.yaml
name: Policy A
id: shared-policy

# policies/b.yaml
name: Policy B
id: shared-policy

# app.yaml
name: App
dependson:
  - shared-policy

In this case, app.yaml runs after both policies/a.yaml and policies/b.yaml.

Legacy manifests

Manifests without an explicit id continue to work as before. They keep their existing execution order, but they cannot be referenced from another manifest using dependson.

Invalid dependencies

Updatecli stops with an error when:

  • a manifest depends on an unknown id

  • a manifest depends on its own id

  • manifest dependencies create a cycle

Autodiscovery

Pipelines generated by autodiscovery inherit the id of the manifest declaring the autodiscovery key, and their dependson is merged with the parent one. Ordering a discovered set relative to a handwritten manifest therefore only requires declaring id and dependson on the autodiscovery manifest itself.

Resource ordering

Inside a single manifest, Updatecli builds a dependency graph of the sources, conditions and targets, and runs each resource as soon as the resources it depends on are done.

Implicit dependencies

Most manifests never need an explicit dependson, because the following already create an edge in the graph:

DeclarationResulting dependency

sourceid: mySource on a condition or a target

That resource waits for mySource. When the manifest has exactly one source, sourceid is filled in automatically.

{{ source "mySource" }} anywhere in a resource configuration

The resource waits for mySource, even if sourceid points somewhere else. The same holds for {{ condition "…​" }}, {{ target "…​" }}, and {{ pipeline "…​" }}.

any condition in the manifest

Every target waits for every condition, unless the target sets disableconditions: true.

Explicit dependencies

dependson accepts a list of rules following the format (<category>#)<resourceID>(:<operator>):

  • <category> is source, condition, or target. When omitted, it defaults to the category of the resource declaring the dependency.

  • <resourceID> is the key of another resource in the same manifest.

  • <operator> is and or or, defaulting to and. and requires every listed dependency to succeed, or requires at least one.

sources:
  tag:
    kind: dockerimage
    spec:
      image: golang

  digest:
    kind: dockerdigest
    # Same category, so this means "source#tag"
    dependson:
      - tag
    spec:
      image: golang
      tag: '{{ source "tag" }}'

targets:
  dockerfile:
    kind: dockerfile
    sourceid: digest
    disableconditions: true
    # Cross-category dependency, with an explicit operator
    dependson:
      - condition#imageExists:and
    spec:
      file: Dockerfile
      instruction:
        keyword: FROM
        matcher: golang

A resource whose dependencies are not met is skipped, not failed. Note that a condition dependency must explicitly succeed: a skipped condition does not unlock the resources depending on it.

Depending on a change rather than a success

Targets additionally accept dependsonchange: true. The target then only runs when the targets it depends on actually modified something. Dependencies on sources and conditions are ignored while this flag is set.

See target for a complete example.

Invalid resource dependencies

Updatecli refuses to run a manifest when a dependson entry references an unknown resource, or when the resource dependencies form a loop.

Tip
Use dependson together with disablesourceinput: true, or without conditionids, to break a cycle that Updatecli detects between two resources.

Visualizing the graph

To check what Updatecli actually derived from a manifest, render the graph:

updatecli manifest show --graph --graph-flavor mermaid

--graph-flavor accepts dot (the default, for Graphviz) and mermaid. For the example above, the mermaid output looks like:

graph TD
    source#version(["version (shell)"])
    source#version --> target#file
    target#file("file (file)")
    condition#exists{"exists (shell)"}
    condition#exists --> target#file

Deprecated keys

KeyReplacement

depends_on on a resource

dependson

conditionids on a target

dependson with condition# keys, combined with disableconditions: true

Go Further