Skip to content

Build Steps Overview#

ALOps v3 introduces a new generation of build tasks that are containerless by design, relying on NuGet packages (notably microsoft.dynamics.businesscentral.development.tools) instead of Docker or BC artifact downloads. This makes pipelines faster and more portable across self-hosted and Microsoft-hosted agents alike.

Related: Build steps v1 Build steps v2

ALOps Agent Maintenance#

Keep your build agents clean and lean. This task removes stale Docker resources, old BC artifact cache folders, orphaned NuGet packages, and temp files — without any dependency on BcContainerHelper.

Full Yaml Description:

    - task: ALOpsAgentMaintenance@3
      displayName: 'ALOps Agent Maintenance'
      inputs:
        dockercontainers: False               # Remove all stopped/exited Docker containers (docker container prune). $(dockercontainers) $(dockercontainers) $(dockercontainers)
        dockerimages: False                   # Remove Docker images older than the specified number of days. $(dockerimages) $(dockerimages) $(dockerimages)
        pruneimagesdayscreated: 0             # Remove Docker images older than this many days. Set to 0 to skip age-based image pruning. $(pruneimagesdayscreated) $(pruneimagesdayscreated) $(pruneimagesdayscreated)
        dockerimagesbyos: False               # Remove Docker images whose OS version does not match the host OS. Uses direct Docker inspect (no BcContainerHelper dependency). $(dockerimagesbyos) $(dockerimagesbyos) $(dockerimagesbyos)
        dockervolumes: False                  # Remove all dangling (unused) Docker volumes. $(dockervolumes) $(dockervolumes) $(dockervolumes)
        dockerbuildcache: False               # Remove all Docker build cache (docker builder prune). $(dockerbuildcache) $(dockerbuildcache) $(dockerbuildcache)
        bcartifacts: False                    # Remove unused BC Artifact cache folders, orphaned VSIX extractions, temp folders, and empty directories. $(bcartifacts) $(bcartifacts) $(bcartifacts)
        bcartifactscachefolder:               # Path to the BC Artifacts cache folder. Leave empty for auto-detection (checks bcaboragentartifactspath env var, then falls back to C:\bcartifacts.cache). $(bcartifactscachefolder) $(bcartifactscachefolder) $(bcartifactscachefolder)
        packagecache: False                   # Remove old ALTool/compiler packages from the agent tools directory and old NuGet global cache packages. $(packagecache) $(packagecache) $(packagecache)
        oldtasks: False                       # Remove old ALOps task version folders from the agent. Auto-detects the current version and removes all older versions. $(oldtasks) $(oldtasks) $(oldtasks)
        agenttemp: False                      # Remove old files and folders from the agent temp directory (AGENT_TEMPDIRECTORY). $(agenttemp) $(agenttemp) $(agenttemp)
        windowstemp: False                    # Remove old files and folders from the Windows temp directory (TEMP). $(windowstemp) $(windowstemp) $(windowstemp)
        daysunused: 30                        # Threshold in days for cleanup operations. Items not used within this period are removed. Applies to BCArtifacts, AgentTemp, WindowsTemp, and PackageCache operations. $(daysunused) $(daysunused) $(daysunused)
        dryrun: False                         # When enabled, reports what would be cleaned without actually deleting anything. Use this for change management review before running actual cleanup. $(dryrun) $(dryrun) $(dryrun)
        erroraction: Warn                     # How cleanup failures affect the task result. 'Error' fails the task on any cleanup error. 'Warn' marks the task as SucceededWithIssues. 'Ignore' silently continues. $(erroraction) $(erroraction) $(erroraction)
        pwsh: False                           # Run task in PowerShell Core (pwsh) instead of Windows PowerShell. $(pwsh) $(pwsh) $(pwsh)

Parameters#

dryrun#

Set dryrun: true to preview everything that would be removed, without actually deleting anything. Useful for change-management reviews or first-time setup.

daysunused#

Threshold (in days) for age-based cleanup operations. Items that have not been accessed within this period are eligible for removal. Applies to bcartifacts, agenttemp, windowstemp, and packagecache.

erroraction#

Controls how cleanup failures affect the overall task result: - Error — fails the task on any cleanup error - Warn — marks the task as SucceededWithIssues - Ignore — silently continues past failures

dockerimagesbyos#

When true, removes Docker images whose OS version does not match the current host OS. This check uses direct Docker inspect calls and has no dependency on BcContainerHelper.


ALOps App Compiler#

Compile Business Central extension(s) from AL source code using the altool.exe compiler distributed as a NuGet package — no Docker, no BC artifacts download required.

