Description

The github/action crawler looks recursively for workflow files and Composite Actions, then tries to update every action reference found in them.

It scans two kinds of file:

  • Workflows - files matching .yaml or .yml located directly inside a workflows directory whose parent is .github, .gitea, or .forgejo.

  • Composite Actions - files named action.yaml or action.yml, in any directory.

Despite its name, the crawler is not GitHub-only: .gitea/workflows and .forgejo/workflows are scanned as well, and the provider is detected from each action reference.

This crawler is enabled by default, so it can be used either automatically by running updatecli diff from a directory containing the files to update, or by providing a manifest. The automatic discovery behavior can be tuned by providing a YAML manifest with a github/action crawler in top-level directive autodiscovery as explained in the "Autodiscovery" page.

Note
The crawler key is github/action. The alias gitea/action maps to the same implementation, but it is not part of the default crawlers, so it only runs when explicitly declared.

Generated manifests

Action references are updated in place with a yaml target. The source depends on the provider and on the shape of the reference:

ReferenceSources used

owner/repo@v4 on GitHub

githubrelease, gittag, gitbranch

owner/repo@v3 on Gitea or Forgejo

gitea/release, gittag, gitbranch

docker://image:tag

dockerimage, dockerdigest

./local-action

Skipped - local actions have no upstream to track.

Digest pinning

digest defaults to true, so generated manifests pin references to an immutable digest and keep the human-readable version as a trailing comment:

- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1

Set digest: false to write the tag or branch directly instead.

Important
Digest pinning is only implemented for GitHub Actions and Docker image references. Gitea and Forgejo actions are always updated to a tag or branch.

Authentication

Discovery queries the provider’s API, so unauthenticated runs are rate limited and private repositories are invisible.

Tokens are resolved per hostname, from credentials, from a GitHub App configuration, or from the environment:

  • GitHub: UPDATECLI_GITHUB_TOKEN, then GITHUB_TOKEN

  • Gitea and Forgejo: UPDATECLI_GITEA_TOKEN, then GITEA_TOKEN

gitea.com, codeberg.org, and code.forgejo.org are recognised as Gitea automatically. Any other unknown hostname falls back to GitHub.

Use credentialsdocker to authenticate against a private registry when resolving docker:// references.

Limitations

  • files matches the file name only, not a path. Patterns such as .github/workflows/.yaml match nothing; use .yaml or ci.yaml. The directory is constrained separately, to .github, .gitea, or .forgejo workflow directories.

  • actions filters Composite Actions by the name of the directory containing action.yaml, not by the file path.

  • Workflow files that are not directly inside a workflows directory are ignored.

Manifest

Parameters

NameTypeDescriptionRequired
actionsarray

“actions” defines the composite action name patterns the crawler searches for.

default:

actions:
  - "*"

remark:

  • a composite action is identified by an “action.yaml” or “action.yml” file, and the pattern is matched against the name of the directory holding it.
ageobject

“age” defines the minimum or maximum age of a release, tag, or branch to be considered valid.

It is the “dependency cooldown” setting: setting “minimum” keeps Updatecli from suggesting a version that has just been published.

default: empty, no age filtering.

remark:

  • it accepts a duration string, such as “24h”, “7d”, “3w” or “1y”.
  • the age filter is not applied to the Docker images referenced by a workflow.

example:

autodiscovery:
  crawlers:
    github/action:
      age:
        minimum: '7d'
    maximumstring

“maximum” defines the maximum age a release may have to be considered.

remark:

  • accepted units are “d” for days, “w” for weeks, “mo” for months and “y” for years, plus the Go duration units such as “h”, “m” and “s”.
  • a unit is required.
  • a month counts as 1/12 of a year and a year as 365 days.

example:

  • maximum: 6mo
  • maximum: 1y
    minimumstring

“minimum” defines the minimum age a release must have to be considered.

remark:

  • accepted units are “d” for days, “w” for weeks, “mo” for months and “y” for years, plus the Go duration units such as “h”, “m” and “s”.
  • a unit is required.
  • a month counts as 1/12 of a year and a year as 365 days.

example:

  • minimum: 24h
  • minimum: 7d
  • minimum: 3w
credentialsobject

“credentials” defines the credentials used to authenticate with each git provider, keyed by git provider domain.

remark:

  • without an entry, “gitea.com”, “codeberg.org” and “code.forgejo.org” use kind “gitea”, and any other domain uses kind “github” with the “github.com” credentials.

example:

autodiscovery:
  crawlers:
    github/action:
      credentials:
        "code.forgejo.com":
          kind: gitea
          token: xxx
        "github.com":
          kind: github
          token: '{{ requiredEnv "GITHUB_TOKEN" }}'
    appobject
        clientidstring“clientid” defines the GitHub App client ID.
        expirationtimestring

