Description

azuredevopssearch is not an scm you clone from - it is a generator. Before anything else runs, Updatecli lists every project of the configured organization, then the repositories of the matching projects, then the branches of the matching repositories, and turns each surviving project/repository/branch triplet into a regular azuredevops scm.

Your manifest is then duplicated once per triplet, each copy pinned to one repository and one branch. Ten matches mean ten pipelines, ten working branches, and (if the manifest declares an azuredevops/pullrequest action) ten pull requests. Everything the azuredevops documentation says about cloning, working branches, commits, and signing applies unchanged to each copy.

Its behavior depends on the stage referencing it:

source and condition

Each discovered repository is cloned and the resource works on the files from the matched branch. Nothing is pushed.

target

Updatecli creates a working branch in each discovered repository, commits the changes there, and pushes it.

Important
Like the azuredevops scm, this plugin does not open pull requests (that is the job of an actions block of kind azuredevops/pullrequest, documented on the "Azure DevOps Pull Request" page).

Parameters

NameTypeDescriptionRequired
branchstring

“branch” defines a regular expression matching the git branches to work on.

default: ^main$

remark:

  • one Azure DevOps scm is generated for each matching branch of each discovered repository.
  • when a generated scm is used by a source or a condition, files are read from the matching branch.
  • when a generated scm is used by a target, Updatecli pushes changes to a working branch based on the matching branch, named “updatecli__” by default.
  • set “workingbranch” to false to push changes directly to the matching branch.

example:

  • branch: ^main$
  • branch: ^release/.*$
commitmessageobject

“commitmessage” defines the settings used to generate commit messages.

remark:

  • the settings apply to every target using this scm.
    bodystring

“body” defines the conventional commit body.

default: empty, which means the body is generated by Updatecli.

remark:

  • see https://www.conventionalcommits.org/en/
    deprecatedtitlestring

“title” is ignored.

deprecated:

  • the commit title is always generated from the target name or description.
    footersstring

“footers” defines the conventional commit footers.

default: empty

remark:

  • see https://www.conventionalcommits.org/en/
    hidecreditboolean

“hidecredit” defines whether the Updatecli credit line is left out of the commit message body.

default: false

remark:

  • if you disable the credit line, please consider sponsoring the Updatecli project, https://github.com/updatecli/updatecli
    scopestring

“scope” defines the conventional commit scope.

default: empty

remark:

  • see https://www.conventionalcommits.org/en/
    squashboolean

“squash” defines whether the commits are squashed into a single commit.

default: false

remark:

  • squashing loses the other commit messages, so setting a meaningful “body” is recommended.
  • when “body” is empty, the squashed commit message is generated from the most recent squashed commit. The title is always generated from the target name or description.
    titlestringTitle is the parsed commit message title (not configurable via YAML). The title is automatically generated from the target name or description.
    typestring

“type” defines the conventional commit type, such as “chore”, “fix” or “feat”.

default: chore

remark:

  • see https://www.conventionalcommits.org/en/
depthinteger

“depth” defines the depth used when cloning the git repository.

default: empty, which means a full clone.

remark:

  • a value greater than 0 creates a shallow clone, so Updatecli cannot see the full git history. Pushing changes may then fail, in which case setting “force” to true may be needed.
  • a negative value is rejected.

example:

  • depth: 1
directorystring

“directory” defines the local path where the git repository is cloned.

default: a directory under the Updatecli temporary directory, such as “/tmp/updatecli/azuredevops//” on Linux.

remark:

  • keep the default value unless you have a good reason to change it, as Updatecli may delete the directory after a pipeline run.
  • the value is passed as is to every generated scm., so every repository then uses the same directory.
emailstring

“email” defines the email address used to author commits.

default: updatecli-bot@updatecli.io

forceboolean

“force” defines whether Updatecli runs git push --force when pushing changes.

default: true

remark:

  • when true, Updatecli also recreates the working branches that diverged from their base branch.
  • when “workingbranch” is false and “force” is not set, each generated Azure DevOps scm returns an error, to avoid force pushing to “branch” by mistake. Set “force” explicitly to confirm the behavior.