Full Yaml Description:

    - task: ALOpsAppCompiler@3
      displayName: 'ALOps App Compiler'
      inputs:
        altool_package_version: 17.0.30.49729-beta# Version of the `microsoft.dynamics.businesscentral.development.tools` NuGet package to download from nuget.org. The package contains `altool.exe` (at `tools/net8.0/any/altool.exe`) and the bundled `alc.exe` compiler. Pre-release suffixes (e.g. `-beta`) are supported. Pin to a specific version for reproducible builds. $(altool_package_version) $(altool_package_version) $(altool_package_version)
        altool_cache_hours: 0                 # Number of hours the downloaded NuGet package is cached on the agent (under `$AGENT_TOOLSDIRECTORY`). Set to `0` to always download fresh. Non-numeric values silently default to `0`. Increase on self-hosted agents to avoid repeated downloads across pipeline runs. $(altool_cache_hours) $(altool_cache_hours) $(altool_cache_hours)
        compilation_mode: Serial              # **Serial:** compiles one app at a time via `altool compile` with full `alc.exe` flag control (analyzers by DLL path, `/continuebuildonerror`, `/errorlog`, `/enableexternalrulesets`). **Parallel:** uses a 3-step workflow — `altool workspace create` ? `altool workspace map` ? `altool workspace compile` — to compile all apps concurrently respecting dependency order. Some parameters only apply in one mode; see individual parameter help for details. $(compilation_mode) $(compilation_mode) $(compilation_mode)
        alsourcepath: $(System.DefaultWorkingDirectory)# Root folder searched recursively for `app.json` files. Each discovered `app.json` represents one AL project to compile. You can also pass a direct path to a single `app.json` file. If no `app.json` is found, the task emits a warning and completes without compilation. $(alsourcepath) $(alsourcepath) $(alsourcepath)
        alcachepath:                          # Folder containing symbol `.app` files used as the package cache for compilation. When empty, defaults to `alsourcepath`. In serial mode, each compiled `.app` is copied here so later apps in the build order can resolve it as a dependency. Auto-resolved symbols (MS and AppSource) are also downloaded into this folder. $(alcachepath) $(alcachepath) $(alcachepath)
        appversiontemplate: 1.0.*.0           # Four-part version template (`Major.Minor.Build.Revision`) applied to `app.json` before compilation. Tokens: `*` = `$(Build.BuildId)`, `?` = keep original part, `A` = use corresponding part from the `application` field. Date formats in brackets are supported, e.g. `[YYYYMMDD]`, `[WW]` (zero-padded week), `[ww]` (plain week). Must have exactly 4 dot-separated parts. Leave **empty** to skip version stamping entirely. $(appversiontemplate) $(appversiontemplate) $(appversiontemplate)
        updatebuildnumber: true               # Update the Azure DevOps build number with the compiled app version. In **serial** mode with multiple apps, the build number is updated per app (last app wins). In **parallel** mode, only the first app's version is used. Only effective when `appversiontemplate` is non-empty. $(updatebuildnumber) $(updatebuildnumber) $(updatebuildnumber)
        appfilenametemplate: %APP_PUBLISHER%_%APP_NAME%_%APP_VERSION%_%BC_VERSION%_%BC_COUNTRY%.app# Template for the output `.app` filename. Tokens: `%APP_PUBLISHER%`, `%APP_NAME%`, `%APP_VERSION%`, `%BC_VERSION%` (from `bc_version`), `%BC_COUNTRY%` (from `bc_localization`). Invalid filename characters are replaced with `_`, consecutive underscores are collapsed. If empty, defaults to `%APP_PUBLISHER%_%APP_NAME%_%APP_VERSION%.app`. $(appfilenametemplate) $(appfilenametemplate) $(appfilenametemplate)
        alcodeanalyzer:                       # Comma-separated list of analyzers for **serial** mode. Named values: `CodeCop`, `UICop`, `AppSourceCop`, `PTECop` (resolved to DLLs in the altool package). You can also specify absolute paths to custom analyzer DLLs. Use `NONE` to skip an entry. A build tag is added per analyzer. If `analyzers` (parallel mode) is empty, this value is used as the fallback for parallel compilation. $(alcodeanalyzer) $(alcodeanalyzer) $(alcodeanalyzer)
        analyzers:                            # Comma-separated analyzers for **parallel** mode: `CodeCop`, `UICop`, `AppSourceCop`, `PTECop`. Use `None` to disable. Values are normalized to proper casing and passed as `--analyzers` to `altool workspace compile`. If empty, falls back to the value of `alcodeanalyzer`. $(analyzers) $(analyzers) $(analyzers)
        ruleset:                              # Path or URL to a ruleset `.json` file that overrides diagnostic severities. Resolution order: if **empty**, checks `.vscode/settings.json` for `al.ruleSetPath`; if `NONE`, disables all rulesets; paths starting with `.` are resolved relative to `alsourcepath`; HTTP(S) URLs are downloaded automatically. In serial mode, resolved per-app. In parallel mode, applied globally via `--ruleset`. $(ruleset) $(ruleset) $(ruleset)
        suppresswarnings: KEEP                # Override `suppressWarnings` in `app.json`. `KEEP` (default, case-sensitive) preserves the existing value. `NONE` or `DISABLED` removes `suppressWarnings` entirely. Any other value is treated as a comma-separated list of diagnostic codes to suppress. $(suppresswarnings) $(suppresswarnings) $(suppresswarnings)
        ignorepragmas:                        # When non-empty, enables `/reportsuppresseddiagnostics` on `alc.exe` (serial mode) and filters out all pragma-suppressed diagnostics (lines marked `(suppressed)`) from the build log. Acts as a **boolean flag** — any non-empty value activates filtering for all suppressed diagnostics regardless of the specific codes listed. $(ignorepragmas) $(ignorepragmas) $(ignorepragmas)
        showmycode: Keep                      # Override `showMyCode` in `app.json`. `Keep` = no change, `Enable` = `true`, `Disable` = `false`. **Note:** for `runtime >= 8.0`, `showMyCode` is automatically removed (use `resourceExposurePolicy` instead). If any `resourceExposurePolicy` override is set to `Enable` or `Disable`, `showMyCode` is also removed regardless of this setting. $(showmycode) $(showmycode) $(showmycode)
        resourceexposurepolicy_allowdebugging: Keep# Override `resourceExposurePolicy.allowDebugging` in `app.json`. `Keep` = no change, `Enable` = `true`, `Disable` = `false`. **Requires `runtime >= 8.0`** — ignored for older runtimes. Setting any REP field to a value other than `Keep` automatically removes `showMyCode` from `app.json`. $(resourceexposurepolicy_allowdebugging) $(resourceexposurepolicy_allowdebugging) $(resourceexposurepolicy_allowdebugging)
        resourceexposurepolicy_allowdownloadingsource: Keep# Override `resourceExposurePolicy.allowDownloadingSource` in `app.json`. `Keep` = no change, `Enable` = `true`, `Disable` = `false`. **Requires `runtime >= 8.0`** — ignored for older runtimes. Setting any REP field to a value other than `Keep` automatically removes `showMyCode` from `app.json`. $(resourceexposurepolicy_allowdownloadingsource) $(resourceexposurepolicy_allowdownloadingsource) $(resourceexposurepolicy_allowdownloadingsource)
        resourceexposurepolicy_includesourceinsymbolfile: Keep# Override `resourceExposurePolicy.includeSourceInSymbolFile` in `app.json`. `Keep` = no change, `Enable` = `true`, `Disable` = `false`. **Requires `runtime >= 8.0`** — ignored for older runtimes. Setting any REP field to a value other than `Keep` automatically removes `showMyCode` from `app.json`. $(resourceexposurepolicy_includesourceinsymbolfile) $(resourceexposurepolicy_includesourceinsymbolfile) $(resourceexposurepolicy_includesourceinsymbolfile)
        internalsvisibleto: Keep              # `Keep` preserves the `internalsVisibleTo` array in `app.json`. `Remove` deletes it entirely. Use `Remove` when building release packages to prevent unintended access to internal symbols from dependent extensions. $(internalsvisibleto) $(internalsvisibleto) $(internalsvisibleto)
        preprocessorsymbols:                  # Override `preprocessorSymbols` in `app.json`. Comma-separated list of symbols to define. Use `NONE` to remove all preprocessor symbols entirely. In parallel mode, symbols are applied both to `app.json` and as `--define` CLI arguments to `altool workspace compile`. $(preprocessorsymbols) $(preprocessorsymbols) $(preprocessorsymbols)
        applicationinsightskey:               # Override Application Insights instrumentation in `app.json`. If the value is a valid **GUID**, it is set as `applicationInsightsKey` (and `applicationInsightsConnectionString` is removed). If it is a **non-GUID string**, it is set as `applicationInsightsConnectionString` (and `applicationInsightsKey` is removed). Use `NONE` to remove both properties. Leave empty for no change. $(applicationinsightskey) $(applicationinsightskey) $(applicationinsightskey)
        publishartifact: true                 # Upload the compiled `.app` file(s) as Azure DevOps build artifacts (artifact name: `ALOpsArtifact`). The pipeline variables `ALOPS_COMPILE_ARTIFACT` (last app path) and `ALOPS_COMPILE_ARTIFACT_ARRAY` (comma-separated list of all paths) are always set regardless of this setting. $(publishartifact) $(publishartifact) $(publishartifact)
        publishxlif: false                    # Upload generated `.g.xlf` translation files as build artifacts (artifact name: `ALOpsXLIF`). In parallel mode, this also enables `--features TranslationFile` on `altool workspace compile`, which is required for the compiler to generate `.g.xlf` files. $(publishxlif) $(publishxlif) $(publishxlif)
        failonwarnings: false                 # When `true`, any warning-level compiler diagnostic is promoted to an error, causing the task to fail. Useful for enforcing a zero-warnings policy. Subsumed by `failonany`. $(failonwarnings) $(failonwarnings) $(failonwarnings)
        failonany: false                      # When `true`, promotes warning-level diagnostics to errors and ensures all errors cause the task to fail. **Note:** despite the name, info-level diagnostics are not promoted to errors. For strict quality enforcement of warnings and errors. $(failonany) $(failonany) $(failonany)
        printappmanifest: true                # When `true`, the final `app.json` content (after all overrides) is printed to the build log before compilation begins. Useful for auditing what manifest values are actually compiled. $(printappmanifest) $(printappmanifest) $(printappmanifest)
        outputalclogs: true                   # When `true`, writes the raw `altool.exe`/`alc.exe` compiler output to the build log. When `false`, only structured commands for errors and warnings are emitted. On compiler failure (non-zero exit code), the full output is always logged regardless of this setting. $(outputalclogs) $(outputalclogs) $(outputalclogs)
        enable_external_rulesets: false       # Passes `/enableexternalrulesets` to `alc.exe`, allowing the compiler to load ruleset files from external (non-local) locations. **Serial mode only** — silently ignored in parallel mode. $(enable_external_rulesets) $(enable_external_rulesets) $(enable_external_rulesets)
        generatereportlayouts: true           # Enable or disable report layout generation during compilation. In serial mode, passes `/generatereportlayout+` or `/generatereportlayout-` (feature-gated by compiler support). In parallel mode, adds `--generatereportlayout` when enabled; the flag is omitted when disabled. $(generatereportlayouts) $(generatereportlayouts) $(generatereportlayouts)
        track_source_build_metadata: true     # Inject build/source metadata into `app.json` before compilation: `build.url` (pipeline URL), `build.by` (`ALOps`), `source.commit` (`BUILD_SOURCEVERSION`), `source.repositoryUrl` (`BUILD_REPOSITORY_URI`). **Requires `runtime >= 12.0`** — a warning is emitted and metadata injection is skipped for older runtimes. In parallel mode, also passes `--sourcerepositoryurl` and `--sourcecommit` CLI arguments. $(track_source_build_metadata) $(track_source_build_metadata) $(track_source_build_metadata)
        alc_continuebuildonerror: false       # Passes `/continuebuildonerror+` to `alc.exe` so the compiler reports all diagnostics rather than stopping at the first error. **Serial mode only** — silently ignored in parallel mode. Feature-gated: only added if the compiler supports it. $(alc_continuebuildonerror) $(alc_continuebuildonerror) $(alc_continuebuildonerror)
        alc_errorlog: false                   # Passes `/errorlog:<file>` to `alc.exe` and publishes the resulting log as the `ALCErrorLog` build artifact. Useful for detailed error analysis after a failed compilation. **Serial mode only** — silently ignored in parallel mode. Feature-gated: only added if the compiler supports it. $(alc_errorlog) $(alc_errorlog) $(alc_errorlog)
        updateruntime:                        # Override the `runtime` field in `app.json` before compilation. Leave empty to keep the declared runtime. **Note:** this is applied after `showMyCode`/`resourceExposurePolicy` logic but before `track_source_build_metadata`, so changing runtime to `>= 12` enables metadata injection, but the REP/showMyCode decision uses the *original* runtime value. $(updateruntime) $(updateruntime) $(updateruntime)
        allowed_publisher_names:              # Separated list of allowed publisher names (use `allowed_publisher_names_separator` to change delimiter). Comparison is **case-insensitive**. In serial mode, apps with unlisted publishers are skipped with an error. In parallel mode, if any app fails the check, the entire build is aborted before compilation begins. Leave empty to allow all publishers. $(allowed_publisher_names) $(allowed_publisher_names) $(allowed_publisher_names)
        allowed_publisher_names_separator: ,  # Separator character used to split the `allowed_publisher_names` value. Defaults to `,`. Use a different character (e.g. `|`) if publisher names themselves contain commas. $(allowed_publisher_names_separator) $(allowed_publisher_names_separator) $(allowed_publisher_names_separator)
        additionalprobingpaths:               # Additional folders (one per line or comma-separated) to probe for .NET assemblies referenced from AL. The task **automatically** discovers directories containing `.dll` files under `alsourcepath` and adds standard Windows assembly paths (`C:\Windows\assembly`, `C:\Windows\Microsoft.NET\assembly`) if they exist. Use this parameter for paths outside the source tree. $(additionalprobingpaths) $(additionalprobingpaths) $(additionalprobingpaths)
        maxcpucount:                          # Maximum number of concurrent project compilations in **parallel mode only**. Passed as `--maxcpucount` to `altool workspace compile`. Defaults to the number of logical processors when empty. **Has no effect in serial mode** (serial mode uses a hardcoded `/maxDegreeOfParallelism:2` for intra-project parallelism). $(maxcpucount) $(maxcpucount) $(maxcpucount)
        sastoken:                             # A SAS token to register with the Azure DevOps secret masking mechanism. Not used in any compilation logic — purely prevents the token from appearing in pipeline log output. $(sastoken) $(sastoken) $(sastoken)
        auto_resolve_ms_symbols: true         # Scans all `app.json` dependency lists for Microsoft-published apps, checks the symbol cache (`alcachepath`), and downloads missing symbols from the MSSymbols NuGet feed. Downloads the entry package `Microsoft.Application[.<country>].symbols` plus its full transitive NuGet dependency tree, then individually resolves any still-missing dependencies. Uses `bc_localization`, `bc_version`, `ms_symbols_feed`, and `ms_symbols_pat`. $(auto_resolve_ms_symbols) $(auto_resolve_ms_symbols) $(auto_resolve_ms_symbols)
        bc_localization: W1                   # Business Central country/localisation code determining the entry-point NuGet package for MS symbol resolution. `W1` ? `Microsoft.Application.symbols` (no country segment). Any other value (e.g. `BE`, `NL`) ? `Microsoft.Application.<country>.symbols`. Also used as the `%BC_COUNTRY%` token in `appfilenametemplate`. Case-insensitive. $(bc_localization) $(bc_localization) $(bc_localization)
        bc_version:                           # BC version filter in `Major.Minor` format (e.g. `27.4`) used for MS symbol NuGet package version resolution. When empty, auto-detected from the `application` field in the first `app.json` found (e.g. `"application": "27.4.0.0"` ? `27.4`). Also used as the `%BC_VERSION%` token in `appfilenametemplate`. If empty and no `app.json` has an `application` field, MS symbol download is skipped with a warning. $(bc_version) $(bc_version) $(bc_version)
        ms_symbols_feed: https://dynamicssmb2.pkgs.visualstudio.com/DynamicsBCPublicFeeds/_packaging/MSSymbols/nuget/v3/index.json# NuGet v3 service index URL for the Microsoft MSSymbols feed. The service index is queried for `RegistrationsBaseUrl` to resolve package versions and download URLs. The default points to the public MSSymbols feed (no authentication required). $(ms_symbols_feed) $(ms_symbols_feed) $(ms_symbols_feed)
        ms_symbols_pat:                       # Personal Access Token for authenticated access to the MSSymbols feed. When provided, it is sent as Basic auth (`ALOps:<PAT>`). The token is automatically masked in pipeline logs. Leave empty for the default public feed (no authentication required). $(ms_symbols_pat) $(ms_symbols_pat) $(ms_symbols_pat)
        auto_resolve_appsource_symbols: true  # Attempts to resolve missing third-party (ISV) symbol dependencies from the AppSourceSymbols NuGet feed. Searches by the dependency's `appId` GUID. **Important:** version matching uses the dependency's own `Major.Minor` version from `app.json`, **not** the `bc_version` parameter. No transitive NuGet dependency resolution is performed (ISV packages are self-contained). Uses `appsource_symbols_feed` and `appsource_symbols_pat`. $(auto_resolve_appsource_symbols) $(auto_resolve_appsource_symbols) $(auto_resolve_appsource_symbols)
        appsource_symbols_feed: https://dynamicssmb2.pkgs.visualstudio.com/DynamicsBCPublicFeeds/_packaging/AppSourceSymbols/nuget/v3/index.json# NuGet v3 service index URL for the AppSourceSymbols feed. The default points to the public AppSourceSymbols feed (no authentication required). $(appsource_symbols_feed) $(appsource_symbols_feed) $(appsource_symbols_feed)
        appsource_symbols_pat:                # Personal Access Token for authenticated access to the AppSourceSymbols feed. When provided, it is sent as Basic auth. The token is automatically masked in pipeline logs. Leave empty for the default public feed (no authentication required). $(appsource_symbols_pat) $(appsource_symbols_pat) $(appsource_symbols_pat)
        pwsh: True                            # Run the task in PowerShell Core (`pwsh`) instead of Windows PowerShell. Default is `true`. ALOpsAppCompilerV3 targets PowerShell 7; the entry script includes PS7 bootstrap logic. $(pwsh) $(pwsh) $(pwsh)

