---
title: "Azure DevOps"
order: 9
---

:::(Internal) (TODO)
* "Connecting to Azure DevOps" -> should be a HOWTO
* Document Azure DevOps Issue Source.
* Link to Feature Branch Workflow Pipeline below
:::

[Azure DevOps](https://azure.microsoft.com/en-us/services/devops/) is a CI/CD service provided as part of Microsoft's Azure platform. Their [pipelines](https://azure.microsoft.com/en-us/services/devops/pipelines/) support containers natively, so many shops building and deploying containers turn to Azure DevOps Pipelines. BuildMaster is designed to work *alongside* Azure DevOps to provide a self-managed CI/CD solution using BuildMaster's [Git Integration](/docs/buildmaster/builds-continuous-integration/buildmaster-git-source-control), [Issue Tracking](/docs/buildmaster/tools-service-integrations/buildmaster-integrations-azure-devops/buildmaster-integrations-azure-devops-issues), and [Importing Builds](/docs/buildmaster/tools-service-integrations/buildmaster-integrations-azure-devops/buildmaster-integrations-azure-devops-importing-builds).

## Connecting to Azure DevOps
:::(Internal) (TODO)
This should be migrated/converted to a HOWTO.
:::
BuildMaster's [Git Integration](/docs/buildmaster/builds-continuous-integration/buildmaster-git-source-control) allows you to connect to Azure DevOps at application creation or through the application's settings page.  To connect BuildMaster to Azure DevOps:

1. Either create a new application or add a new connection on the application settings page, then select Git Repository
![select-connection-type](/resources/docs/select-connection-type.png){width="50%"}
2. Select the Azure DevOps connection type
![git-connect-to-service](/resources/docs/git-connect-to-service.png){width="50%"}
3. Enter your Azure DevOps instance URL, user name, and [personal access token(#Generating-a-Azure-DevOps-Personal-Access-Token)] and click Select Azure DevOps Repository
![ado-connect-to](/resources/docs/ado-connect-to.png){width="50%"}
4. Select your Azure DevOps project and enter or select your repository and click Save Repository
![ado-connnect-repository](/resources/docs/ado-connnect-repository.png){width="50%"}

The Azure DevOps repository will then be [synchronized to your server](/docs/buildmaster/builds-continuous-integration/buildmaster-git-source-control#synchronized-git-repositories) and you will see a successfully synced message.
![ado-successfully-synced](/resources/docs/ado-successfully-synced.png){width="50%"}

### Editing a Azure DevOps Connection 

You can edit these items directly to enable advanced scenarios (such as a shared repository) by clicking View All on the Settings page, or by going to Admin > Credentials & Resources.  See [Credentials & Resources](/docs/buildmaster/configuring-for-your-team/buildmaster-administration-resource-credentials) to learn more.

## Generating a Azure DevOps Personal Access Token

When connection BuildMaster to Azure DevOps, you need to use a [Azure DevOps Personal Access Token (PAT)](https://learn.microsoft.com/en-us/azure/devops/organizations/accounts/use-personal-access-tokens-to-authenticate?view=azure-devops).  To generate this token:
1. Navigate to your Azure DevOps project
2. In the upper right corner, click user settings icon, and then click _Personal Access Token_
3. Click "+ New Token"
4. Enter a Name, select your organization, enter an expiration, and select the following scopes
   - `Work Items` - `Read & Write`
   - `Code` - `Full`
   - `Build` - `Read & execute` (Only required if [importing builds](/docs/buildmaster/tools-service-integrations/buildmaster-integrations-azure-devops/buildmaster-integrations-azure-devops-importing-builds))
   - `Release` - `Read, write, & execute` (Only required if [importing builds](/docs/buildmaster/tools-service-integrations/buildmaster-integrations-azure-devops/buildmaster-integrations-azure-devops-importing-builds))
5. Click Create

## Browsing Azure DevOps Repositories

After adding a synchronized Azure DevOps repository to an application, you'll be able to browse that repository's branches, source code, and commits—as well as the changes between builds/releases—directly from BuildMaster's web UI.  See our [synchronized git repositories documentation](/docs/buildmaster/builds-continuous-integration/buildmaster-git-source-control#synchronized-git-repositories) to learn more.

::: (Info) (Note:)
When viewing branch, tag, or commit details, you can also click the "browse on Azure DevOps" link to view details in Azure DevOps directly.
:::

## Issue Tracking
By connecting your BuildMaster application to an Azure DevOps issue tracker, your work items will be automatically synchronized with BuildMaster's issues. This will allow you to browse issues, tie them to specific releases, and block releases when there are untested or unresolved issues from within BuildMaster. See our [Azure DevOps Issue Tracking](/docs/buildmaster/tools-service-integrations/buildmaster-integrations-azure-devops/buildmaster-integrations-azure-devops-issues) documentation for more information.

BuildMaster also allows you create or update your work items using OtterScript operations.  

::: (Internal) (TODO)
Document Azure DevOps Issue Source.
:::

## Integrating Azure DevOps Builds
BuildMaster allows you to import artifacts from your Azure DevOps builds and deploy them to your server. BuildMaster includes a number of OtterScript operations for working with Azure DevOps Builds, see our [Importing Builds from Azure DevOps](/docs/buildmaster/tools-service-integrations/buildmaster-integrations-azure-devops/buildmaster-integrations-azure-devops-importing-builds) for more information.

## Azure DevOps and Scripting
If your application uses a synchronized Azure DevOps repository, you can create a build from any commit of the repository. When you create a build in this way, the selected commit—along with its branch and repository—will be associated with that build and displayed at UI.You can access those values in scripts with the `$Commit`, `$Branch`, and `$Repository` variable functions.  See [Git Build Scripts & Automations](/docs/buildmaster/builds-continuous-integration/buildmaster-git-source-control#build-scripts-operations) for more information.

### Azure DevOps Git Operations

::: (Internal) (TODO)
These feel a little too long / copypasta, and also doesn't really provide any ADO-specific information about how Inedo's operations map to ADO concepts.

Assume the reader has already read & studied (or can read and study) the Git parent docuemtation, and just wants to know how these fields "map" to ADO. The information is mostly different, and is probably very minimal

For example, Credeential maps to an Organization. What's a "namespace" in ADO (I think it's a project??), what is a repository, etc.

Git::SetStatus  can link to their documentation for which each field means.

:::

The Azure DevOps integration supports all standard [BuildMaster Git operations](/docs/buildmaster/builds-continuous-integration/buildmaster-git-source-control#build-scripts-operations), but there are a few things to keep in mind when using these operations. Azure DevOps credentials are tied to an organization and that organization consists of multiple projects, with each project having one or more Git repositories. This is different from other Git repositories because there is an additional project layer between your organization and your Git repository.

#### Using Other Git Repositories
By default, `Git::Checkout-Code` will use your Git Connection to connect to the repository.  If you would like to select a repository that is different than what your Git connection specifies; find your [Azure DevOps Repository URL](https://learn.microsoft.com/en-us/azure/devops/repos/git/clone?view=azure-devops&tabs=git-command-line), remove the user name from it (ex., use `https://dev.azure.com/kramerica/Kramerica-Project/_git/Kramerica` instead of `https://sdennis@dev.azure.com/kramerica/Kramerica-Project/_git/Kramerica`), then set the `RepositoryUrl` parameter to it in the`Git::Checkout-Code` operation.

In these cases, you can specify input parameters like this.
```
Git::Checkout-Code
(
    RepositoryUrl: https://dev.azure.com/kramerica/Kramerica-Project/_git/Kramerica,
    BranchOrCommit: master,
    To: c:\build\space\src,
    CommitHash => $CommitId
);
Log-Information Checked out at $CommitId from my-repo;
```

#### Git::Set-CommitStatus Operation
Azure DevOps allows you to set the "status" of a particular commit, as it relates to a successful build. This status is often displayed in Azure DevOps' UI when listing commits.

To set this status in BuildMaster, you can simply call the operation with the desired status. In general, you'll want to use a `try..catch` statement as follows:
```
Git::Checkout-Code;

Git::Set-CommitStatus pending;
try
{
    ... perform build operations...
    Git::Set-CommitStatus success;
}
catch
{
    Git::Set-CommitStatus error;
    throw;
}
```

Like the `Git::Checkout-Code` operation, the operation will use `$Commit` and  `$Repository` if you don't specify them as parameters. The operation can also automatically determine the status, but you can override that by specifying the  `Status` parameter:
 * `pending` - a build is about to start or is running
 * `succeeded` - build completed successfully
 * `failed` - execution didn't complete or there was an error unrelated to build compilation/tests
 * `error` - execution completed but with a build error
* `notApplicable` - the status is not applicable for that commit
* `notSet` - sets the commit status back to its default state
* `auto` - BuildMaster chooses `succeeded` or `error` based on current state
 
 #### Git::Create-PullRequest and Git::Merge-PullRequest

Just like `Git::Checkout-Code`, the `Git::Create-PullRequest` operation will use your Git Repository connection to create a pull request. Here is an example of using a repository that is different from the one specified in your Git Repository connection:

```
Git::Create-PullRequest
(
    Title: My New Thing,
    Target: main,
    Repository: https://dev.azure.com/kramerica/Kramerica-Project/_git/Kramerica
);
```

This operation will also record the ID of the Pull Request on the Build, so that you can later access it with `$PullRequestId`.

 ::: (Internal) (TODO once implemented)
### Link to Feature Branch Workflow Pipeline below

- Make this an info box
The Feature Branch Workflow Pipeline will create a script with the `Git::Create-PullRequest` operation. Try it out to see this in action.

You may wish to extend your Feature Branch workflow, and have BuildMaster perform the merge. 

To merge a pull request, you can run the operation without any parameters:
```
Git::Merge-PullRequest;
```

This will use the `$PullRequestId` if you don't specify it as a parameter.

:::

### Azure DevOps Work Item Operations

#### AzureDevOps::Find-WorkItems
This operation allows you to find work items in Azure DevOps for use in your OtterScript.

To find all work items in the Kramerica project under iteration path 1.10.0, you can use this operation:
```
AzureDevOps::Find-WorkItems
(
    Credentials: AzureCredentials,
    Project: Kramerica,
    IterationPath: 1.10.0,
    Output => @workItems
);
```

Find-WorkItems will return a list of mapped objects.  You can then convert each item to a [map variable](/docs/buildmaster/otterscript-execution-engine/buildmaster-variables) using a `foreach` in OtterScript.

```
foreach %item in @workItems
{
    Log-Debug %item[Id] %item[System.Description];
}
```

::: (Info)
Each item must be converted to a map variable, not a scalar variable. 
:::

#### WIQL Filter
By default, BuildMaster will start with the following [WIQL query](https://docs.microsoft.com/en-us/azure/devops/boards/queries/wiql-syntax?view=azure-devops\) to find work items.

```
SELECT [System.Id], [System.State], [System.Title], [System.Description] 
FROM WorkItems
```

If the `ProjectName` and `IterationPath` are specified, BuildMaster will add `WHERE [System.TeamProject] = 'PROJECT_NAME' AND [System.IterationPath] UNDER 'ITERATION_PATH' ` to the query.  If the `Filter` parameter is included, it will also append that filter to the where clause of the query.

When there is a need to perform a more complex WIQL query, you can specify the entire query to the `CustomWiql` parameter.  When using that parameter, `ProjectName`, `IterationPath`, and `Filter` will be ignored.

#### AzureDevOps::Create-WorkItem
Use this operation to create a new work item in Azure DevOps.

To add a new work item in the Kramerica project under the 1.10.0 iteration path, you can use this operation:
```
AzureDevOps::Create-WorkItem
(
    Credentials: AzureCredentials,
    Project: Kramerica,
    Type: Task,
    Title: QA Testing Required for $ApplicationName,
    IterationPath: 1.10.0,
    Description: This issue was created by BuildMaster on $Date
);
```

You can also access the ID of the recently created work item by assigning a variable to the `WorkItemId` parameter (e.g. `WorkItemId => $WorkItemId`).

#### AzureDevOps::Update-WorkItem
Use this operation to update an existing work item in Azure DevOps.

To update a work item in the Kramerica project, you can use this operation:
```
AzureDevOps::Update-WorkItem
(
    Credentials: AzureCredentials,
    Project: Kramerica,
    Id: $WorkItemId,
    State: In Progress
);
```

By default, you can update the following fields on a work item:
- Title
- Description
- Iteration Path
- State

If you would like to update a field that is not included out of the box, you can pass a [map variable](/docs/buildmaster/otterscript-execution-engine/buildmaster-variables) to the `OtherFields` parameter.  The map variable must use the field name defined in WIQL.  For example, if you want to upgrade the "Integration Build" field you would use the following OtterScript:
```
AzureDevOps::Update-WorkItem
(
    Credentials: AzureCredentials,
    Project: Kramerica,
    Id: $WorkItemId,
    OtherFields: %(Microsoft.VSTS.Build.IntegrationBuild:$ReleaseNumber.$BuildNumber)
);
```

### Azure DevOps Build Operations
See our [Importing Builds from Azure DevOps](/docs/buildmaster/tools-service-integrations/buildmaster-integrations-azure-devops/buildmaster-integrations-azure-devops-importing-builds) documentation for the available OtterScript operations.

## Installing the Azure DevOps Extension 

The Azure DevOps extension is installed by default when you install BuildMaster. You can upgrade the extension by simply navigating to the *Admin > Extensions* page in your instance of BuildMaster and clicking the update link to the right of the Azure DevOps extension. Once the Azure DevOps extension has been upgraded, it can be downgraded back to the built-in version by navigating to *Admin > Extensions > Azure DevOps* and then selecting the Change Version button in the upper right corner.

If your instance doesn't have Internet access, you can upgrade/downgrade it by [manually install the Azure DevOps extension](/docs/buildmaster/reference/extensions#manual-install) after downloading the [Azure DevOps Extension Package](https://proget.inedo.com/feeds/Extensions/inedox/AzureDevOps).

:::(Info) (NOTE:)
Built-in extensions cannot be deleted or downgraded past the included version.
:::