gpgobject“gpg” defines the GPG key and passphrase used to sign commits.
    passphrasestring“passphrase” defines the passphrase that unlocks “signingkey”.
    signingkeystring

“signingkey” defines the armored GPG private key used to sign commits.

default: empty, which means commits are not signed.

remark:

  • the value is the key content, not a key ID.
  • a private key is sensitive, so avoid writing it in the manifest.
limitinteger

“limit” defines the maximum number of Azure DevOps scm generated from the matching repositories.

default: 10

remark:

  • 0 means no limit.
  • one scm is generated for each matching branch of each repository, so the limit counts repository branches, not repositories.
organizationstring“organization” defines the Azure DevOps organization to search repositories in.
projectstring

“project” defines a regular expression matching the Azure DevOps projects to search in.

default: .*

example:

  • project: ^platform$
repositorystring

“repository” defines a regular expression matching the repositories to use.

default: .*

remark:

  • disabled repositories are always ignored.

example:

  • repository: ^infra-.*$
submodulesboolean

“submodules” defines whether Updatecli clones the git submodules of the repository.

default: true

tokenstring

“token” defines the personal access token used to authenticate with Azure DevOps.

remark:

  • a token is sensitive, so avoid writing it in the manifest.
  • the environment variable UPDATECLI_AZURE_DEVOPS_TOKEN takes precedence over this value.
urlstring

“url” defines the Azure DevOps base URL.

default: https://dev.azure.com

remark:

  • the scheme “https://” is added when missing.
userstring

“user” defines the name used to author commits.

default: updatecli-bot

usernamestring

“username” defines the username used for git authentication.

remark:

  • the environment variable UPDATECLI_AZURE_DEVOPS_USERNAME takes precedence over this value.
workingbranchboolean

“workingbranch” defines whether Updatecli pushes changes to a temporary working branch based on “branch”, instead of pushing to “branch” directly.

default: true

workingbranchprefixstring

“workingbranchprefix” defines the prefix of the working branch name.

default: updatecli

remark:

  • the working branch name joins the prefix, the target branch and the pipeline ID, separated by “workingbranchseparator”.
  • when set to an empty string, the name starts with the separator, for example “main”.
workingbranchseparatorstring

“workingbranchseparator” defines the separator between the parts of the working branch name.

default: _

organization is the only mandatory parameter; without it the run aborts with azure DevOps organization is required for azuredevopssearch SCM.

Apart from organization, project, repository, branch, and limit, every parameter is passed through untouched to each generated azuredevops scm; see the "Azure DevOps" page for what they do. One consequence is worth spelling out: directory is copied verbatim, so every discovered repository would be cloned into the same path. Leave it unset and let Updatecli derive one path per repository.

Matching repositories

project, repository, and branch are regular expressions, not names. project and repository default to .* (every project, every repository) and branch defaults to ^main$.

project: "^platform-.*$"    # projects whose name starts with platform-
repository: "^.*-service$"  # repositories whose name ends with -service
branch: "^main$|^v2$"       # the main or v2 branch

Anchors matter: an unanchored main also matches maintenance. An expression that does not compile is rejected at load time with invalid project regex, invalid repository regex, or invalid branch regex, naming the offending pattern.

Repositories flagged as disabled in Azure DevOps are skipped, as are repositories the API returns without a name or an ID.

Limit

limit caps the number of generated pipelines, that is project/repository/branch triplets - not the number of repositories. It defaults to 10; 0 means no cap.

A repository with three matching branches therefore consumes three slots. Projects, repositories, and branches are consumed in the order the API returns them, so a limit that truncates the set gives you an arbitrary subset rather than a chosen one. Tighten the three patterns instead of relying on limit to keep a run small.

Authentication

url defaults to https://dev.azure.com; for Azure DevOps Server, give the base URL of your instance.

Updatecli supports Personal Access Token (PAT) authentication for interacting with Azure DevOps. You can authenticate using environment variables or directly in your manifest.