Parameters#

compilation_mode#

Choose between two compilation strategies:

  • Serial — compiles one app at a time via altool compile. Gives full control over alc.exe flags (/continuebuildonerror, /errorlog, /enableexternalrulesets, analyzers by DLL path).
  • Parallel — uses a three-step workflow (altool workspace create → altool workspace map → altool workspace compile) to compile all apps concurrently in dependency order. Some parameters only apply in one mode; see individual parameter descriptions.

altool_package_version#

The exact version of the microsoft.dynamics.businesscentral.development.tools NuGet package to use. Pre-release suffixes (e.g. -beta) are supported. Pin to a specific version for reproducible builds; use altool_cache_hours to avoid re-downloading on every run.

auto_resolve_ms_symbols / auto_resolve_appsource_symbols#

ALOpsAppCompiler@3 can automatically resolve missing symbol dependencies from public NuGet feeds:

  • auto_resolve_ms_symbols: true — downloads Microsoft symbols from the MSSymbols feed (public, no PAT required by default).
  • auto_resolve_appsource_symbols: true — downloads third-party ISV symbols from the AppSourceSymbols feed (matched by appId).

Both feeds can be overridden with ms_symbols_feed / appsource_symbols_feed and authenticated with ms_symbols_pat / appsource_symbols_pat.

