sourceconditiontarget

Description

The yaml resource reads and writes a key in a YAML file, addressed by a yamlpath expression.

source

Returns the value of one key from one file.

condition

Checks that the key holds value, or the source output when value is unset. With keyonly, checks only that the key exists.

target

Writes the value at the key. Keys already holding it are reported as up to date and left untouched, so a target that changes nothing does not create a commit.

Parameters

NameTypeDescriptionRequired
commentstring

comment defines a comment to add after the value.

default: empty

compatible:

  • target

remarks:

  • Please note that the comment is added if the value is modified by Updatecli
documentindexinteger

DocumentIndex defines the index of the document to interact with in a multi-document yaml file.

compatible:

  • source
  • condition
  • target

default: empty

remark:

  • when not set in the context of a source, the value will be retrieve from the first documents matching query.
  • when not set in the context of a condition or a target, all documents will be evaluated by the query.
  • When not set in the context of a target, all documents will be updated by the query.

example:

  • documentindex: 0
  • documentindex: 1
enginestring

“engine” defines the engine to use to manipulate the yaml file.

There is no one good Golang library to manipulate yaml files. And each one of them have has its pros and cons so we decided to allow this customization based on user’s needs.

remark:

  • Accepted value is one of “yamlpath”, “go-yaml”,“default” or nothing
  • go-yaml, “default” and "" are equivalent
filestring

“file” defines the yaml file path to interact with.

compatible:

  • source
  • condition
  • target

remark:

  • “file” and “files” are mutually exclusive
  • scheme “https://”, “http://”, and “file://” are supported in path for source and condition
filesarray

“files” defines the list of yaml files path to interact with.

compatible:

  • condition
  • target

remark:

  • file and files are mutually exclusive
  • protocols “https://”, “http://”, and “file://” are supported in file path for source and condition
keystring

“key” defines the yaml keypath.

compatible:

  • source
  • condition
  • target

remark:

  • key is a simpler version of yamlpath accepts keys.

example using default engine:

  • key: $.name
  • key: $.agent.name
  • key: $.agents[0].name
  • key: $.agents[*].name
  • key: $.‘agents.name’
  • key: $.repos[?(@.repository == ‘website’)].owner" (require engine set to yamlpath)

remark: field path with key/value is not supported at the moment. some help would be useful on https://github.com/goccy/go-yaml/issues/290

keyonlyboolean

keyonly allows to check only if a key exist and do not return an error otherwise

compatible: * condition

default: false

keysarray

“keys” defines multiple yaml keypaths to update with the same value.

compatible:

  • target

remark:

  • keys is mutually exclusive with key.
  • keys accepts the same syntax as key for each element.
  • all keys will be updated with the same value.
  • only available for target operations, not for source or condition.

example using default engine:

  • keys:
    • $.image.tag
    • $.sidecar.tag
  • keys:
    • $.agents[0].version
    • $.agents[1].version
searchpatternboolean

searchpattern defines if the MatchPattern should be applied on the file(s) path

If set to true, it modifies the behavior of the file and files attributes to search for files matching the pattern instead of searching for files with the exact name. When looking for file path pattern, it requires pattern to match all of name, not just a substring.

The pattern syntax is:

   pattern:
       { term }
   term:
       '*'         matches any sequence of non-Separator characters
       '?'         matches any single non-Separator character
       '[' [ '^' ] { character-range } ']'
                   character class (must be non-empty)
       c           matches character c (c != '*', '?', '\\', '[')
       '\\' c      matches character c

character-range:
       c           matches character c (c != '\\', '-', ']')
       '\\' c      matches character c
       lo '-' hi   matches character c for lo <= c <= hi
valuestring

value is the value associated with a yaml key.

compatible:

  • source
  • condition
  • target

default: When used from a condition or a target, the default value is set to the associated source output.

The spec has two mutually exclusive pairs, and breaking either aborts the run before the pipeline starts:

file / files

