sourceconditiontarget

Description

The gittag resource works with the tags of a git repository directly, over the git protocol (no forge API involved, so it works with any host).

source

Returns the tag matching versionfilter, or its hash when key: hash.

condition

Tests that a matching tag exists. With tag set, the check is an exact match instead of a pattern match.

target

Creates the tag when no matching one exists. This is the one resource in this family that writes to a repository.

Parameters

NameTypeDescriptionRequired
depthinteger

Depth is used to limit the number of commits fetched from the git repository.

compatible:

  • source
  • condition
  • target

default: 0 (no limit)

remark:

  • Updatecli won’t be able to find tags that are not included in the fetched commits.
keystring

“key” of the tag object to retrieve.

Accepted values: [’name’,‘hash’].

Default: ’name’ Compatible:

  • source
lsremoteboolean
messagestring

Message associated to the git tag

compatible:

  • target
passwordstring

“password” specifies the password when using the HTTP protocol

compatible: * source * condition * target

pathstringPath contains the git repository path
sourcebranchstring

“sourcebranch” defines the branch name used as a source to create the new Git branch.

compatible:

  • target

remark:

  • sourcebranch is required when the scmid is not defined.

default: main

tagstring

Tag defines the git tag to check for exact match.

compatible:

  • condition

When specified, the condition will check for an exact tag match instead of using versionFilter pattern matching.

urlstring

“url” specifies the git url to use for fetching Git Tags.

compatible: * source * condition * target

example: * git@github.com:updatecli/updatecli.git * https://github.com/updatecli/updatecli.git

remarks: when using the ssh protocol, the user must have the right to clone the repository based on its local ssh configuration

it’s possible to specify git tags without cloning the repository by using the lsremote option, in that case the URL is required and the tags will be retrieved from the remote repository directly without cloning it.

usernamestring

“username” specifies the username when using the HTTP protocol

compatible * source * condition * target

versionfilterobject

VersionFilter provides parameters to specify version pattern and its type like regex, semver, or just latest.

compatible:

  • source
  • condition
  • target
    kindstringspecifies the version kind such as semver, regex, or latest
    patternstringspecifies the version pattern according the version kind for semver, it is a semver constraint for regex, it is a regex pattern for time, it is a date format
    regexstringspecifies the regex pattern, used for regex/semver and regex/time. Output of the first capture group will be used.
    replaceallobjectreplaceAll applies a regex replacement to version strings before filtering. This is useful for transforming versions (e.g., curl-8_15_0 to curl-8.15.0) before regex extraction.
    strictbooleanstrict enforce strict versioning rule. Only used for semantic versioning at this time
url

The repository. Over SSH (git@github.com:updatecli/updatecli.git), access depends on your local SSH configuration; over HTTPS, on username and password.

path

A local repository to read instead of cloning.

key

Source only. name, the default, returns the tag name; hash returns the commit hash it points at. Any other value is rejected with The only valid values for Key are 'name', 'hash', or empty.

tag

Condition only - an exact tag, bypassing versionfilter.

message

Target only - the annotation message of the tag being created.

sourcebranch

Target only, and required when no scmid is set.

Avoiding a clone

lsremote: true lists the tags straight from the remote with git ls-remote, without cloning. On a large repository that is the difference between a second and a minute, and it is enough for any source or condition that only needs tag names.

depth limits how many commits are fetched when a clone does happen.

Warning

lsremote and depth both mean an incomplete local repository. A key: hash lookup or a target creating a tag needs real objects, so leave them off there.

Version Filter

versionFilter allows to specify the kind of version retrieved from a resource and its version pattern. Default value is "latest" as we want to retrieve the newest version from a resource.

A version filter accepts the following keys:

NameDefaultDescription

kind

latest

One of latest, lex, regex, semver, regex/semver, time, regex/time, pep440. An unsupported value stops the run with an error.

pattern

depends on kind

The constraint applied to the versions, interpreted according to kind. Defaults to . for regex, for semver and pep440, and 2006-01-02 for time and regex/time.

regex

-

Used by regex/semver and regex/time only, to extract the version from a longer string. The first capture group is the value being filtered.

