Github Release
kind: githubRelease
| source | condition | target |
|---|---|---|
✔ | ✔ | ✗ |
Description
source
The GitHub Release "source" retrieves the latest release version sorted by release date. If no release can be found then we fallback to release tags sorted on tag date creation. It’s important to notice that both information are mutually exclusive.
Parameter
| Name | Type | Description | Required |
|---|---|---|---|
| app | object | “app” specifies the GitHub App credentials used to authenticate with GitHub API. It is not compatible with the “token” and “username” fields. It is recommended to use the GitHub App authentication method for better security and granular permissions. For more information, please refer to the following documentation: | |
| clientid | string | ClientID represents the GitHub App client ID | |
| expirationtime | string | Expiration represents the token expiration time in seconds The token is used during the entire execution of updatecli and should be valid for the entire duration of the run The minimum value is 600 seconds (10 minutes) Default: 3600 (1 hour) | |
| installationid | string | InstallationID represents the GitHub App installation ID
It is the same ID that you can find in the GitHub endpoint:
https://github.com/settings/installation/ | |
| privatekey | string | PrivateKey represents a PEM encoded private key It is recommended to use PrivateKeyPath instead of PrivateKey to avoid putting sensitive information in the configuration file If both PrivateKey and PrivateKeyPath are set, PrivateKey takes precedence | |
| privatekeypath | string | PrivateKeyPath represents the path to a PEM encoded private key If both PrivateKey and PrivateKeyPath are set, PrivateKey takes precedence It is recommended to use an environment variable to set the PrivateKeyPath value e.g. PrivateKeyPath: {{ requiredEnv “GITHUB_APP_PRIVATE_KEY_PATH” }} to avoid putting sensitive information in the configuration file | |
| key | string | “key” defines the GitHub release information we are looking for. It accepts one of the following inputs:
accepted values:
default: ’tagname' compatible:
| |
| owner | string | owner defines repository owner to interact with. required: true compatible:
| |
| repository | string | repository defines the repository name to interact with. required: true compatible:
| |
| tag | string | tag allows to check for a specific release tag, release tag hash, or release title depending on a the parameter key. compatible:
default: source input | |
| token | string | token defines the GitHub personal access token used to authenticate with. more information on https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/managing-your-personal-access-tokens required: true compatible:
| |
| typefilter | object | typeFilter specifies the GitHub Release type to retrieve before applying the versionfilter rule default:
compatible:
| |
| draft | boolean | “Draft” enable/disable GitHub draft release | |
| latest | boolean | “Latest” if set to true will only filter the release flag as latest. | |
| prerelease | boolean | “PreRelease” enable/disable GitHub PreRelease | |
| release | boolean | “Release” enable/disable GitHub release | |
| url | string | URL defines the default github url in case of GitHub enterprise. default: https://github.com compatible:
| |
| username | string | username defines the username used to authenticate with GitHub API. compatible:
| |
| versionfilter | object | versionFilter provides parameters to specify version pattern and its type like regex, semver, or just latest. default: latest compatible:
| |
| kind | string | specifies the version kind such as semver, regex, or latest | |
| pattern | string | specifies 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 | |
| regex | string | specifies the regex pattern, used for regex/semver and regex/time. Output of the first capture group will be used. | |
| strict | boolean | strict enforce strict versioning rule. Only used for semantic versioning at this time |
Authentication
Updatecli supports multiple authentication methods for interacting with GitHub. You can authenticate using either a Personal Access Token (PAT) or a GitHub App. Below are the supported methods, in order of precedence.
1. GitHub App Authentication via Environment Variables
Set the following environment variables to enable GitHub App authentication:
UPDATECLI_GITHUB_APP_CLIENT_ID: Your GitHub App’s Client IDUPDATECLI_GITHUB_APP_PRIVATE_KEY: The private key for your GitHub App (PEM format, as a string)UPDATECLI_GITHUB_APP_PRIVATE_KEY_PATH: The path to your GitHub App’s private key file (PEM format)UPDATECLI_GITHUB_APP_INSTALLATION_ID: The installation ID for your GitHub App
You can use either UPDATECLI_GITHUB_APP_PRIVATE_KEY or UPDATECLI_GITHUB_APP_PRIVATE_KEY_PATH to provide the private key.
Example using the private key content:
export UPDATECLI_GITHUB_APP_CLIENT_ID="123456"
export UPDATECLI_GITHUB_APP_PRIVATE_KEY="$(cat /path/to/private-key.pem)"
export UPDATECLI_GITHUB_APP_INSTALLATION_ID="789012"Example using the private key path:
export UPDATECLI_GITHUB_APP_CLIENT_ID="123456"
export UPDATECLI_GITHUB_APP_PRIVATE_KEY_PATH="/path/to/private-key.pem"
export UPDATECLI_GITHUB_APP_INSTALLATION_ID="789012"Note | When these variables are set, Updatecli will use GitHub App authentication for all GitHub operations. |
2. Personal Access Token via Environment Variable
Set the following environment variable to use a Personal Access Token:
UPDATECLI_GITHUB_TOKEN: Your GitHub Personal Access Token
Example:
export UPDATECLI_GITHUB_TOKEN="ghp_XXXXXXXXXXXXXXXXXXXXXXXXXXXX"3. Personal Access Token via Manifest
You can specify your Personal Access Token directly in your Updatecli manifest under the spec.token field:
scms:
default:
kind: github
spec:
owner: myorg
repository: myrepo
token: "{{ requiredEnv `GITHUB_TOKEN` }}"Warning | For security reasons, it is recommended to use environment variables or secret management tools (like SOPS) instead of hardcoding tokens in your manifest. |
4. GitHub App Authentication via Manifest
You can configure GitHub App authentication directly in your manifest using the spec.app field:
scms:
default:
kind: github
spec:
owner: myorg
repository: myrepo
app:
clientID: "123456"
privateKey: "{{ requiredEnv `GITHUB_APP_PRIVATE_KEY` }}"
installationID: "789012"Or, if you prefer to reference a private key file:
scms:
default:
kind: github
spec:
owner: myorg
repository: myrepo
app:
clientID: "123456"
privateKeyPath: "/path/to/private-key.pem"
installationID: "789012"Precedence and Fallback
Updatecli will use the first valid authentication method it finds, in the following order:
Personal Access Token via environment variable
GitHub App via environment variables
Personal Access Token via manifest
GitHub App via manifest
If no valid authentication is found, Updatecli will fail with an error.
Further Reading
Tip: For best security and maintainability, prefer using a GitHub App or environment variables for authentication, and avoid hardcoding secrets in your manifests.
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.
latest
If kind is set to latest then no need to specify the patter as we gonna retrieve the newest version from the resource.
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: lexregex
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
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
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 fallback to '*' which return the newest version.
If a version doesn’t respect semantic versioning, then it’s not the value is just ignored.
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 added it back using transformers.
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 fallback to '*' which return the newest version.
If a extracted version doesn’t respect semantic versioning, then it’s not the value is just ignored.
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 fallback to '2006-01-02' which return the newest version using date format YYYY-MM-DD.
If a extracted date doesn’t match the date pattern, then it’s not the value is just 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"Remark:
It’s considered a very bad practice to store credentials in an un-encrypted file. Consider using an environment variable to store the token.
# source.yaml
sources:
lastRelease:
kind: githubRelease
spec:
owner: "jenkins-infra"
repository: "jenkins-wiki-exporter"
token: "{{ requiredEnv "ENV_VARIABLE" }}"
username: "john"
versionFilter:
kind: regexp
pattern: "v1.10\.(.*)"
⇒ Return v1.10.3
Example
# updatecli.yaml
name: Github Release Example
# Scms defines Git repository configuration to interact with.
scms:
default:
kind: github
spec:
user: "updatecli"
email: "updatecli@olblak.com"
owner: "olblak"
repository: "charts"
token: '{{ requiredEnv "GITHUB_TOKEN" }}'
username: "olblak"
branch: "master"
# Sources are responsible for retrieving information from thirds location like GitHub releases.
sources:
# Retrieve the "latest" Helm version using the Helm GitHub Release.
helm:
name: Get latest Helm release version
kind: githubrelease
spec:
owner: "helm"
repository: "helm"
token: '{{ requiredEnv .github.token }}'
username: olblak
versionfilter:
kind: latest
# Conditions are simple checks that need to pass before updating a target.
conditions:
# The yaml plugin doesn't support advanced yamlpath syntax so when we need
# to fetch information from an array, we want to be sure that the position is
# still relevant to the target
keyExist:
name: Update GitHub Action workflow
kind: yaml
scmid: default
disablesourceinput: true
spec:
file: .github/workflows/helm.yaml
key: .$jobs.release.steps[0].name
value: Install Helm
# Targets define the state of files based on source information.
targets:
# Ensure the Dockerfile arg HELM_VERSION is set to the latest Helm version retrieved by the source.
dockerfile:
name: Update Dockerfile ARG HELM_VERSION
kind: dockerfile
scmid: default
sourceid: helm
spec:
file: docker/Dockerfile
instruction:
keyword: ARG
matcher: HELM_VERSION
# Ensure the GitHub workflow file is correctly set to the latest helm version retrieved from the source.
ghWorkflow:
name: Update GitHub Action workflow
kind: yaml
scmid: default
sourceid: helm
spec:
file: .github/workflows/helm.yaml
key: .$jobs.release.steps[0].with.version
actions:
# If one of the two targets is modified, then we want to open a
# pullrequest with the auto merge flag set to true and the label "helm"
default:
kind: github/pullrequest
scmid: default
title: 'Bump Helm version to {{ source "helm" }}'
spec:
automerge: true
labels:
- "helm"