Azure DevOps
Description
The azuredevops scm plugin clones a repository hosted on Azure DevOps (dev.azure.com or a self-hosted Azure DevOps Server) and pushes changes back to it. It is referenced by a resource through its scmid, as described on the "SCM" page.
Its behavior depends on the stage referencing it:
- source and condition
The repository is cloned and the resource works on the files from the branch defined by
branch. Nothing is pushed.- target
Updatecli creates a working branch based on
branch, commits the changes to it, and pushes that branch. Thebranchvalue itself is left untouched.
Important | This plugin does not open pull requests. Pushing a working branch and opening a pull request are two distinct steps: the pull request comes from an actions block of kind azuredevops/pullrequest, documented on the "Azure DevOps Pull Request" page. Without such an action, the branch is pushed and nothing else happens. |
Parameters
| Name | Type | Description | Required |
|---|---|---|---|
| branch | string | “branch” defines the git branch 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 passphrased 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 | |
| organization | string | Organization defines the Azure DevOps organization URL to interact with. | |
| project | string | “project” defines the Azure DevOps project containing the repository. | |
| repository | string | “repository” defines the Azure DevOps repository name. | |
| 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 organization URL to interact with. | |
| user | string | “user” specifies the user associated with new git commit messages created by Updatecli. | |
| username | string | “username” defines 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 validated at load time, leaving it out aborts the run with wrong azure devops configuration. project and repository are needed to locate the repository, which is cloned from:
<url>/<organization>/<project>/_git/<repository>Note | The table is generated from the Updatecli JSON schema, refreshed by a bot after each release. A recently added parameter (currently singleBranch, which restricts clone and fetch to the configured branch) may work in the binary before it appears there. |
Authentication
url defaults to https://dev.azure.com. For Azure DevOps Server, give the base URL of your instance, with or without a scheme; https:// is assumed when none is given, and a trailing slash is removed.
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.
When token is set without a username, Updatecli uses updatecli-bot as the git username (Azure DevOps ignores the username of a PAT, so this only needs to be non-empty).
Working branch
For a target, the working branch is derived from three components joined by a separator:
<workingBranchPrefix><workingBranchSeparator><branch><workingBranchSeparator><pipelineID>With the defaults (updatecli and ), a pipeline based on main produces updatecli_main<pipelineID>, where pipelineID is a hash derived from the manifest - so the same pipeline reuses the same branch instead of piling up new ones. Characters git refuses in a ref are stripped, and the name is truncated to 255 characters. Setting workingBranchPrefix: "" gives <branch>_<pipelineID>.
branch defaults to main, with a warning in the logs when it is left unset.
Disabling the working branch
workingBranch: false makes Updatecli commit and push straight to branch. Since force defaults to true (meaning git push --force), that combination is refused unless force is also set explicitly:
Better safe than sorry.
Updatecli may be pushing unwanted changes to the branch "main".Set force: false to push without forcing, or force: true to acknowledge the force push. When force is true, Updatecli also recreates working branches that diverged from their base branch.
Tip | updatecli apply --clean-git-branches deletes, at the end of a run, the working branches that ended up identical to their base branch (those left behind by pipelines that had nothing to change). |
Commit message
Updatecli generates conventional commits. The commitMessage parameters (type, scope, body, footers, hideCredit, squash) shape the result.
The commit title always comes from the target’s name, or from its description when name is unset. It is capped at 72 characters minus the room taken by type and scope; the overflow moves into the body. With the default type chore:
Author: updatecli-bot <updatecli-bot@updatecli.io>
Date: Tue May 4 15:41:44 2021 +0200
chore: Update key "dependencies[0].version" from file "charts/jenkins/r...
... equirements.yaml"
Made with ❤️️ by updatecliSetting body replaces the generated body entirely, including that overflow. hideCredit: true drops the credit line. squash: true collapses the commits of the working branch into one (set body when you use it, since the individual messages are lost).
Warning |
|
Note | commitMessage applies to every target linked to the same scm. |
Commit signing and identity
gpg.signingkey takes an armored private GPG key and gpg.passphrase its passphrase. Both are secrets:
gpg:
signingkey: '{{ requiredEnv "GPG_SIGNING_KEY" }}'
passphrase: '{{ requiredEnv "GPG_PASSPHRASE" }}'user and email name the commit author, defaulting to updatecli-bot and updatecli-bot@updatecli.io.
Clone behavior
Left unset, directory defaults to <tmp>/updatecli/azuredevops/<project>/<repository> on your system temporary directory. Overriding it is rarely useful, as Updatecli may clean that directory up after a run.
submodulesDefaults to
true; set it tofalseto skip submodule checkout.depthNumber of commits to fetch. Unset means a full clone. A shallow clone leaves an incomplete history, which can break pushes;
force: trueis often needed alongside.singleBranchDefaults to
false, meaning every branch, tag, and ref is fetched.truefetches onlybranch(much faster on repositories with many refs, at the cost of Updatecli sometimes failing to notice an already published working branch and opening a duplicate pull request).
Tip | To run the same manifest against every repository of an organization instead of a single one, use the azuredevopssearch scm. |
Example
This pipeline updates the Golang version in a single Azure DevOps repository: the change is committed on a working branch, and the azuredevops/pullrequest action turns that branch into a pull request against main.
# updatecli.yaml
name: Update a file and open an Azure DevOps Pull Request
scms:
default:
kind: azuredevops
spec:
organization: myorg
project: myproject
repository: myrepo
branch: main
token: '{{ requiredEnv "UPDATECLI_AZURE_DEVOPS_TOKEN" }}'
username: '{{ requiredEnv "UPDATECLI_AZURE_DEVOPS_USERNAME" }}'
user: updatecli
email: updatecli@example.com
sources:
golang:
name: Get the latest Golang version
kind: golang
spec:
versionfilter:
kind: semver
pattern: "1.24.x"
targets:
golang-version:
name: 'deps(golang): Bump Golang version to {{ source "golang" }}'
kind: yaml
scmid: default
spec:
file: .github/workflows/*.yaml
key: '$.jobs.build.steps[?(@.uses =~ /^actions\/setup-go/)].with.go-version'
searchpattern: true
actions:
default:
kind: azuredevops/pullrequest
scmid: default
spec:
title: 'deps(golang): Bump Golang version'