replaceall

-

An optional find-and-replace applied to each version before the filter, with the sub-keys pattern (a regular expression) and replacement (which may reference capture groups with $1, $2, …).

strict

false

Used by semver and regex/semver only. When true, only strictly formatted MAJOR.MINOR.PATCH versions are considered, so a lenient version such as 1.2 is dropped instead of being read as 1.2.0.

Note
Versions that cannot be parsed for the selected kind are silently skipped, not treated as errors. When nothing is left after filtering, the resource fails with "no version found".

latest

If kind is set to latest then there is no need to specify a pattern, as Updatecli returns the last version provided by the resource, in the order the resource returned them.

Important
latest does not compare versions, it trusts the ordering of the resource. For a Docker registry, that is the most recently pushed tag, which is not necessarily the highest version number. Use semver when you need the highest version.
Example
sources:
  kubectl:
    kind: githubRelease
    spec:
      owner: "kubernetes"
      repository: "kubectl"
      token: "{{ requiredEnv .github.token }}"
      username: "john"
      versionFilter:
        kind: latest
    transformers:
      - trimPrefix: "kubernetes-"

Return the latest Github release and remove "kubernetes-" from it.

Lex

If the kind is set to lex then Updatecli returns the latest version sorted lexicographically.

Sorting versions lexicographically means arranging them based on their lexicographic order, which is essentially alphabetical order as used in dictionaries, but applied to version strings.

For example, in lexicographic order:

"1.10" comes before "1.2", because it compares character by character:
    Compare "1" vs. "1" → equal.
    Compare "." vs "." → equal.
    Compare "1" vs. "2" → "1" is smaller, so "1.10" < "1.2".

This ordering does not account for numerical values of version components. For meaningful version comparisons, semantic versioning is typically preferred, where "1.2" < "1.10" because "2" is numerically smaller than "10".

Example
sources:
  ubuntu-focal:
    name: Get latest ubuntu focal docker image tag using regex/time versionfilter
    kind: dockerimage
    spec:
      image: ubuntu
      versionfilter:
        kind: lex

regex

If versionFilter.kind is set to regex then we can use versionFilter.pattern to specify a regular expression to return the newest version returned from a resource matching the regex If no versionFilter.pattern is provided then it uses '.*' which return the newest version

Note
Like latest, regex walks the versions in the order the resource returned them and stops on the first match, starting from the end. It filters, it does not sort. To compare version numbers, use regex/semver.

versionFilter.replaceall can optionally be used to transform version strings before the regex is applied. It accepts a pattern (regex) and a replacement string, similar to a find-and-replace operation.

sources:
  kubectl:
    kind: githubRelease
    spec:
      owner: "kubernetes"
      repository: "kubectl"
      token: "{{ requiredEnv .github.token }}"
      username: "john"
      versionFilter:
        kind: regex
        pattern: "kubernetes-1.(\\d*).(\\d*)$"
    transformers:
      - trimPrefix: "kubernetes-"

⇒ Return the newest kubectl version matching pattern "kubernetes-1.(\\d*).(\\d*)$" and remove "kubernetes-" from it

Example with replaceall

Some projects use version tags that are not directly compatible with the regex pattern. For example, curl uses tags like curl-8_11_1 where underscores separate version components. The replaceall option can be used to normalize these tags before applying the regex.

sources:
  curl:
    kind: githubRelease
    spec:
      owner: "curl"
      repository: "curl"
      versionFilter:
        kind: regex
        pattern: 'curl-\d+\.\d+\.\d+'
        replaceall:
          pattern: "_"
          replacement: "."

⇒ The replaceall converts curl-8_11_1 to curl-8.11.1, and the newest tag matching pattern is returned as curl-8.11.1

Important
With kind: regex, the returned value is the whole transformed version, not a capture group - the regex key is ignored, only pattern is read. Use kind: regex/semver when you need to extract 8.11.1 out of curl-8.11.1, and add a trimprefix transformer otherwise.

semver