“expirationtime” defines the lifetime of the GitHub App token, in seconds.

default: 3600

remark:

  • the token is used during the whole Updatecli run, so it must stay valid until the run ends.
  • the minimum value is 600.
        installationidstring

“installationid” defines the GitHub App installation ID.

remark:

  • the value must be an integer.
  • it is the ID shown in the URL https://github.com/settings/installation/
        privatekeystring

“privatekey” defines the PEM encoded private key of the GitHub App.

remark:

  • “privatekey” or “privatekeypath” is required.
  • when both are set, “privatekey” takes precedence.
  • prefer “privatekeypath”, to keep sensitive information out of the manifest.
        privatekeypathstring

“privatekeypath” defines the path to a file holding the PEM encoded private key of the GitHub App.

remark:

  • “privatekey” or “privatekeypath” is required.
  • when both are set, “privatekey” takes precedence.
  • setting the value from an environment variable keeps sensitive information out of the manifest.

example:

  • privatekeypath: ‘{{ requiredEnv “GITHUB_APP_PRIVATE_KEY_PATH” }}’
    kindstring
    tokenstring
credentialsdockerobject

“credentialsdocker” defines the registry credentials used for Docker images, keyed by registry host without scheme.

remark:

  • when empty, Updatecli uses the local OCI credentials, such as the Docker ones.

example:

credentialsdocker:
  "ghcr.io":
    token: "xxx"
  "index.docker.io":
    username: "admin"
    password: "password"
    passwordstring

“password” defines the container registry password used for authentication.

default: credentials are retrieved from the local environment, such as ~/.docker/config.json.

remark:

  • “password” requires “username”.
  • “token” cannot be combined with both “username” and “password”.
    tokenstring

“token” defines the container registry bearer token used for authentication.

default: credentials are retrieved from the local environment, such as ~/.docker/config.json.

remark:

  • “token” cannot be combined with both “username” and “password”.
    usernamestring

“username” defines the container registry username used for authentication.

default: credentials are retrieved from the local environment, such as ~/.docker/config.json.

remark:

  • “username” requires “password”.
  • “token” cannot be combined with both “username” and “password”.
digestboolean

“digest” defines whether the generated manifests pin the digest instead of the branch or tag.

default: true

remark:

  • digest pinning is supported for GitHub actions and Docker images, not yet for Gitea and Forgejo actions.
  • when false, actions referenced by “main”, “master” or “latest” are skipped.
filesarray

“files” defines the workflow file name patterns the crawler searches for.

default:

files:
  - "*.yaml"
  - "*.yml"