One is mandatory. Setting both gives the attributes 'spec.file' and 'spec.files' are mutually exclusive; duplicates inside files are rejected too.

key / keys

One is mandatory. Setting both gives 'key' and 'keys' are mutually exclusive; duplicates inside keys are rejected.

Several parameters work in only one stage, which the table above does not make obvious:

keys

Target only. Updates several keys with the same value in one go - useful for an image tag repeated across a chart. A source or condition must use key.

keyonly

Condition only. Passes when the key exists, whatever its value.

comment

Target only. Appended inline after the value, and only when Updatecli actually changes it.

searchpattern

Not supported in a source. It turns file/files into glob patterns rather than exact names. A source using it fails with validation error in sources of type 'yaml': the attribute 'spec.searchpattern' is not supported for source.

Engines

engine picks the YAML library, because none of them handles every case well:

ValueBehaviour

default

Default when unset. Equivalent to go-yaml and to an empty value.

go-yaml

Same as default.

yamlpath

Required for filter expressions such as $.repos[?(@.repository == 'website')].owner.

Key syntax

Arrays are indexed with key[x], counting from zero, and can be chained with dots, key.array[3].key:

COUNTRY_CODE:
- BE
- FR
- LU

Here COUNTRY_CODE[1] is FR.

Escaping dots

A dot separates path elements, so a key that itself contains dots is escaped with a backslash. These two files are different:

image.tag: latest     # one key named "image.tag"  -> image\.tag
image:                # a key "tag" nested under "image" -> image.tag
    tag: latest

The escaped form must be written in single quotes, otherwise YAML consumes the backslash before Updatecli sees it:

targets:
  helm-chart-label:
    name: bump chart dependencies
    kind: yaml
    disablesourceinput: true
    spec:
      file: "/tmp/gateway.yaml"
      key: 'spec\.values\.labels\.service\.istio\.io/canonical-revision'
      value: "test"

Multi-document files

documentindex selects one document in a ----separated file, counting from zero. Its default is not "the first document" but something different per stage:

  • source - the value is taken from the first document matching the query.

  • condition - every document is evaluated.

  • target - every document is updated.

That last one surprises people. Given this file:

kind: Deployment
image:
  tag: 1.0.0
---
kind: Service
image:
  tag: 2.0.0

a target on $.image.tag with no documentindex rewrites both, even though the run report mentions a single key:

kind: Deployment
image:
  tag: 9.9.9 # updated by updatecli
---
kind: Service
image:
  tag: 9.9.9 # updated by updatecli

Set documentindex: 0 to touch only the first one.

Remote files

For a source and a condition, file accepts https://, http:// and file://. A target cannot write back to a URL and fails with URL scheme is not supported for YAML target.

Example

# updatecli.yaml
name: Example of YAML resources

scms:
  default:
    kind: github
    spec:
      user: "my git user"
      email: "my git email"
      owner: "olblak"
      repository: "chart"
      token: "{{ requiredEnv .github.token }}"
      username: "github username"
      branch: "main"

sources:
  lastRelease:
    kind: helmchart
    spec:
      url: https://charts.jenkins.io
      name: jenkins

conditions:
  chartVersion:
    name: "jenkinsci/jenkins Helm Chart used"
    kind: yaml
    scmid: default
    spec:
      file: "charts/jenkins/requirements.yaml"
      key: "dependencies[0].name"
      value: "jenkins"

targets:
  chartVersion:
    name: "jenkinsci/jenkins Helm Chart"
    kind: yaml
    scmid: default
    spec:
      file: "charts/jenkins/requirements.yaml"
      key: "dependencies[0].version"

What it says:

Source

Retrieve the version of the Jenkins helm chart from https://charts.jenkins.io.

Condition

Check that charts/jenkins/requirements.yaml has a dependencies array whose first element is jenkins. If not, the pipeline stops here.

Target

Update that first element to the source value in the GitHub repository olblak/chart, then publish the change as a pull request against master from a working branch.