# Build tasks

Build tasks compose a Business Central build pipeline: resolve the artifact, version the app, create the container, restore dependencies, compile, sign, publish, test and clean up. Every build task is **free of license**. Each task is a thin wrapper over exactly one `businessdev.ALbuild` cmdlet, so the behaviour is identical locally and in CI.

## Tasks in this category

| Task | Reference name | Purpose |
| --- | --- | --- |
| [Check Translations](#check-translations) | `CheckTranslations@0` | Checks AL XLIFF files for missing and needs-work translations (CI gate). |
| [Cleanup ALbuild Caches](#cleanup-albuild-caches) | `CleanupCaches@0` | Prunes old, unused ALbuild artifact/package/BC-artifact caches (and optionally Docker) to reclaim agent disk space. |
| [Compile AL App](#compile-al-app) | `CompileApp@0` | Compiles an AL project into an .app package using the AL tool or a container. |
| [Create BC Container](#create-bc-container) | `CreateBcContainer@0` | Creates a Business Central container from an artifact URL and waits for it to be ready. |
| [Create BC Container User](#create-bc-container-user) | `CreateBcContainerUser@0` | Creates a Business Central user inside a container and assigns a permission set. |
| [Create NuGet Package](#create-nuget-package) | `CreateNuGetPackage@0` | Creates a NuGet package (.nupkg) from a compiled Business Central .app. |
| [Get BC Artifact](#get-bc-artifact) | `GetBcArtifact@0` | Resolves a Business Central artifact URL and stores it in an output variable. |
| [Get Universal Package](#get-universal-package) | `GetUniversalPackage@0` | Downloads a named package from an Azure DevOps Universal feed into a folder. |
| [Import Configuration Package](#import-configuration-package) | `ImportConfigPackage@0` | Imports a RapidStart (.rapidstart) configuration package into a Business Central container. |
| [Install 365 App](#install-365-app) | `InstallBc365App@0` | Installs one or more 365 business development apps into a Business Central container. |
| [Install Dependencies](#install-dependencies) | `InstallDependencies@0` | Installs an AL project's resolved dependency apps into the container, in dependency order. |
| [Install Test Toolkit](#install-test-toolkit) | `InstallTestToolkit@0` | Publishes and installs the Business Central test toolkit apps into a container. |
| [Publish App](#publish-app) | `PublishApp@0` | Publishes, synchronises and installs an .app into a Business Central container. |
| [Publish Testiny Results](#publish-testiny-results) | `PublishTestinyResults@0` | Publishes a JUnit test result file to Testiny. |
| [Remove BC Container](#remove-bc-container) | `RemoveBcContainer@0` | Removes a Business Central build container. |
| [Resolve Dependencies](#resolve-dependencies) | `ResolveDependencies@0` | Resolves an AL project's dependencies from NuGet feeds and writes them to .alpackages. |
| [Run AL Tests](#run-al-tests) | `RunBcTests@0` | Runs AL tests in a Business Central container using ALbuild's built-in test runner and publishes a JUnit result file. |
| [Sign AL App](#sign-al-app) | `SignBcApp@0` | Signs .app files with an Azure Key Vault certificate (AzureSignTool). |
| [Stamp Build Version](#stamp-build-version) | `StampBuildVersion@0` | Stamps the app version into app.json and atomically claims a build/&lt;version> branch (parallel-safe). |

---

## Check Translations

**Reference name:** `CheckTranslations@0`

Checks AL XLIFF files for missing and needs-work translations (CI gate).

> **Note:** Wraps Test-BcTranslation from the businessdev.ALbuild module.

**Underlying cmdlet:** [`Test-BcTranslation`](../powershell-module/apps#test-bctranslation)

### Example

```yaml
- task: CheckTranslations@0
  displayName: 'Check translations'
  inputs:
    path: ''                # empty = all AL projects in the repo
    skipNeedsWork: false
    failOnIssue: true
```

### Inputs

| Input | Type | Required | Default | Description |
| --- | --- | :---: | --- | --- |
| `path` | filePath | No | — | Translations path (empty = all AL projects in the repo) |
| `excludeProjects` | string | No | — | Projects to exclude (folder names, comma-separated) |
| `skipNeedsWork` | boolean | No | `false` | Only check for missing translations |
| `failOnIssue` | boolean | No | `true` | Fail on any issue |

> **Note:** Validates the .xlf translation files (missing or untranslated entries). `failOnIssue` (default true) fails the build when problems are found; `skipNeedsWork` (default false) ignores units flagged as needing work. This task sets no output variables.

---

## Cleanup ALbuild Caches

**Reference name:** `CleanupCaches@0`

Prunes old, unused ALbuild artifact/package/BC-artifact caches (and optionally Docker) to reclaim agent disk space.

> **Note:** Wraps Clear-ALbuildCache from the businessdev.ALbuild module. Removes cache entries not written within the retention window (default 30 days), keeping recent ones, from the cache folders configured via Get-ALbuildConfig. Runs non-interactively (no confirmation prompt); use 'What-if' to preview.

### Example

```yaml
- task: CleanupCaches@0
  displayName: 'Prune ALbuild caches'
  condition: always()          # keep the agent lean even when the build failed
  inputs:
    keepDays: '3'              # remove cache entries not written in the last 3 days
    keepLatest: '1'            # ...but always keep the newest per cache (the version in use)
    cache: 'All'              # All | Artifacts | Packages | BcArtifacts
    includeDocker: true        # also prune dangling BC images + stopped containers
```

### Inputs

| Input | Type | Required | Default | Description |
| --- | --- | :---: | --- | --- |
| `keepDays` | string | No | `30` | Cache entries not written within this many days are removed. Default 30. |
| `keepLatest` | string | No | `0` | Safety floor: always keep at least this many most-recently-written entries per cache, regardless of age. |
| `cache` | pickList | No | `All` | Caches to prune **Options:** `All = All`, `Artifacts = Artifacts (symbols)`, `Packages = Packages`, `BcArtifacts = BC artifacts`. |
| `includeDocker` | boolean | No | `false` | Also prune unused Docker images/stopped containers |
| `whatIf` | boolean | No | `false` | What-if (preview only, delete nothing) |

> **Note:** Reclaims disk on long-lived self-hosted agents. ALbuild's caches grow unbounded - a multi-GB entry per BC version in the BC artifact cache (C:\bcartifacts.cache -> C:\dl), the host artifact/symbol cache and the dependency package cache - and nothing trims them automatically; repeated 'docker pull' also orphans old images. Add this as a first or scheduled step so every build self-maintains. `keepLatest` is a safety floor (never empties a cache); `keepDays` sets the retention window. `includeDocker` runs `docker image/container prune` filtered to the same window. Use `whatIf: true` to preview what would be removed without deleting. Reads the cache locations from Get-ALbuildConfig, so it prunes exactly the folders the tasks use (including any relocated to a roomier drive). This task sets no output variables. As of module 2.17.0, New-BcContainer also auto-prunes as a last resort when the drive is below its disk floor - but a scheduled CleanupCaches step is the intended retention mechanism.

---

## Compile AL App

**Reference name:** `CompileApp@0`

Compiles an AL project into an .app package using the AL tool or a container.

> **Note:** Wraps Invoke-BcCompiler from the businessdev.ALbuild module.

**Underlying cmdlet:** [`Invoke-BcCompiler`](../powershell-module/apps#invoke-bccompiler)

### Example

```yaml
- task: CompileApp@0
  displayName: 'Compile AL app'
  inputs:
    projectFolder: ''            # empty = all AL projects in the repo, in dependency order
    engine: 'AlTool'            # container-less compile with the AL tool
    artifactUrl: '$(bcArtifactUrl)'
    # analyzers: 'CodeCop,UICop' # empty = use albuild.json / .vscode settings
    # updateManifest: true       # rewrite app.json to the target BC version (runtime-package builds)
    # alToolPrerelease: 'Auto'   # NextMajor: use the prerelease compiler when the runtime has no stable one
  # -> sets $(bcAppFile) (first app) and $(bcAppFiles) (all, ';'-joined)
```

### Inputs

| Input | Type | Required | Default | Description |
| --- | --- | :---: | --- | --- |
| `projectFolder` | filePath | No | — | Project folder (empty = all AL projects in the repo) |
| `excludeProjects` | string | No | — | Projects to exclude (folder names, comma-separated) |
| `outputFolder` | filePath | No | — | Where to write the built .app files. Leave empty to use the build's artifact staging directory, so the Sign and Publish tasks find them without extra wiring. |
| `engine` | pickList | No | `AlTool` | Engine **Options:** `AlTool = AL tool (cross-platform)`, `Container = Container`. |
| `containerName` | string | No | — | Container name (Container engine) |
| `artifactUrl` | string | No | `$(bcArtifactUrl)` | BC artifact URL (for first-party symbols) |
| `testToolkitSymbols` | string | No | `$(bcTestToolkitSymbols)` | Host folder of test-toolkit .app symbols bridged out of the container by the Install Test Toolkit task. Needed for an AL Tool compile of a test app when the artifact ships those symbols only inside the container (e.g. country 'w1'). |
| `compilerPath` | string | No | — | AL compiler path (blank = auto-detect / install the AL Tool) |
| `installAlTool` | boolean | No | `true` | Install the AL Tool on the agent if missing (AlTool engine) |
| `alToolVersion` | string | No | — | Pin an exact AL Tool (compiler) version, e.g. '18.0.39.10160-beta'. Leave blank to derive it from the BC artifact being built against: the AL Tool major IS the AL runtime it supports (BC28 = runtime 17 = AL Tool 17.x, BC29 = 18 = 18.x). A compiler older than the app's runtime fails with AL1043. |
| `alToolPrerelease` | pickList | No | `Auto` | A BC major that has not shipped yet (NextMajor) publishes ONLY prerelease ('-beta') compilers, so 'Auto' falls back to one for that runtime and returns to the stable compiler automatically once the major goes GA. 'Never' makes such a build fail rather than use a prerelease compiler. **Options:** `Auto = Auto - only when the target runtime has no stable compiler (NextMajor)`, `Always = Always - newest, even if prerelease`, `Never = Never - stable only`. |
| `analyzers` | string | No | — | Analyzers to run during compile: 'CodeCop', 'UICop', 'AppSourceCop', 'PerTenantExtensionCop' (with or without the '$&#123;...}' wrapper), or explicit analyzer DLL paths. Overrides the project's albuild.json 'analyzers' and .vscode/settings.json 'al.codeAnalyzers'. Leave blank to use those. Empty everywhere = no analyzers. |
| `ruleset` | string | No | — | Ruleset file applied to the analyzers. Overrides albuild.json 'ruleset' and .vscode/settings.json 'al.ruleSetPath'. Relative paths resolve against the project folder. |
| `updateManifest` | boolean | No | `false` | Before compiling, rewrite each app.json for the BC version being built against: set application/runtime/platform to the target, and inject the BC&lt;min>..BC&lt;current> preprocessor symbols (min = the app's own 'application' major) so version-conditional AL ('#if BC24') compiles. Needed when building runtime packages for older platform versions. |
| `preprocessorSymbols` | string | No | — | Additional preprocessor symbols to add alongside the BC&lt;n> range (only applied when 'Update app.json' is enabled). |
| `treatWarningsAsErrors` | boolean | No | `false` | When true, any 'warning' diagnostic from the compiler or an analyzer fails the task (the individual warnings are still shown as annotations). Use to enforce a clean-code / analyzer quality gate. Default false keeps existing pipeline behaviour. |

### Option values

**`engine`**

| Value | Meaning |
| --- | --- |
| `AlTool` | Cross-platform, container-less compile with the AL compiler tool (fast; no container needed). Default. |
| `Container` | Compile inside the BC container named by `containerName` (uses the container's bundled compiler). |

**`alToolPrerelease`**

| Value | Meaning |
| --- | --- |
| `Auto` | Prefer a stable compiler for the target runtime, and fall back to a prerelease only when that runtime has none. Default - this is what makes a **NextMajor** build work, and it returns to the stable compiler by itself once the BC major ships. |
| `Always` | Always take the newest compiler for the runtime, even when it is a prerelease. |
| `Never` | Stable compilers only; a build whose target runtime has no stable compiler fails instead of using a prerelease. |

### Output variables

| Variable | Description |
| --- | --- |
| `bcAppFile` | Path to the first built .app (convenience for single-app repos). |
| `bcAppFiles` | All built .app paths, semicolon-joined, in dependency (build) order. |

> **Note:** The `analyzers` input is free text, not a pickList: the built-in names are `CodeCop`, `UICop`, `AppSourceCop`, `PerTenantExtensionCop` (with or without the `${...}` wrapper), or explicit analyzer DLL paths. It overrides albuild.json `analyzers` and .vscode/settings.json `al.codeAnalyzers`; blank everywhere = no analyzers.

The AL compiler is matched to the BC version you build against: the AL Tool's major version IS the AL runtime it supports (BC28 = runtime 17 = AL Tool 17.x, BC29 = 18 = 18.x), and a compiler older than the app's `runtime` fails with `AL1043`. The task derives that from `artifactUrl` and installs the matching AL Tool into its own per-version folder rather than the machine-wide global tool, so parallel stages building different BC majors on one agent keep their own compiler. Pin an exact version with `alToolVersion`, or change the prerelease policy with `alToolPrerelease`.

---

## Create BC Container

**Reference name:** `CreateBcContainer@0`

Creates a Business Central container from an artifact URL and waits for it to be ready.

> **Note:** Wraps New-BcContainer from the businessdev.ALbuild module. Sets the 'containerName', 'containerUsername' and 'containerPassword' pipeline variables for downstream tasks.

**Underlying cmdlet:** [`New-BcContainer`](../powershell-module/containers#new-bccontainer)

### Example

```yaml
- task: CreateBcContainer@0
  displayName: 'Create BC container'
  inputs:
    artifactUrl: '$(bcArtifactUrl)'
    containerName: 'albuild-$(Build.BuildId)'
    auth: 'UserPassword'
    userName: 'admin'
    # password: '$(BcContainerPassword)'   # empty = a random password is generated
    # licenseFile: '$(BcLicensePath)'
    # isolation: ''                         # empty = auto (Docker decides process/hyperv)
  # -> sets $(containerName), $(containerUsername), $(containerPassword) (secret)
```

### Inputs

| Input | Type | Required | Default | Description |
| --- | --- | :---: | --- | --- |
| `artifactUrl` | string | No | `$(bcArtifactUrl)` | Artifact URL |
| `containerName` | string | No | `albuild-$(Build.BuildId)` | Container name |
| `auth` | pickList | No | `UserPassword` | Authentication **Options:** `UserPassword = UserPassword`, `NavUserPassword = NavUserPassword`, `Windows = Windows`, `AAD = AAD`. |
| `userName` | string | No | `admin` | Admin user name |
| `password` | string | No | — | Admin password (blank = generated) |
| `licenseFile` | string | No | — | License file (path or URL) |
| `memoryLimit` | string | No | — | Memory limit (e.g. 8G) |
| `isolation` | pickList | No | — | Isolation **Options:** ` = (auto)`, `process = process`, `hyperv = hyperv`. |

### Option values

**`auth`**

| Value | Meaning |
| --- | --- |
| `UserPassword` | Username/password authentication (the usual CI choice). |
| `NavUserPassword` | Classic NAV username/password authentication. |
| `Windows` | Windows (NTLM) authentication using the container host identity. |
| `AAD` | Microsoft Entra ID (Azure AD) authentication. |

**`isolation`**

| Value | Meaning |
| --- | --- |
| `(empty)` | Let Docker choose the isolation mode automatically based on the host. |
| `process` | Process isolation - lighter/faster; requires matching host and container OS builds. |
| `hyperv` | Hyper-V isolation - stronger isolation; tolerates host/container OS mismatch, more overhead. |

### Output variables

| Variable | Description |
| --- | --- |
| `containerName` | The name of the created container (consumed by Publish/Run tasks). |
| `containerUsername` | The admin username inside the container. |
| `containerPassword` | The admin password (marked secret; a random password is generated when `password` is left blank). |

> **Note:** If `password` is blank a random password is generated and exposed (secret) as `$(containerPassword)`. `memoryLimit` (e.g. `8G`) caps container memory. Requires a Docker engine on the agent.

---

## Create BC Container User

**Reference name:** `CreateBcContainerUser@0`

Creates a Business Central user inside a container and assigns a permission set.

> **Note:** Wraps New-BcContainerUser from the businessdev.ALbuild module.

**Underlying cmdlet:** [`New-BcContainerUser`](../powershell-module/containers#new-bccontaineruser)

### Example

```yaml
- task: CreateBcContainerUser@0
  displayName: 'Create BC container user'
  inputs:
    containerName: '$(containerName)'
    userName: 'testuser'
    password: '$(BcTestUserPassword)'
    permissionSetId: 'SUPER'
```

### Inputs

| Input | Type | Required | Default | Description |
| --- | --- | :---: | --- | --- |
| `containerName` | string | No | `$(containerName)` | Container name |
| `userName` | string | No | `$(containerUsername)` | User name |
| `password` | string | No | `$(containerPassword)` | Password |
| `permissionSetId` | string | No | `SUPER` | Permission set |

> **Note:** Creates a user inside the container and assigns a permission set. `userName` / `password` default to the container admin credentials set by Create BC Container; `permissionSetId` defaults to `SUPER`. This task sets no output variables.

---

## Create NuGet Package

**Reference name:** `CreateNuGetPackage@0`

Creates a NuGet package (.nupkg) from a compiled Business Central .app.

> **Note:** Wraps New-BcNuGetPackage from the businessdev.ALbuild module. Packages each matched .app - a single file, every .app under a folder, or a wildcard - into a .nupkg (*.runtime.app is skipped; use the runtime-package flow for those). Sets the output variable (default 'bcNuGetPackage') to the first package and 'bcNuGetPackages' to all of them; feed those to the 'Publish NuGet Package' task.

### Example

```yaml
- task: CreateNuGetPackage@0
  displayName: 'Create NuGet package'
  inputs:
    path: '$(bcAppFile)'                 # a .app file or a folder of .app files
    idScheme: '{publisher}.{name}.{id}'
    # packageId: 'MyCompany.MyApp'       # overrides idScheme with an explicit id
    # version: '$(appVersion)'           # empty = version from app.json
    outputFolder: '$(Build.ArtifactStagingDirectory)'
    outputVariable: 'bcNuGetPackage'
  # -> sets $(bcNuGetPackage) (first package) and $(bcNuGetPackages) (all, ';'-joined)
```

### Inputs

| Input | Type | Required | Default | Description |
| --- | --- | :---: | --- | --- |
| `path` | string | No | `$(bcAppFile)` | The compiled .app to package, a folder to package every .app in, or a wildcard. Defaults to the primary app built by 'Compile AL App'. |
| `packageId` | string | No | — | Package id (blank = derived from id scheme) |
| `idScheme` | string | No | `&#123;publisher}.&#123;name}.&#123;id}` | Template for the package id when 'Package id' is blank. Placeholders: &#123;publisher}, &#123;name}, &#123;id}. |
| `version` | string | No | — | Package version (blank = app version) |
| `authors` | string | No | — | Authors (blank = app publisher) |
| `description` | string | No | — | Description (blank = app name) |
| `outputFolder` | filePath | No | — | Where the .nupkg files are written. Blank = a 'nuget' folder under the artifact staging directory (or the app's own folder). |
| `outputVariable` | string | No | `bcNuGetPackage` | Output variable name |

### Option values

**`idScheme`**

| Value | Meaning |
| --- | --- |
| `{publisher}` | Placeholder replaced by the app publisher from app.json. |
| `{name}` | Placeholder replaced by the app name from app.json. |
| `{id}` | Placeholder replaced by the app id (GUID) from app.json. |

### Output variables

| Variable | Description |
| --- | --- |
| `bcNuGetPackage` | Path to the first created .nupkg. The variable name is configurable via the `outputVariable` input (default `bcNuGetPackage`). |
| `bcNuGetPackages` | All created .nupkg paths, semicolon-joined (always set under this fixed name). |

> **Note:** Wraps one or more .app files into NuGet packages. The package id comes from `packageId` when set, otherwise from `idScheme` (a template of `{publisher}`, `{name}`, `{id}`). `version` defaults to the app.json version. The primary output variable name is chosen with `outputVariable`; the plural `bcNuGetPackages` is always emitted as well.

---

## Get BC Artifact

**Reference name:** `GetBcArtifact@0`

Resolves a Business Central artifact URL and stores it in an output variable.

> **Note:** Wraps Find-BcArtifactUrl from the businessdev.ALbuild module.

**Underlying cmdlet:** [`Find-BcArtifactUrl`](../powershell-module/containers#find-bcartifacturl)

### Example

```yaml
- task: GetBcArtifact@0
  displayName: 'Get BC artifact'
  inputs:
    type: 'Sandbox'          # empty = from albuild.json (default Sandbox)
    country: 'w1'            # empty = from albuild.json (default w1)
    select: 'Latest'
    # version: '26'          # optional version / prefix filter
  # -> sets $(bcArtifactUrl) and $(bcArtifactVersion) for the downstream tasks
```

### Inputs

| Input | Type | Required | Default | Description |
| --- | --- | :---: | --- | --- |
| `type` | pickList | No | — | Type **Options:** ` = (from albuild.json / Sandbox)`, `Sandbox = Sandbox`, `OnPrem = OnPrem`. |
| `country` | string | No | — | Leave empty to use the country from albuild.json (default w1). |
| `version` | string | No | — | Version |
| `select` | pickList | No | — | Select **Options:** ` = (from albuild.json / Latest)`, `Latest = Latest`, `First = First`, `Closest = Closest`, `NextMinor = NextMinor`, `NextMajor = NextMajor`. |
| `projectFolder` | filePath | No | — | Project folder (reads albuild.json) |
| `dependencyAware` | boolean | No | `false` | For a plain 'Latest' (no pinned Version): pick the newest BC whose build all projects' dependencies still resolve against, stepping back through minor versions when an ISV has not shipped packages for the latest BC yet. Emits a warning when it downgrades. |
| `maxDowngradeSteps` | string | No | `5` | How many minor versions back the dependency-aware selection may step (crossing a major boundary to the previous major's latest minor). Shown when dependencyAware is on. _(Shown when: `dependencyAware = true`.)_ |
| `outputVariable` | string | No | `bcArtifactUrl` | Output variable name |

### Option values

**`type`**

| Value | Meaning |
| --- | --- |
| `(empty)` | Take the artifact type from albuild.json (falls back to Sandbox). |
| `Sandbox` | The Sandbox artifact (in-memory, cronus demo data) - the normal build/test target. |
| `OnPrem` | The OnPrem artifact - use when building/testing against the on-premises platform. |

**`select`**

| Value | Meaning |
| --- | --- |
| `(empty)` | Take the selection strategy from albuild.json (falls back to Latest). |
| `Latest` | Newest artifact matching type/country/version. |
| `First` | Earliest artifact matching the filter. |
| `Closest` | Artifact closest to the given `version`. |
| `NextMinor` | The upcoming next-minor Insider build (requires accepting the BC Insider EULA). |
| `NextMajor` | The upcoming next-major Insider build (requires accepting the BC Insider EULA). |

### Output variables

| Variable | Description |
| --- | --- |
| `bcArtifactUrl` | The resolved artifact URL. The variable name is configurable via the `outputVariable` input (default `bcArtifactUrl`). |
| `bcArtifactVersion` | The BC version parsed from the artifact URL (e.g. 26.1.12345.12345). Consumed by Resolve Dependencies. Not set if the URL cannot be parsed (logged as a warning). |

> **Note:** Set `dependencyAware: true` to down-select the artifact so the app's dependency closure stays resolvable; `maxDowngradeSteps` (visible only then) caps how many minor versions it may step down.

---

## Get Universal Package

**Reference name:** `GetUniversalPackage@0`

Downloads a named package from an Azure DevOps Universal feed into a folder.

> **Note:** Wraps Get-BcUniversalPackage from the businessdev.ALbuild module. Requires the Azure CLI with the azure-devops extension on the agent.

**Underlying cmdlet:** [`Get-BcUniversalPackage`](../powershell-module/feeds#get-bcuniversalpackage)

### Example

```yaml
- task: GetUniversalPackage@0
  displayName: 'Download universal package'
  inputs:
    feed: 'ALbuild'
    name: 'my-universal-package'
    version: '*'                 # '*' = latest version
    outputFolder: '$(Pipeline.Workspace)/pkg'
    # project: 'MyProject'       # for a project-scoped feed
    # organization / accessToken default to the current collection / $(System.AccessToken)
```

### Inputs

| Input | Type | Required | Default | Description |
| --- | --- | :---: | --- | --- |
| `organization` | string | No | `$(System.TeamFoundationCollectionUri)` | Organization (URL or name) |
| `feed` | string | No | — | Feed |
| `name` | string | No | — | Package name |
| `version` | string | No | `*` | Version (or *) |
| `outputFolder` | filePath | No | — | Output folder |
| `project` | string | No | — | Project (for project-scoped feeds) |
| `accessToken` | string | No | `$(System.AccessToken)` | Access token (PAT) |

> **Note:** Downloads an Azure Artifacts Universal Package from the named `feed` into `outputFolder`. `version` accepts an exact version or `*` (latest). Set `project` for a project-scoped feed; `organization` and `accessToken` default to the running collection and the build service token. This task sets no output variables.

---

## Import Configuration Package

**Reference name:** `ImportConfigPackage@0`

Imports a RapidStart (.rapidstart) configuration package into a Business Central container.

> **Note:** Wraps Import-BcConfigurationPackage from the businessdev.ALbuild module.

**Underlying cmdlet:** [`Import-BcConfigurationPackage`](../powershell-module/containers#import-bcconfigurationpackage)

### Example

```yaml
- task: ImportConfigPackage@0
  displayName: 'Import configuration package'
  inputs:
    containerName: '$(containerName)'
    path: 'config/RapidStart.rapidstart'   # a .rapidstart configuration package
```

### Inputs

| Input | Type | Required | Default | Description |
| --- | --- | :---: | --- | --- |
| `containerName` | string | No | `$(containerName)` | Container name |
| `path` | filePath | No | — | Path (.rapidstart file or folder) |

> **Note:** Imports and applies a RapidStart configuration package into the container (e.g. to seed setup/master data before tests). This task sets no output variables.

---

## Install 365 App

**Reference name:** `InstallBc365App@0`

Installs one or more 365 business development apps into a Business Central container.

> **Note:** Wraps Install-Bc365App from the businessdev.ALbuild module. Provide one app id per line.

**Underlying cmdlet:** [`Install-Bc365App`](../powershell-module/apps#install-bc365app)

### Example

```yaml
- task: InstallBc365App@0
  displayName: 'Install 365 business apps'
  inputs:
    containerName: '$(containerName)'
    appId: |                       # one app id per line
      63ca2fa4-4f03-4f2b-a480-172fef340d3f
      abcabc00-0000-0000-0000-000000000000
    # installerUrl: 'https://.../installer'   # optional custom installer source
```

### Inputs

| Input | Type | Required | Default | Description |
| --- | --- | :---: | --- | --- |
| `containerName` | string | No | `$(containerName)` | Container name |
| `appId` | multiLine | No | — | App id(s) (one per line) |
| `installerUrl` | string | No | — | Installer URL (optional) |

> **Note:** Installs one or more 365 business development apps into the container by app id. The `appId` input is multi-line - provide one app id per line. `installerUrl` overrides the default installer source. This task sets no output variables.

---

## Install Dependencies

**Reference name:** `InstallDependencies@0`

Installs an AL project's resolved dependency apps into the container, in dependency order.

> **Note:** Wraps Install-BcContainerDependency from the businessdev.ALbuild module. Run after Resolve Dependencies and before publishing the built apps, so the app under test can be installed against its dependencies.

### Example

```yaml
- task: InstallDependencies@0
  displayName: 'Install app dependencies into container'
  inputs:
    containerName: '$(containerName)'
    packageFolder: ''          # empty = the symbols cache resolved by Resolve Dependencies
    skipVerification: true
```

### Inputs

| Input | Type | Required | Default | Description |
| --- | --- | :---: | --- | --- |
| `containerName` | string | No | `$(containerName)` | Container name |
| `projectFolder` | filePath | No | — | Project folder (empty = all AL projects in the repo) |
| `excludeProjects` | string | No | — | Projects to exclude (folder names, comma-separated) |
| `packageFolder` | filePath | No | — | Dependency package folder (default: each project's .alpackages) |
| `skipVerification` | boolean | No | `true` | Skip signature verification |

> **Note:** Publishes the resolved dependency .app files into the container so the app under test can be installed. `packageFolder` points at the folder holding the dependency packages (defaults to the resolved symbols cache); `skipVerification` (default true) skips app signature verification. This task sets no output variables.

---

## Install Test Toolkit

**Reference name:** `InstallTestToolkit@0`

Publishes and installs the Business Central test toolkit apps into a container.

> **Note:** Wraps Install-BcContainerTestToolkit from the businessdev.ALbuild module. Exports the installed toolkit .app symbols to a host folder and publishes it as the 'bcTestToolkitSymbols' pipeline variable, so a following AL Tool Compile AL App can resolve test-toolkit symbols (required for test apps on country 'w1').

**Underlying cmdlet:** [`Install-BcContainerTestToolkit`](../powershell-module/containers#install-bccontainertesttoolkit)

### Example

```yaml
- task: InstallTestToolkit@0
  displayName: 'Install test toolkit'
  inputs:
    containerName: '$(containerName)'
    includeTestLibrariesOnly: true   # false = also install the full test framework apps
  # -> sets $(bcTestToolkitSymbols) with the exported test-symbol folder
```

### Inputs

| Input | Type | Required | Default | Description |
| --- | --- | :---: | --- | --- |
| `containerName` | string | No | `$(containerName)` | Container name |
| `includeTestLibrariesOnly` | boolean | No | `true` | Default (checked): install just the test framework + libraries — what you need to compile and run your own test app, and fast. Uncheck to also publish Microsoft's full test **content** apps (all Tests-* apps, recompiled in the container) — rarely needed, and much slower. |
| `symbolExportFolder` | string | No | — | Host folder to export the installed toolkit .app symbols into (for an AL Tool host compile). Blank = a folder under the agent temp directory; the path is published as the 'bcTestToolkitSymbols' variable. |

### Output variables

| Variable | Description |
| --- | --- |
| `bcTestToolkitSymbols` | Folder the exported test-toolkit symbols were written to (consumed by Compile App via `testToolkitSymbols`). |

> **Note:** Installs Microsoft's test toolkit into the container. `includeTestLibrariesOnly` (default true) installs only the test libraries needed to compile/run tests; set false to install the complete test framework. `symbolExportFolder` overrides where the test symbols are exported.

---

## Publish App

**Reference name:** `PublishApp@0`

Publishes, synchronises and installs an .app into a Business Central container.

> **Note:** Wraps Publish-BcContainerApp from the businessdev.ALbuild module.

**Underlying cmdlet:** [`Publish-BcContainerApp`](../powershell-module/apps#publish-bccontainerapp)

### Example

```yaml
- task: PublishApp@0
  displayName: 'Publish AL app to container'
  inputs:
    containerName: '$(containerName)'
    appFile: '$(bcAppFile)'          # empty = publish every .app under appFolder
    syncMode: 'Add'
    install: true
    skipVerification: true
```

### Inputs

| Input | Type | Required | Default | Description |
| --- | --- | :---: | --- | --- |
| `containerName` | string | No | `$(containerName)` | Container name |
| `appFile` | string | No | — | App (.app) file (single-app; leave empty to publish all built apps) |
| `appFolder` | filePath | No | `$(Build.ArtifactStagingDirectory)` | Folder of built .app files (multi-project) |
| `projectFolder` | filePath | No | — | Project folder (empty = all AL projects in the repo) |
| `excludeProjects` | string | No | — | Projects to exclude (folder names, comma-separated) |
| `syncMode` | pickList | No | `Add` | Schema sync mode **Options:** `Add = Add`, `Clean = Clean`, `Development = Development`, `ForceSync = ForceSync`. |
| `skipVerification` | boolean | No | `true` | Skip signature verification |
| `install` | boolean | No | `true` | Install after sync |

### Option values

**`syncMode`**

| Value | Meaning |
| --- | --- |
| `Add` | Additive schema sync - only non-breaking schema changes are applied; existing data is kept. Default. |
| `Clean` | Publish with a clean schema: the app's tables are recreated, discarding their data. Use for a fresh install. |
| `Development` | Development sync (rapid application development): schema changes are forced and table data may be lost - for dev boxes only. |
| `ForceSync` | Force the schema sync through even for breaking changes (fields/tables may be dropped). Data loss is possible. |

> **Note:** Publishes into the container named by `containerName` (defaults to the `$(containerName)` set by Create BC Container). `skipVerification` (default true) skips app signature verification; `install` (default true) installs the app after publishing. This task sets no output variables.

---

## Publish Testiny Results

**Reference name:** `PublishTestinyResults@0`

Publishes a JUnit test result file to Testiny.

> **Note:** Wraps Publish-BcTestinyResult from the businessdev.ALbuild module. For standard pipeline reporting use the built-in PublishTestResults task.

**Underlying cmdlet:** [`Publish-BcTestinyResult`](../powershell-module/apps#publish-bctestinyresult)

### Example

```yaml
- task: PublishTestinyResults@0
  displayName: 'Publish results to Testiny'
  inputs:
    resultsFile: '$(bcTestResults)'    # defaults to TestResults.xml
    apiKey: '$(TestinyApiKey)'
    projectId: '$(TestinyProjectId)'
    # runId: '123'                     # optional: append to an existing run
```

### Inputs

| Input | Type | Required | Default | Description |
| --- | --- | :---: | --- | --- |
| `resultsFile` | filePath | No | `TestResults.xml` | Results file (JUnit) |
| `apiKey` | string | No | — | Testiny API key |
| `projectId` | string | No | — | Testiny project id |
| `runId` | string | No | — | Testiny run id (optional) |

> **Note:** Uploads the test results (JUnit XML, e.g. the `$(bcTestResults)` from Run Tests) to the Testiny test-management service for the given `projectId`. `apiKey`, `resultsFile` and `projectId` are required. `runId` targets an existing run; when omitted a new run is created. This task sets no output variables.

---

## Remove BC Container

**Reference name:** `RemoveBcContainer@0`

Removes a Business Central build container.

> **Note:** Wraps Remove-BcContainer from the businessdev.ALbuild module.

**Underlying cmdlet:** [`Remove-BcContainer`](../powershell-module/containers#remove-bccontainer)

### Example

```yaml
- task: RemoveBcContainer@0
  displayName: 'Remove BC container'
  condition: always()          # tear down even when earlier steps failed
  inputs:
    containerName: '$(containerName)'
```

### Inputs

| Input | Type | Required | Default | Description |
| --- | --- | :---: | --- | --- |
| `containerName` | string | No | — | Container name |

> **Note:** Removes the BC container. Put this in a cleanup step with `condition: always()` so the container is torn down even when the build fails. This task sets no output variables.

---

## Resolve Dependencies

**Reference name:** `ResolveDependencies@0`

Resolves an AL project's dependencies from NuGet feeds and writes them to .alpackages.

> **Note:** Wraps Register-BcFeed + Resolve-BcDependencies from the businessdev.ALbuild module. NuGet feeds take precedence over the albuild.json Universal/local/URL packages: a dependency a registered feed offers is resolved from the feed, and those external packages are used only as a fallback for apps no feed provides.

**Underlying cmdlet:** [`Resolve-BcDependencies`](../powershell-module/feeds#resolve-bcdependencies)

### Example

```yaml
- task: ResolveDependencies@0
  displayName: 'Resolve AL dependencies'
  inputs:
    feedUrl: 'https://pkgs.dev.azure.com/365businessdev/_packaging/ALbuild/nuget/v3/index.json'
    feedToken: '$(System.AccessToken)'
    feedKind: 'symbols'
    select: 'Latest'
    targetVersion: '$(bcArtifactVersion)'
    includeMicrosoftDefaults: true
```

### Inputs

| Input | Type | Required | Default | Description |
| --- | --- | :---: | --- | --- |
| `projectFolder` | filePath | No | — | Project folder (empty = all AL projects in the repo) |
| `excludeProjects` | string | No | — | Projects to exclude (folder names, comma-separated) |
| `includeMicrosoftDefaults` | boolean | No | `true` | Include Microsoft default feeds |
| `feedUrl` | string | No | — | NuGet feed URL (v3 index.json) |
| `feedToken` | string | No | — | Feed token / PAT |
| `feedKind` | pickList | No | `symbols` | Feed kind **Options:** `symbols = symbols`, `apps = apps`, `runtime = runtime`. |
| `select` | pickList | No | `Latest` | Selection **Options:** `Latest = Latest`, `LowestCompatible = LowestCompatible`. |
| `containerName` | string | No | `$(containerName)` | Container (pin installed apps) |
| `targetVersion` | string | No | `$(bcArtifactVersion)` | The BC version dependency resolution caps against. Defaults to $(bcArtifactVersion) from the Get BC Artifact task so a container-less build still honours the pinned BC version. Falls back to the container's platform version, then albuild.json 'bcVersion'. |
| `outputFolder` | filePath | No | — | Output folder (.alpackages) |

### Option values

**`feedKind`**

| Value | Meaning |
| --- | --- |
| `symbols` | Download the symbols (.app placeholder) packages - enough to compile against. Default. |
| `apps` | Download the full runtime .app packages - needed to publish/install the dependencies. |
| `runtime` | Download the runtime-package variant of the dependencies. |

**`select`**

| Value | Meaning |
| --- | --- |
| `Latest` | Take the newest compatible version of each dependency. Default. |
| `LowestCompatible` | Take the lowest version that still satisfies the app.json dependency range (reproducible minimum-baseline builds). |

> **Note:** Restores dependencies from a NuGet feed into the symbols cache. `targetVersion` (default `$(bcArtifactVersion)` from Get BC Artifact) pins the BC platform the dependencies must match; `includeMicrosoftDefaults` (default true) also pulls the Microsoft first-party symbol packages. This task sets no output variables.

---

## Run AL Tests

**Reference name:** `RunBcTests@0`

Runs AL tests in a Business Central container using ALbuild's built-in test runner and publishes a JUnit result file.

> **Note:** Wraps Invoke-BcContainerTest from the businessdev.ALbuild module. Discovers AL test apps under the project folder (honouring each app's pipeline.config alTestRunnerId) or runs an explicit extension id.

**Underlying cmdlet:** [`Invoke-BcContainerTest`](../powershell-module/apps#invoke-bccontainertest)

### Example

```yaml
- task: RunBcTests@0
  displayName: 'Run AL tests'
  inputs:
    containerName: '$(containerName)'
    testSuite: 'DEFAULT'
    failOnTestFailure: true
    codeCoverage: 'PerRun'
    coverageFormats: 'Cobertura,Markdown'
    publishCoverage: true
    minLineCoverage: '80'          # fail the build below 80% line coverage
    failOnCoverageBelow: true
  # -> sets $(bcTestResults), $(bcCoverageLineRate), $(bcCoverageCobertura), $(bcTestQualityScore)
```

### Inputs

| Input | Type | Required | Default | Description |
| --- | --- | :---: | --- | --- |
| `containerName` | string | No | `$(containerName)` | Container name |
| `username` | string | No | `$(containerUsername)` | Container user |
| `password` | string | No | `$(containerPassword)` | Container password |
| `auth` | string | No | `NavUserPassword` | Client services auth |
| `projectFolder` | filePath | No | — | Project folder |
| `extensionId` | string | No | — | Extension id (optional) |
| `testSuite` | string | No | `DEFAULT` | Test suite |
| `testRunnerCodeunitId` | string | No | — | Test runner codeunit id (optional) |
| `disableIsolation` | boolean | No | `False` | Disable test isolation |
| `installTestToolkit` | boolean | No | `True` | Auto-install the BC test toolkit into the container when it is not already present, so a separate Install Test Toolkit step is not required. |
| `includeTestLibrariesOnly` | boolean | No | `False` | Test libraries only (when auto-installing) |
| `resultPath` | filePath | No | `TestResults.xml` | Result file (JUnit) |
| `failOnTestFailure` | boolean | No | `False` | Fail on test failure |
| `codeCoverage` | pickList | No | `Disabled` | Capture Business Central code coverage at this granularity while the tests run. When enabled, a Cobertura file and a Markdown summary are produced and (optionally) published. **Options:** `Disabled = Disabled`, `PerRun = Per run`, `PerCodeunit = Per codeunit`, `PerTest = Per test`. |
| `codeCoverageMap` | pickList | No | `Disabled` | Also capture a test -> covered-line map. **Options:** `Disabled = Disabled`, `PerCodeunit = Per codeunit`, `PerTest = Per test`. _(Shown when: `codeCoverage != Disabled`.)_ |
| `coverageFormats` | string | No | `Cobertura,Markdown` | Comma-separated: ALbuildJson, Cobertura, Markdown, Html. 'Html' writes a self-contained report that the build's Code Coverage tab renders; it is added automatically when 'Publish coverage' is on, so you only need to list it here if you want the report without publishing. _(Shown when: `codeCoverage != Disabled`.)_ |
| `coverageWorkspaceRoot` | filePath | No | — | AL source root, so coverage maps to your app objects only and to source files. Defaults to the project folder. _(Shown when: `codeCoverage != Disabled`.)_ |
| `coverageOutputFolder` | filePath | No | `CodeCoverage` | Coverage output folder _(Shown when: `codeCoverage != Disabled`.)_ |
| `publishCoverage` | boolean | No | `True` | Publish the Cobertura file to the build and append the Markdown summary to the build summary. This also generates the HTML report the Code Coverage tab renders - without it the tab reports "report HTML was not found", because the publish command uploads a report directory but never creates one. The report lists objects lowest-coverage first and expands to uncovered line ranges and annotated source. Azure DevOps runs no JavaScript in that tab, so filtering and column sorting appear only when you download the report artifact and open it in a browser; everything else works in the tab itself. _(Shown when: `codeCoverage != Disabled`.)_ |
| `minLineCoverage` | string | No | — | Fail (or warn) the task when honest line coverage is below this percent. Empty = no gate. Uses the source-based denominator. _(Shown when: `codeCoverage != Disabled`.)_ |
| `minObjectLineCoverage` | string | No | — | Optional per-object coverage floor; any object below it fails the gate. _(Shown when: `codeCoverage != Disabled`.)_ |
| `failOnCoverageBelow` | boolean | No | `True` | Fail build when below coverage gate _(Shown when: `codeCoverage != Disabled`.)_ |
| `checkTestQuality` | boolean | No | `False` | Test quality is ALWAYS part of the coverage report and the build summary when coverage is enabled - coverage says which lines ran, not that a wrong result would be caught, because a [Test] method that asserts nothing still covers every line it touches. This option adds the `bcTestQualityScore` build variable and raises a build WARNING when tests without assertions exist; it is off by default so switching on coverage does not start flagging existing pipelines. |

### Option values

**`codeCoverage`**

| Value | Meaning |
| --- | --- |
| `Disabled` | No code coverage is collected. Default. |
| `PerRun` | Collect one coverage result for the whole test run. |
| `PerCodeunit` | Collect coverage separately per test codeunit. |
| `PerTest` | Collect coverage separately per test method (most granular, slowest). |

**`codeCoverageMap`**

| Value | Meaning |
| --- | --- |
| `Disabled` | Do not produce a coverage map. Default. |
| `PerCodeunit` | Emit a coverage map per codeunit. |
| `PerTest` | Emit a coverage map per test method. |

**`coverageFormats`**

| Value | Meaning |
| --- | --- |
| `Cobertura` | Cobertura XML - published to the build's Code Coverage tab. |
| `Markdown` | A Markdown summary - uploaded as a build summary tab. |
| `ALbuildJson` | The raw ALbuild JSON coverage document. |

### Output variables

| Variable | Description |
| --- | --- |
| `bcTestResults` | Path to the JUnit/XML test results file (`resultPath`). |
| `bcCoverageLineRate` | Overall line-coverage rate (only when code coverage is enabled). |
| `bcCoverageCobertura` | Path to the generated Cobertura XML (only when Cobertura is among `coverageFormats`). |
| `bcTestQualityScore` | Test-quality score (only when `checkTestQuality` is true). |

> **Note:** The `coverageFormats` input is a comma-separated list; valid entries are `Cobertura`, `Markdown` and `ALbuildJson`. `minLineCoverage` / `minObjectLineCoverage` set coverage thresholds; combined with `failOnCoverageBelow` (default true) they fail the build when coverage is below target. `checkTestQuality` additionally warns about tests without assertions.

---

## Sign AL App

**Reference name:** `SignBcApp@0`

Signs .app files with an Azure Key Vault certificate (AzureSignTool).

> **Note:** Wraps Invoke-BcAppSigning from the businessdev.ALbuild module. AzureSignTool must be available on the agent. NOTE: Azure DevOps does not pass *secret* pipeline variables into task inputs. If your Key Vault credentials are secret variables, map them via the task 'env:' block instead of inputs: ALBUILD_SIGN_KEYVAULTURL, ALBUILD_SIGN_TENANTID, ALBUILD_SIGN_CLIENTID, ALBUILD_SIGN_CLIENTSECRET, ALBUILD_SIGN_CERTNAME.

**Underlying cmdlet:** [`Invoke-BcAppSigning`](../powershell-module/apps#invoke-bcappsigning)

### Example

```yaml
- task: SignBcApp@0
  displayName: 'Sign AL app'
  inputs:
    path: '$(bcAppFile)'                 # a .app file or a folder of .app files
    certificateName: '$(SigningCertName)'
  env:
    # Secret pipeline variables do not reach task inputs, so map them via env (SignBcApp reads ALBUILD_SIGN_*):
    ALBUILD_SIGN_KEYVAULTURL: $(SigningAzureKeyVaultUrl)
    ALBUILD_SIGN_TENANTID:    $(SigningAzureKeyVaultTenantId)
    ALBUILD_SIGN_CLIENTID:    $(SigningAzureKeyVaultClientId)
    ALBUILD_SIGN_CLIENTSECRET: $(SigningAzureKeyVaultClientSecret)
    ALBUILD_SIGN_CERTNAME:    $(SigningCertName)
```

### Inputs

| Input | Type | Required | Default | Description |
| --- | --- | :---: | --- | --- |
| `path` | string | No | `$(bcAppFile)` | App file / folder / wildcard |
| `keyVaultUrl` | string | No | — | Key Vault URL |
| `tenantId` | string | No | — | Tenant id |
| `clientId` | string | No | — | Client id |
| `clientSecret` | string | No | — | Client secret |
| `certificateName` | string | No | — | Certificate name |
| `timestampUrl` | string | No | `http://timestamp.digicert.com` | Timestamp URL |

> **Note:** Azure DevOps does not pass secret variables to task inputs, so the Key Vault credentials are read from the `ALBUILD_SIGN_KEYVAULTURL` / `_TENANTID` / `_CLIENTID` / `_CLIENTSECRET` / `_CERTNAME` environment variables when the matching inputs are blank. Signs via Azure Key Vault (AzureSignTool); the certificate must be a code-signing cert. `timestampUrl` defaults to `http://timestamp.digicert.com`.

---

## Stamp Build Version

**Reference name:** `StampBuildVersion@0`

Stamps the app version into app.json and atomically claims a build/&lt;version> branch (parallel-safe).

> **Note:** Wraps Invoke-BcBuildVersionStamp from the businessdev.ALbuild module. Uses a branch-push compare-and-swap so concurrent builds never share a version.

**Underlying cmdlet:** [`Invoke-BcBuildVersionStamp`](../powershell-module/core#invoke-bcbuildversionstamp)

### Example

```yaml
# CI: version app.json from its current Major.Minor, Build+1, Revision 0, and claim a build/<version>
# branch so the CD build can seed the exact validated version later.
- task: StampBuildVersion@0
  displayName: 'Stamp build version'
  inputs:
    schema: 'major.minor.increment.0'
    # version: '1.2.3.0'          # an explicit version overrides schema entirely
    # onlyUpdateOnChangedSource: true
  env:
    AZURE_DEVOPS_EXT_PAT: $(System.AccessToken)   # required to push the build/<version> branch

# CD: inherit Major.Minor.Build from the latest CI build branch, set Revision = build id.
- task: StampBuildVersion@0
  inputs:
    schema: 'latest.latest.latest.build-id'       # 'latest' auto-enables Seed from build branch
    noBuildBranch: true
  env:
    AZURE_DEVOPS_EXT_PAT: $(System.AccessToken)
```

### Inputs

| Input | Type | Required | Default | Description |
| --- | --- | :---: | --- | --- |
| `path` | filePath | No | — | Repository / project path |
| `schema` | string | No | `major.minor.increment.0` | One token per dotted position: a number = literal; 'increment' = current + 1; 'build-id' = the build id; 'no-of-commits' = the git commit count; 'date' = a yyyyMMdd date stamp; 'major'/'minor'/'build'/'revision'/'keep' = keep the current app.json component; 'latest' = take the component from the **latest build branch** (implies Seed from build branch). Fewer than four tokens keeps the remaining lower components unchanged. E.g. 'latest.latest.latest.build-id' → keep Major.Minor.Build from the latest CI build, revision = build id. |
| `version` | string | No | — | Explicit version (overrides schema) |
| `buildId` | string | No | `$(Build.BuildId)` | Build id (for the build-id token) |
| `onlyUpdateOnChangedSource` | boolean | No | `false` | Only version changed apps |
| `branchPrefix` | string | No | `build/` | Build branch prefix |
| `remote` | string | No | `origin` | Git remote |
| `noBuildBranch` | boolean | No | `false` | Do not create/push a build branch |
| `seedFromBuildBranch` | boolean | No | `false` | Release/CD use. Instead of claiming a new build branch, read the highest build/&lt;Major>.&lt;Minor>.* the CI already claimed on the remote (e.g. 1.1.588.0), apply the schema to it, and stamp every app to the result — e.g. schema 'latest.latest.latest.build-id' → 1.1.588.$(Build.BuildId). Lets a release pipeline that checks out the source branch (where app.json is still 1.1.0.0) reproduce the CI build number. **Also enabled automatically when the schema uses a 'latest' token**, so you usually just set the schema. Read-only on the remote (no branch is pushed). Ignored when an explicit version is given. |
| `updateBuildNumber` | boolean | No | `true` | Update the pipeline build number |

### Option values

**`schema`**

| Value | Meaning |
| --- | --- |
| `<number>` | A literal non-negative integer at that position (e.g. the `0` in `major.minor.increment.0`). |
| `increment` | The current app.json component + 1 (e.g. Build+1). |
| `build-id` | The pipeline build id from the `buildId` input (default `$(Build.BuildId)`); must be numeric. |
| `no-of-commits` | The git commit count (V1-style versioning); must be numeric. |
| `date` | A numeric date stamp, `yyyyMMdd`. |
| `major` | Keep the current Major from app.json (unchanged). |
| `minor` | Keep the current Minor from app.json (unchanged). |
| `build` | Keep the current Build from app.json (unchanged). |
| `revision` | Keep the current Revision from app.json (unchanged). |
| `keep` | Keep the current component at this position (alias of major/minor/build/revision). |
| `latest` | Keep the component, but seed the base version from the latest `build/<Major>.<Minor>.*` branch on the remote first (i.e. take it from the latest CI build). Auto-enables Seed from build branch. |

### Output variables

| Variable | Description |
| --- | --- |
| `appVersion` | The full stamped version, Major.Minor.Build.Revision. |
| `appVersionShort` | Major.Minor.Build (no revision). |
| `semanticAppVersion` | Alias of appVersionShort. |
| `appVersionMajor` | The Major component. |
| `appVersionMinor` | The Minor component. |
| `appVersionBuild` | The Build component. |
| `appVersionRevision` | The Revision component. |
| `buildBranch` | The build/&lt;version> branch that was claimed and pushed (only emitted when a branch was created, i.e. not with noBuildBranch). |

> **Note:** A schema with fewer than four positions keeps the remaining lower components unchanged (implicit `latest`). Any token other than those above fails the build. When the schema contains a `latest` token, or when `seedFromBuildBranch` is set, the task reads the highest existing `build/<Major>.<Minor>.*` branch on the remote as the base before applying the schema; the build/&lt;version> branch push is a compare-and-swap (Build is incremented on conflict). Pushing the branch needs the build service to have Contribute on the repo (map $(System.AccessToken) to AZURE_DEVOPS_EXT_PAT).

---