If versionFilter.kind is set to semver then we can use versionFilter.pattern to specify version pattern as explained here. In the process we also sort. If no versionFilter.pattern is provided then it falls back to '*' which returns the newest version. Versions that do not respect semantic versioning are ignored.

Setting versionFilter.strict to true additionally rejects versions that are only loosely semantic, such as 1.2 or v1, instead of completing them with zeros.

Remark

In the process we drop any characters not respecting semantic version like in this version "v1.0.0", we drop the "v" but we can add it back using transformers.

Autodiscovery patterns

On top of the standard constraints, semver accepts the following keywords, which are resolved against the version currently in use. They are what the autodiscovery crawlers use to restrict the scope of an update.

PatternMeaning

patch

Only patch updates, keeping the same major and minor.

minor

Minor and patch updates, keeping the same major.

minoronly

Minor updates only, excluding patch updates within the current minor.

major

Any update from the current major upwards.

majoronly

Major updates only.

prerelease

Pre-releases of the current version.

Example
  jenkins-wiki-exporter:
    kind: githubRelease
    spec:
      owner: "jenkins-infra"
      repository: "jenkins-wiki-exporter"
      token: "{{ requiredEnv .github.token }}"
      username: "john"
      versionFilter:
        kind: semver
        pattern: "~1.10"

⇒ Return the version "v1.10.3"

regex/semver

If versionFilter.kind is set to regex/semver then we can use versionFilter.regex to specify a regular expression to extract version numbers. The regular expression should return the semantic version in the first capturing group. We can then use versionFilter.pattern to specify version pattern as explained here. In the process we also sort. If no versionFilter.pattern is provided then it falls back to '*' which returns the newest version. Extracted values that do not respect semantic versioning are ignored.

versionFilter.replaceall can optionally be used to transform version strings before the regex is applied. It accepts a pattern (regex) and a replacement string, similar to a find-and-replace operation. See the regex section for an example.

Important
The regular expression must define at least one capture group; a version without one is skipped. pattern filters the extracted value, regex extracts it (the two are not interchangeable).
Example
sources:
  default:
    name: Get latest version
    kind: githubrelease
    spec:
      owner: yarnpkg
      repository: berry
      token: '{{ requiredEnv "GITHUB_TOKEN" }}'
      versionfilter:
        kind: regex/semver
        regex: "@yarnpkg/cli/(\\d*\\.\\d*\\.\\d*)"

⇒ Return the version "4.5.3"

regex/time

If versionFilter.kind is set to regex/time then we can use versionFilter.regex to specify a regular expression to extract dates. The regular expression should return the date in the first capturing group. We can then use versionFilter.pattern to specify date pattern as explained here. In the process we also sort. If no versionFilter.pattern is provided then it falls back to '2006-01-02' which returns the newest version using date format YYYY-MM-DD. Extracted values that do not match the date pattern are ignored.

To define your own format/pattern, write down what the reference time would look like formatted your way; The model is to demonstrate what the reference time looks like so that the Format and Parse methods can apply the same transformation to a general time value.

Here is a summary of the components of a layout string. Each element shows by example the formatting of an element of the reference time. Only these values are recognized. Text in the layout string that is not recognized as part of the reference time is echoed verbatim during Format and expected to appear verbatim in the input to Parse.

Year: "2006" "06"
Month: "Jan" "January" "01" "1"
Day of the week: "Mon" "Monday"
Day of the month: "2" "_2" "02"
Day of the year: "__2" "002"
Hour: "15" "3" "03" (PM or AM)
Minute: "4" "04"
Second: "5" "05"
AM/PM mark: "PM"

You can get inspiration from the following examples

Pattern

Example

2006-01-02

2021-01-02 (YYYY-MM-DD)

20060102

20210102 (YYYYMMDD)

20060201

20260201 (YYYYDDMM)

Example
sources:
  ubuntu-focal:
    name: Get latest ubuntu focal docker image tag using regex/time versionfilter
    kind: dockerimage
    spec:
      image: ubuntu
      versionfilter:
        kind: 'regex/time'
        regex: '^focal-(\d*)$'
        pattern: "20060102"

time

