Azure DevOps Search
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
| Name | Type | Description | Required |
|---|---|---|---|
| branch | string | “branch” defines the git branch regex to work on. | |
| commitmessage | object | “commitMessage” is used to generate the final commit message. | |
| body | string | body defines the commit body of the commit message as defined by the conventional commit specification. More information on -> https://www.conventionalcommits.org/en/ default: none | |
| deprecatedtitle | string | DeprecatedTitle is deprecated and will be ignored. The commit title is now always generated from the target name or description. | |
| footers | string | footers defines the footer of the commit message as defined by the conventional commit specification. More information on -> https://www.conventionalcommits.org/en/ default: none | |
| hidecredit | boolean | hideCredit defines if updatecli credits should be displayed inside commit message body please consider sponsoring the Updatecli project if you want to disable credits. -> https://github.com/updatecli/updatecli default: false | |
| scope | string | scope defines the scope of the commit message as defined by the conventional commit specification. More information on -> https://www.conventionalcommits.org/en/ default: none | |
| squash | boolean | squash defines if the commit should be squashed default: false important: if squash is set to true, then it’s highly recommended to set the commit body to a meaningful value as all other commit information will be lost during the squash operation. if body is not set, then the commit title/message will be generated based on the most recent commit message of the squashed commits. The commit title is always generated from the target name or description. | |
| title | string | Title is the parsed commit message title (not configurable via YAML). The title is automatically generated from the target name or description. | |
| type | string | type defines the type of commit message such as “chore”, “fix”, “feat”, etc. as defined by the conventional commit specification. More information on -> https://www.conventionalcommits.org/en/ default:
| |
| depth | integer | Depth defines the depth used when cloning the git repository. | |
| directory | string | “directory” defines the local path where the git repository is cloned. | |
| string | “email” defines the email used to commit changes. | ||
| force | boolean | “force” is used during the git push phase to run git push --force. | |
| gpg | object | “gpg” specifies the GPG key and passphrase used for commit signing. | |
| passphrase | string | passphrase defines the gpg passphrase used to sign the commit message | |
| signingkey | string | signingKey defines the gpg key used to sign the commit message default: none | |
| limit | integer | Limit defines the maximum number of repositories to return. | |
| organization | string | “organization” defines the Azure DevOps organization. | |
| project | string | “project” defines the Azure DevOps project regex used to match projects to search in. | |
| repository | string | “repository” defines the Azure DevOps repository regex used to match repositories. | |
| submodules | boolean | “submodules” defines if Updatecli should checkout submodules. | |
| token | string | “token” specifies the personal access token used to authenticate with Azure DevOps. | |
| url | string | “url” defines the Azure DevOps base URL. | |
| user | string | “user” specifies the user associated with new git commit messages created by Updatecli. | |
| username | string | “username” specifies the username used for git authentication. | |
| workingbranch | boolean | “workingBranch” defines if Updatecli should use a temporary branch to work on. | |
| workingbranchprefix | string | WorkingBranchPrefix defines the prefix used to create a working branch. | |
| workingbranchseparator | string | WorkingBranchSeparator defines the separator used to create a working branch. |
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 branchAnchors 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 TokenUPDATECLI_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 |
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:
azuredevopsThe manifest wins.
UPDATECLI_AZURE_DEVOPS_TOKENandUPDATECLI_AZURE_DEVOPS_USERNAMEonly fill in the fields the manifest leaves empty.azuredevopssearchThe 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