appversiontemplate#

Four-part version template applied to app.json before compilation. Tokens: - * → current $(Build.BuildId) - ? → keep the original part - A → use the corresponding part from the application field - Date formats in brackets, e.g. [YYYYMMDD], [WW] (zero-padded week)

Leave empty to skip version stamping entirely.

track_source_build_metadata#

When true, injects build and source metadata into app.json (build.url, build.by, source.commit, source.repositoryUrl). Requires runtime >= 12.0 — a warning is emitted and injection is skipped for older runtimes.

publishartifact and alc_errorlog#

publishartifact controls whether compiled .app files are uploaded as pipeline artifacts. It does not control error log publishing.

When alc_errorlog: true, the error log is always published regardless of publishartifact. Set alc_errorlog: false (the default) to prevent error log artifacts.


ALOps App Symbol#

Convert compiled .app files into symbol-only packages using altool CreateSymbolPackage. Symbol packages can be distributed to partners or used as lightweight dependencies without exposing source code.

Full Yaml Description:

    - task: ALOpsAppSymbol@3
      displayName: 'ALOps App Symbol'
      inputs:
        altool_package_version: 17.0.30.49729-beta# Version of the `microsoft.dynamics.businesscentral.development.tools` NuGet package to download from nuget.org. The package contains `altool.exe` which provides the `CreateSymbolPackage` command. Pre-release suffixes (e.g. `-beta`) are supported. $(altool_package_version) $(altool_package_version) $(altool_package_version)
        altool_cache_hours: 0                 # Number of hours the downloaded NuGet package is cached on the agent (under `$AGENT_TOOLSDIRECTORY`). Set to `0` to always download fresh. Non-numeric values silently default to `0`. $(altool_cache_hours) $(altool_cache_hours) $(altool_cache_hours)
        app_source_path: $(System.DefaultWorkingDirectory)# Root folder searched recursively for `.app` files to convert into symbol packages. All matching files (see `app_file_filter`) will be processed. $(app_source_path) $(app_source_path) $(app_source_path)
        app_file_filter: *.app                # File filter/glob pattern for selecting which `.app` files to process. Default is `*.app` which matches all app files in `app_source_path`. $(app_file_filter) $(app_file_filter) $(app_file_filter)
        output_path: $(Build.ArtifactStagingDirectory)# Folder where generated symbol `.app` files will be written. The folder is created if it does not exist. $(output_path) $(output_path) $(output_path)
        verify_symbol: true                   # When `true`, runs `altool IsSymbolOnly` on each generated symbol package to verify it is indeed a symbol-only package. If verification fails, the task fails with an error. $(verify_symbol) $(verify_symbol) $(verify_symbol)
        publishartifact: true                 # Upload the generated symbol `.app` file(s) as Azure DevOps build artifacts. The artifact name is controlled by the `artifact_name` parameter. $(publishartifact) $(publishartifact) $(publishartifact)
        artifact_name: ALOpsSymbolArtifact    # Name of the Azure DevOps build artifact for the symbol packages. Only used when `publishartifact` is `true`. $(artifact_name) $(artifact_name) $(artifact_name)
        pwsh: True                            # Run the task in PowerShell Core (`pwsh`) instead of Windows PowerShell. $(pwsh) $(pwsh) $(pwsh)