remark:

  • the pattern is matched against the file name only, not against its path, so a pattern such as “.github/workflows/*.yaml” never matches.
  • a workflow file must sit directly inside a “workflows” directory whose parent is “.github”, “.gitea”, or “.forgejo”.
ignorearray

“ignore” defines rules to exclude matching actions or Docker images from the autodiscovery.

remark:

  • an action or Docker image is ignored when it matches at least one rule.
    actionsobject

“actions” defines the actions and Docker images to match, keyed by name.

remark:

  • for an action, the key is the action name, such as “actions/checkout”.
  • for a Docker image, the key is the image reference as written in the workflow, tag included, such as “docker://alpine:3.18” for a step or “alpine:3.18” for a job container.
  • an empty value matches any version.
  • otherwise the value is a semantic version constraint, such as “>=1.0.0”.
  • when the version or the constraint cannot be parsed, the value must equal the reference, such as a git branch, a git tag, or a Docker image tag.
    pathstring

“path” defines a workflow or composite action file path pattern.

remark:

  • the pattern must match the whole path, not just a substring.
  • the pattern follows the Go filepath.Match syntax, such as “*” or “?”.
onlyarray

“only” defines rules to restrict the autodiscovery to matching actions or Docker images.

remark:

  • an action or Docker image is kept only when it matches at least one rule.
    actionsobject

“actions” defines the actions and Docker images to match, keyed by name.

remark:

  • for an action, the key is the action name, such as “actions/checkout”.
  • for a Docker image, the key is the image reference as written in the workflow, tag included, such as “docker://alpine:3.18” for a step or “alpine:3.18” for a job container.
  • an empty value matches any version.
  • otherwise the value is a semantic version constraint, such as “>=1.0.0”.
  • when the version or the constraint cannot be parsed, the value must equal the reference, such as a git branch, a git tag, or a Docker image tag.
    pathstring

“path” defines a workflow or composite action file path pattern.

remark:

  • the pattern must match the whole path, not just a substring.
  • the pattern follows the Go filepath.Match syntax, such as “*” or “?”.
rootdirstring

“rootdir” defines the directory where the crawler starts searching for workflow files and composite actions.

default: the scm directory when “scmid” is set, otherwise the directory relative paths resolve from, by default the working directory.

remark:

  • a relative path is resolved from the default directory.
  • an absolute path is used as is, instead of the scm directory.
versionfilterobject

“versionfilter” defines the version filter used by the generated manifests.

default:

  • for an action, kind “semver” with pattern “*”, the latest version, when its reference is a semantic version, otherwise kind “latest”.
  • for a Docker image, kind “semver” with pattern “>=”, combined with a tag filter derived from the current tag.

remark:

  • with kind “semver”, “pattern” accepts:
    • “prerelease”: the latest prerelease of the current version.
    • “patch”: patch updates only.
    • “minor”: patch and minor updates.
    • “minoronly”: minor updates only.
    • “major”: patch, minor and major updates.
    • “majoronly”: major updates only.
    • a version constraint, such as “>= 1.0.0”.
  • with kind “regex”, “pattern” accepts a regular expression.
  • more examples at https://www.updatecli.io/docs/core/versionfilter/

example:

versionfilter:
  kind: semver
  pattern: minor
    kindstring

“kind” defines the versioning scheme used to select a version.

default: latest

remark:

  • accepted values are “latest”, “semver”, “regex”, “regex/semver”, “time”, “regex/time”, “lex” and “pep440”.
  • “latest” returns the last version of the list.
  • “lex” sorts the versions lexicographically and returns the last one.
  • “pep440” follows https://peps.python.org/pep-0440/

example:

  • kind: semver
    patternstring

“pattern” defines the version pattern, according to “kind”.

default:

  • latest: “latest”
  • semver and pep440: “*”
  • regex: “.*”
  • time and regex/time: “2006-01-02”

remark:

  • for “latest”, “latest” returns the last version, any other value must match a version exactly.
  • for “semver” and “regex/semver”, it is a semantic versioning constraint.
  • for “pep440”, it is a pep440 version specifier.
  • for “regex”, it is a regular expression.
  • for “time” and “regex/time”, it is a Go date layout.
  • ignored by “lex”.

example:

  • pattern: ~1.2
  • pattern: “>=1.0.0 <2.0.0”
  • pattern: ^v\d+.\d+.\d+$
    regexstring

“regex” defines the regular expression extracting the version from each entry.

remark:

  • only used by the kinds “regex/semver” and “regex/time”.
  • the value of the first capture group is used as the version.

example:

  • regex: ^v(\d+.\d+.\d+)$
    replaceallobject

“replaceall” applies a regular expression replacement to each version before filtering.

remark:

  • only used by the kinds “regex”, “regex/semver” and “regex/time”.
  • the replacement runs before “pattern” or “regex” is evaluated.

example:

replaceall:
  pattern: "_"
  replacement: "."

turns “curl-8_15_0” into “curl-8.15.0”.

        patternstring

“pattern” defines the regular expression matching the text to replace.

example:

  • pattern: “_”
        replacementstring

“replacement” defines the text replacing each match of “pattern”.

remark:

  • capture groups can be referenced with $1, $2, and so on.

example:

  • replacement: “.”
    strictboolean

“strict” enforces strict semantic versioning rules when parsing versions.

default: false

remark:

  • only used by the kinds “semver” and “regex/semver”.
⚠ This table is generated from the Updatecli codebase and may contain inaccurate data. Feel free to report them on github.com/updatecli/updatecli
Note
Each entry of credentials is keyed by the git provider hostname, and accepts kind (github, gitea, or forgejo) along with a token or a GitHub App configuration.

Example

Basic Example

# updatecli.d/default.yaml
name: "githubaction autodiscovery"
scms:
  default:
    kind: git
    spec:
      url: https://github.com/updatecli/updatecli.git
      branch: "main"

autodiscovery:
  scmid: default
  crawlers:
    github/action:
      digest: true
      rootdir: ".github"

Multiple providers

# updatecli.d/github-action-providers.yaml
autodiscovery:
  crawlers:
    github/action:
      # Pin to a tag or branch rather than a digest
      digest: false
      credentials:
        "github.com":
          kind: github
          token: '{{ requiredEnv "GITHUB_TOKEN" }}'
        "codeberg.org":
          kind: forgejo
          token: '{{ requiredEnv "FORGEJO_TOKEN" }}'
      versionfilter:
        kind: semver
        pattern: minor
Important
Crawler settings are declared directly under the crawler key. An extra spec: level is accepted by the parser but silently ignored, leaving every setting at its default.