# Azure DevOps Search<no value>
// <!-- Required for asciidoctor -->
:toc:
// Set toclevels to be at least your hugo [markup.tableOfContents.endLevel] config key
:toclevels: 4

== 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 link:/docs/plugins/scm/azuredevops/[`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 link:/docs/plugins/actions/azuredevops/["Azure DevOps Pull Request" page]).

== Parameters

{{< resourceparameters "scms" "azuredevopssearch" >}}

`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 link:/docs/plugins/scm/azuredevops/["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$`.

[source,yaml]
----
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.

include::content/en/docs/plugins/_azuredevopsAuth.adoc[]

=== Working branch and commit message

Both work exactly as on the link:/docs/plugins/scm/azuredevops/["Azure DevOps" page]: a working branch named `<workingBranchPrefix><separator><branch><separator><pipelineID>`, `force` defaulting to `true` with its "better safe than sorry" safeguard, and link:https://www.conventionalcommits.org/[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.

[source,yaml]
----
# updatecli.yaml
{{<include "assets/code_example/docs/plugins/scm/azuredevopssearch/updatecli.d/default.yaml">}}
----