Parameters#

verify_symbol#

When true, runs altool IsSymbolOnly on each generated package to confirm it is a valid symbol-only file. The task fails if verification does not pass.

app_file_filter#

Glob pattern for selecting which .app files under app_source_path to process. Defaults to *.app.


ALOps BC Replay#

Run Business Central UI test recordings using @microsoft/bc-replay and Playwright. Recordings are captured outside the pipeline and stored as .yml files; this task replays them against a running BC environment and publishes the results.

Full Yaml Description:

    - task: ALOpsBCReplay@3
      displayName: 'ALOps BC Replay'
      inputs:
        tests: $(System.DefaultWorkingDirectory)\recordings\*.yml# File glob pattern to select the recording `.yml` files to run. Maps to the `-Tests` parameter of `npx replay`. $(tests) $(tests) $(tests)
        start_address:                        # URL to the deployed BC web client. For Docker: `http://localhost:<port>/`. For SaaS: `https://<tenant>.businesscentral.dynamics.com/`. Maps to `-StartAddress`. $(start_address) $(start_address) $(start_address)
        authentication: Windows               # Authentication method to use against the BC web client. `Windows` for on-prem/Docker, `AAD` for SaaS/cloud, `UserPassword` for basic auth. $(authentication) $(authentication) $(authentication)
        username_key:                         # Name of the environment variable containing the username. Required when Authentication is set to `AAD` or `UserPassword`. Maps to `-UserNameKey`. $(username_key) $(username_key) $(username_key)
        password_key:                         # Name of the environment variable containing the password or PAT. Required when Authentication is set to `AAD` or `UserPassword`. Maps to `-PasswordKey`. $(password_key) $(password_key) $(password_key)
        multifactor_type: None                # MFA mechanism. Only available with AAD authentication. Maps to `-MultiFactorType`. $(multifactor_type) $(multifactor_type) $(multifactor_type)
        multifactor_secret_key:               # Name of the environment variable storing the MFA secret. For TOTP: the TOTP secret key. For Certificate: Base64-encoded PFX certificate. Maps to `-MultiFactorSecretKey`. $(multifactor_secret_key) $(multifactor_secret_key) $(multifactor_secret_key)
        result_dir: $(Agent.TempDirectory)\bcreplay_results# Directory to write test results. Maps to `-ResultDir`. $(result_dir) $(result_dir) $(result_dir)
        npm_install: true                     # Automatically install `@microsoft/bc-replay` and Playwright browsers before running. When `false`, expects `@microsoft/bc-replay` to be pre-installed (e.g. in a prior pipeline step). Requires Node.js >= 16.14.0 on the agent. $(npm_install) $(npm_install) $(npm_install)
        bcreplay_version: latest              # Version of `@microsoft/bc-replay` to install. Use `latest` for the newest version or pin to a specific version (e.g. `0.1.119`). Only used when Auto-Install is enabled. $(bcreplay_version) $(bcreplay_version) $(bcreplay_version)
        failed_action: Error                  # Action to take when one or more replay recordings fail. `Error`: fail the task. `Warning`: succeed with issues. `Ignore`: succeed silently. $(failed_action) $(failed_action) $(failed_action)
        publish_results: true                 # Publish replay results as Azure DevOps test results (visible in the Tests tab). $(publish_results) $(publish_results) $(publish_results)
        publish_summary: true                 # Generate and publish a markdown summary report as a build artifact. $(publish_summary) $(publish_summary) $(publish_summary)
        pwsh: true                            # Run task in Powershell Core. $(pwsh) $(pwsh) $(pwsh)