If versionFilter.kind is set to time then we can use versionFilter.pattern to specify date pattern as explained here. In the process we also sort. If no versionFilter.pattern is provided then it fallback to '2006-01-02' which return the newest version using date format YYYY-MM-DD. Please note date time not matching the pattern will be ignored.

To define your own format/pattern, write down what the reference time would look like formatted your way; The model is to demonstrate what the reference time looks like so that the Format and Parse methods can apply the same transformation to a general time value.

Here is a summary of the components of a layout string. Each element shows by example the formatting of an element of the reference time. Only these values are recognized. Text in the layout string that is not recognized as part of the reference time is echoed verbatim during Format and expected to appear verbatim in the input to Parse.

Year: "2006" "06"
Month: "Jan" "January" "01" "1"
Day of the week: "Mon" "Monday"
Day of the month: "2" "_2" "02"
Day of the year: "__2" "002"
Hour: "15" "3" "03" (PM or AM)
Minute: "4" "04"
Second: "5" "05"
AM/PM mark: "PM"

You can get inspiration from the following examples

Pattern

Example

2006-01-02

2021-01-02 (YYYY-MM-DD)

20060102

20210102 (YYYYMMDD)

20060201

20260201 (YYYYDDMM)

Example
sources:
  ubuntu:
    name: Get latest ubuntu docker image tag using time versionfilter
    kind: dockerimage
    spec:
      image: ubuntu
      versionfilter:
        kind: 'time'
        pattern: "06.01"

pep440

If versionFilter.kind is set to pep440 then versions are parsed and sorted according to the Python PEP 440 specification, and versionFilter.pattern is a PEP 440 specifier such as >=1.0,<2.0. Versions that are not valid PEP 440 versions are ignored.

This is the right choice for Python packages, whose versions are not semantic versions: PEP 440 understands epochs (1!2.0), post-releases (1.0.post1), development releases (1.0.dev1), and pre-release spellings such as 1.0rc1 or 1.0a1, which semver rejects or misorders.

If no versionFilter.pattern is provided then it falls back to *.

Important
With *, or with no pattern at all, Updatecli returns the newest stable version and only falls back to a pre-release when no stable version exists. An explicit specifier does not apply that preference: it returns the newest version satisfying it, pre-release or not.
Example
sources:
  ansible:
    name: Get the latest stable Ansible release
    kind: pypi
    spec:
      name: ansible
      versionfilter:
        kind: pep440

Example

# updatecli.yaml
---
name: "Test new gittag resource"

scms:
  gitExample:
    kind: "git"
    spec:
        url: "git@github.com:updatecli/updatecli.git"
        branch: "main"
  githubExample:
    kind: "github"
    spec:
        user: "updatecli-bot"
        email: "updatecli@example.com"
        owner: "updatecli"
        repository: "updatecli"
        token: '{{ requiredEnv "GITHUB_TOKEN" }}'
        username: "john"
        branch: "main"
sources:
  gitExample1:
    name: "Get Latest updatecli test"
    kind: gittag
    scmid: gitExample
    spec:
      path: "./git_repository_path/"

  gitExample2: # Without scmid
    name: Get Latest updatecli test
    kind: gittag
    spec:
      path: "./git_repository_path/"

  githubSemver:
    name: Get Latest updatecli test
    kind: gittag
    scmid: githubExample
    spec:
      versionfilter:
        kind: semver
        pattern: "~0.1"
  githubRegex:
    name: Get Latest updatecli test
    kind: gittag
    scmid: githubExample
    spec:
      versionfilter:
        kind: regex
        pattern: "v0.*"
conditions:
  gitRegex:
    name: Test Get Latest updatecli test
    disablesourceinput: true
    kind: gittag
    scmid: gitExample
    spec:
      versionfilter:
        pattern: "v0.1.2"
targets:
  github:
    sourceid: githubRegex
    name: Publish tag with -github
    scmid: githubExample
    kind: gittag
    transformers:
      - addsuffix: "-github"
  git:
    scmid: gitExample
    sourceid: githubRegex
    name: Publish tag with -git
    kind: gittag
    transformers:
      - addsuffix: "-git"