1. Personal Access Token via Environment Variables

Set the following environment variables to enable PAT authentication:

  • UPDATECLI_AZURE_DEVOPS_TOKEN: Your Azure DevOps Personal Access Token

  • UPDATECLI_AZURE_DEVOPS_USERNAME: Your Azure DevOps username

Example:

export UPDATECLI_AZURE_DEVOPS_TOKEN="your-pat-token"
export UPDATECLI_AZURE_DEVOPS_USERNAME="your-username"
Note

These variables are read per field: exporting only UPDATECLI_AZURE_DEVOPS_TOKEN is enough to supply the token while the username comes from elsewhere.


2. Personal Access Token via Manifest

You can specify your Personal Access Token directly in your Updatecli manifest under the spec.token and spec.username fields:

scms:
  default:
    kind: azuredevops
    spec:
      organization: myorg
      project: myproject
      repository: myrepo
      token: "{{ requiredEnv `UPDATECLI_AZURE_DEVOPS_TOKEN` }}"
      username: "{{ requiredEnv `UPDATECLI_AZURE_DEVOPS_USERNAME` }}"
Warning

For security reasons, it is recommended to use environment variables or secret management tools (like SOPS) instead of hardcoding tokens in your manifest.


Precedence and Fallback

Which of the two wins depends on the plugin:

azuredevops

The manifest wins. UPDATECLI_AZURE_DEVOPS_TOKEN and UPDATECLI_AZURE_DEVOPS_USERNAME only fill in the fields the manifest leaves empty.

azuredevopssearch

The environment wins. When either variable is set, it overrides the matching manifest field.

Nothing validates that a credential was found at all: only organization is checked when the manifest loads. A missing or wrong token surfaces later, when Updatecli calls the API or clones the repository.


Further Reading


Tip: For best security and maintainability, prefer using environment variables for authentication, and avoid hardcoding secrets in your manifests.

Working branch and commit message

Both work exactly as on the "Azure DevOps" page: a working branch named <workingBranchPrefix><separator><branch><separator><pipelineID>, force defaulting to true with its "better safe than sorry" safeguard, and conventional commit messages driven by commitMessage.

The pipelineID component is derived from the manifest, not from the repository, so all copies share it and every discovered repository ends up with an identically named working branch (convenient when you later need to find or clean up the branches an organization-wide run created).

Note
commitMessage.title is deprecated and ignored. The commit title comes from the target name.

Example

This manifest bumps the Golang version across the repositories of the myorg organization: azuredevopssearch discovers them, each discovered repository/branch pair gets its own working branch and squashed commit, and the action opens one pull request per pair.

# updatecli.yaml
name: "Updatecli Golang - Azure DevOps Multi-Repo"
pipelineid: "golang/version"

scms:
  default:
    kind: azuredevopssearch
    spec:
      organization: myorg
      # project, repository and branch are regular expressions
      project: "^myproject$"
      repository: "^.*$"
      branch: "^main$"
      token: '{{ requiredEnv "UPDATECLI_AZURE_DEVOPS_TOKEN" }}'
      username: '{{ requiredEnv "UPDATECLI_AZURE_DEVOPS_USERNAME" }}'
      user: updatecli
      email: updatecli@example.com
      commitmessage:
        squash: true
        type: chore
        scope: deps

actions:
  default:
    kind: azuredevops/pullrequest
    scmid: default
    spec:
      title: "deps(golang): Bump Golang version"

sources:
  golang:
    name: Get the latest Golang version
    kind: golang
    spec:
      versionfilter:
        kind: semver
        pattern: "1.24.x"

targets:
  github-action:
    name: 'deps(github-action): Bump Golang version to {{ source "golang" }}'
    kind: yaml
    scmid: default
    spec:
      engine: yamlpath
      files:
        - ".github/workflows/*"
      key: '$.jobs.build.steps[?(@.uses =~ /^actions\/setup-go/)].with.go-version'
      searchpattern: true