Parameters#

authentication#

Determines how the task authenticates against the BC web client: - Windows — for on-premises or Docker environments - AAD — for SaaS / cloud environments - UserPassword — for basic username/password auth

npm_install#

When true (default), the task automatically installs @microsoft/bc-replay and the required Playwright browsers before running. Set to false if you install the package in a prior pipeline step. Requires Node.js ≥ 16.14.0 on the agent.

failed_action#

Controls the task outcome when one or more recordings fail: - Error — fails the task - Warning — succeeds with issues - Ignore — succeeds silently


ALOps Info#

Display environment diagnostics for the current build agent and optionally enforce thresholds for free memory, free disk space, and active Docker containers. Useful as a first step in pipelines to catch resource problems early.

Full Yaml Description:

    - task: ALOpsInfo@3
      displayName: 'ALOps Info'
      inputs:
        freemem_threshold: 0                  # Minimum required free memory percentage. Set to 0 to disable. When free memory drops below this value, a warning or error is generated based on the threshold action. $(freemem_threshold) $(freemem_threshold) $(freemem_threshold)
        freemem_threshold_action: Warn        # Action to take when the free memory threshold is not met. Warn = task succeeds with issues. Error = task fails. $(freemem_threshold_action) $(freemem_threshold_action) $(freemem_threshold_action)
        freedisk_threshold: 0                 # Minimum required free disk space percentage. Set to 0 to disable. When any drive's free space drops below this value, a warning or error is generated based on the threshold action. $(freedisk_threshold) $(freedisk_threshold) $(freedisk_threshold)
        freedisk_threshold_action: Warn       # Action to take when the free disk threshold is not met. Warn = task succeeds with issues. Error = task fails. $(freedisk_threshold_action) $(freedisk_threshold_action) $(freedisk_threshold_action)
        docker_containers_action: Error       # Action to take when existing Docker containers are found on the agent. Ignore = no action. Warn = task succeeds with issues. Error = task fails. $(docker_containers_action) $(docker_containers_action) $(docker_containers_action)
        pwsh: True                            # Run task in Powershell Core. $(pwsh) $(pwsh) $(pwsh)

Parameters#

freemem_threshold / freedisk_threshold#

Set a minimum percentage of free memory or free disk space. Set to 0 (default) to disable the check. When the threshold is not met, the task reacts according to the corresponding _action parameter (Warn or Error).

docker_containers_action#

Defines what happens when existing Docker containers are found on the agent — useful to detect leftover containers from previous runs: - Ignore — no action - Warn — succeeds with issues - Error — fails the task


ALOps Nuget Download#

Download .app files from NuGet feeds based on a declarative nuget.json spec file. Supports Azure DevOps feeds, public NuGet feeds, and authenticated private feeds. Automatically resolves transitive AppSource dependencies.

Full Yaml Description:

    - task: ALOpsNugetDownload@3
      displayName: 'ALOps Nuget Download'
      inputs:
        nuget_username:                       # Username for the NuGet Source. For Azure DevOps feeds, use any value (e.g. 'az') combined with a PAT as password. $(nuget_username) $(nuget_username) $(nuget_username)
        nuget_password:                       # Password or Personal Access Token (PAT) for the NuGet Source. $(nuget_password) $(nuget_password) $(nuget_password)
        nuget_source_apikey:                  # API Key for the NuGet Source. When set, used as Bearer token and X-NuGet-ApiKey header. $(nuget_source_apikey) $(nuget_source_apikey) $(nuget_source_apikey)
        nuget_protocol_version: auto          # NuGet protocol version to use. 'auto' detects based on feed URL and service index. Set 'v2' or 'v3' to force a specific protocol. $(nuget_protocol_version) $(nuget_protocol_version) $(nuget_protocol_version)
        nuget_spec_file: $(System.DefaultWorkingDirectory)\nuget.json# Path to the nuget.json spec file that defines feeds and package dependencies. $(nuget_spec_file) $(nuget_spec_file) $(nuget_spec_file)
        nuget_select_type_filter:             # Wildcard filter for type names defined in the nuget.json spec file. Leave empty to process all types. $(nuget_select_type_filter) $(nuget_select_type_filter) $(nuget_select_type_filter)
        download_folder: $(System.ArtifactsDirectory)# Target folder where .app files will be downloaded. $(download_folder) $(download_folder) $(download_folder)
        artifact_folder_name: Nuget           # Artifact folder name used when uploading the resolved.json as a build artifact. $(artifact_folder_name) $(artifact_folder_name) $(artifact_folder_name)
        dependency_publisher_filter:          # Semicolon-separated list of publisher names to include when resolving dependencies. Leave empty to allow all publishers. Set to 'NONE' to skip dependency resolution entirely. $(dependency_publisher_filter) $(dependency_publisher_filter) $(dependency_publisher_filter)
        skip_microsoft_apps: True             # Skip packages whose ID starts with 'microsoft.' during dependency resolution. $(skip_microsoft_apps) $(skip_microsoft_apps) $(skip_microsoft_apps)
        pwsh: False                           # Run task in PowerShell Core. $(pwsh) $(pwsh) $(pwsh)

Parameters#

nuget_spec_file#

Path to the nuget.json file that lists feeds and package dependencies. This is the primary configuration for the task.

nuget_protocol_version#

Force v2 or v3 NuGet protocol, or leave as auto to let the task detect the correct protocol from the feed URL and service index.

dependency_publisher_filter#

Semicolon-separated list of publisher names to include during dependency resolution. Leave empty to allow all publishers. Set to NONE to skip dependency resolution entirely.

skip_microsoft_apps#

When true (default), packages whose ID starts with microsoft. are excluded from dependency resolution to avoid redundant downloads of first-party symbols.