D365 Finance & Operations: Build Automation Using Azure Pipeline and Microsoft Hosted Agent

This blog will help guide you in automating the build release using Azure Pipeline and Microsoft-hosted agents.

Normally, to create a build release, you would setup a cloud-hosted Build environment in Lifecycle Services (LCS). This is a Virtual Machine in Azure that costs money depending on the size of the machine and time usage. There is minimal storage cost when the machine is turned off but when it is left running, regardless of if it’s being used or not, the monthly cost will be significant.

Alternatively, you can create a build release using Azure Pipelines and Microsoft-hosted agents. You don’t have to worry about maintenance and updates since there is no server to maintain and to perform updates to. A temporary Virtual Machine is created each time you run your pipeline. After that, the Virtual Machine is discarded.

For this alternative build process, Microsoft gives each private project in an organization the following:

  • One free parallel job that can run for up to 60 minutes each time (with limit of 1,800 minutes (30 hours) per month). You’ll need to purchase additional parallel jobs if you need to run multiple pipelines at the same time. Read more about configuring and paying for parallel jobs.
  • 2 GB free usage of Azure Artifacts. If you exceed this limit, actual usage will be charged per this pricing documentation.

Table of Contents

NuGet Packages

For Dynamics 365 Finance & Operations environment versions 10.0.18 and above, you need to download four packages from LCS’ Shared Asset Library.

Step 1- On your Dev environment, open your web browser and login to LCS. Go to the Shared Asset Library.

Screenshot of LCS home page highlighting the shared assets library tab.

Step 2- Go to the NuGet packages tab then download the four packages that match your Dev environment’s Platform Update version. To download, click the name (blue hyperlink) of the package.

    1. Application Build Reference (Microsoft.Dynamics.AX.Application.DevALM.BuildXpp.nupkg)
    2. Application Suite Build Reference (Microsoft.Dynamics.AX.ApplicationSuite.DevALM.BuildXpp.nupkg)
    3. Compiler Tools (Microsoft.Dynamics.AX.Platform.CompilerPackage.nupkg)
    4. Platform Build Reference (Microsoft.Dynamics.AX.Platform.DevALM.BuildXpp.nupkg)

My Dev environment is on Platform Update 56

Screenshot of environment version information highlighting the platform release. Screenshot of LCS shared asset library highlighting NuGet packages asset type and Nuget packages files.

Step 3- In File Explorer under your Downloads library, create a folder called NugetPackagesD365FO. Save the package files to this folder.

Here is the complete path:  C:\Users\<your username>\Downloads\NugetPackagesD365FO.

Screenshot of NugetPackagesD365FO folder.

Azure DevOps Artifacts

Step 1- On your Dev environment, login to your Azure DevOps, then navigate to your DevOps Project > Artifacts > Connect to Feed.

Azure devops projects highlighting artifacts and then highlighting connect to feed.

Step 2- Click on NuGet.exe.

Screenshot of azure devops in connect to feed highlighting NuGet.exe .

Step 3- Create a nuget.config file by copying the section below from DevOps. It should look like this:

screenshot in azure devops NuGet.exe highlighting the project setup

Note that if you are using a text editor like Notepad to create this config file, make sure you change the ‘Save as type’ to ‘All files’.  Save your nuget.config file to C:\Users\<your username>\Downloads\NugetPackagesD365FO.

Step 4- Go back to the Artifacts window then click the gear icon to open the Feed Settings.

Screenshot of Azure DevOps artifacts window highlighting the gear icon.

Step 5- Under Retention policies, tick the box to Enable package retention. Set your Maximum number of versions per package and Days to keep recently downloaded packages. Take note that the free storage space is only 2GB. Your setting here will affect your storage cost. Click ‘save’ when done.

Screenshot of Azure DevOps feed details highlighting retention policies, maximum number of persons per package, days to keep recently download packages, and the save button.

Step 6- Click here to download the latest nuget.exe file and save it to C:\Users\<your username>\Downloads\NugetPackagesD365FO.

Step 7- Open a Command Prompt window in Admin mode.

Step 8- Navigate to C:\Users\<your username>\Downloads\NugetPackagesD365FO where the four NuGet packages from above are saved. Make sure the nuget.config and nuget.exe files are in the same folder as the four NuGet packages.

Sreenshot in NugetPackagesD365FO file.

Run this command: cd “C:\Users\<your username>\Downloads\NugetPackagesD365FO”.

Screenshot of command prompt.

Step 9- Publish your NuGet packages by providing the package path, an API Key (any string will do) and the feed URL. To publish, run these commands in the Command Prompt window:

nuget.exe push -Source “<xxxxx>” -ApiKey az Microsoft.Dynamics.AX.Application.DevALM.BuildXpp.nupkg

nuget.exe push -Source “<xxxxx>” -ApiKey az Microsoft.Dynamics.AX.ApplicationSuite.DevALM.BuildXpp.nupkg

nuget.exe push -Source “<xxxxx>” -ApiKey az Microsoft.Dynamics.AX.Platform.CompilerPackage.nupkg

nuget.exe push -Source “<xxxxx>” -ApiKey az Microsoft.Dynamics.AX.Platform.DevALM.BuildXpp.nupkg

Note: Replace the source <xxxxx> above with the key from your nuget.config file.

Screenshot of source code.

When prompted for a password, type in the Personal Access Token (PAT) for the user instead of the normal password. Here’s a link to read more about PAT.

Screenshot of PAT code.

Step 10- When done, you should see your four NuGet packages in DevOps’ Artifacts. Take note of the version for each file below:

Screenshot of azure devops artifacts highlighting the file versions.

Step 11- On your Dev environment, create a packages.config file using the template below. Replace the version of the packages based on the previous step. Save this config file to C:\Users\<your username>\Downloads\NugetPackagesD365FO.

Screenshot of packages.config file.

Here’s a text version of the template above for your convenience:

<?xml version=”1.0″ encoding=”utf-8″?>


    <package id=”Microsoft.Dynamics.AX.Platform.DevALM.BuildXpp” version=”7.0.6801.80″ targetFramework=”net40″ />

    <package id=”Microsoft.Dynamics.AX.Application.DevALM.BuildXpp” version=”10.0.1515.81″ targetFramework=”net40″ />

    <package id=”Microsoft.Dynamics.AX.ApplicationSuite.DevALM.BuildXpp” version=”10.0.1515.81″ targetFramework=”net40″ />

    <package id=”Microsoft.Dynamics.AX.Platform.CompilerPackage” version=”7.0.6801.80″ targetFramework=”net40″ />


Azure DevOps Repos

Step 1- Login to Azure DevOps then go to your Project > Repos.

Step 2- Click the 3 dots next to the Trunk folder to create 2 folders called ‘Dev’ and ‘Main’.

Screenshot of azure devops repos highlighting trunk, new, and. Screenshot of azure devops repos highlighting dev and main in the trunk file.

Step 3- Create 3 sub-folders called ‘BuildAutomation’, ‘Metadata’ and ‘Projects’ under each of the Dev and Main folders. Your folder structure should look like this:

Screenshot of trunk folder with three subfolders under dev and main.

Visual Studio Solution and Project

Step 1- Login to your Dev environment.

Step 2- Launch File Explorer to create the following folder structure in your C drive.

Screenshot of VS file.Screenshot of code merge file. Screenshot of dev file. Screenshot of main file.

Step 3- Copy the nuget.config and packages.config files to C:\VS\BuildAutomation.

Step 4- Launch Visual Studio in Admin mode.

Step 5- Create a new project.

Screenshot of visual studio highlighting create a new project option.

Step 6- Type ‘Finance Operations’ in the search field then select Finance Operations and click next.

Screenshot of create a new project highlighting finance operations search.

Step 7- Enter your project name, location, and solution name then set your location to “C:\VS\Projects\” folder. Leave the box ‘Place solution and project in the same directory’ unchecked and click create.

Screenshot of configure new project- finance operations.

Step 8- From the main menu, click View > Team Explorer.

Visual studio main menu highlighting view and team explorer.

Step 9- Click the Home icon then Source Control Explorer.

Screenshot of team explorer home highlighting source control.

Step 10- From the Source Control Explorer, open Workspaces.

Screenshot of source control explorer page highlighting workspaces.

Step 11- Click ‘add’ to create 2 workspaces: one for <ComputerName>_Dev and one for <ComputerName>_Code_Merge.

Screenshot of manage workspaces.

Step 12- Select the Dev workspace then click edit. Map your Source Control Folders to your Local Folders as follows. Click ok when done.

Screenshot of edit workspace source control folder.

Step 13- Select the Code_Merge workspace. Map your Source Control Folders to your Local Folders as follows. Click ok when done.

Screenshot of code_merge workspace edit.

Step 14- Switch to your Dev workspace.

Screenshot of dev workspace, source control explorer.

Step 15- Convert the Dev and Main Folders to Dev and Main Branches:

Right click Dev > Branching and Merging > Convert to Branch.

Right click Main > Branching and Merging > Convert to Branch.

Screenshot highlighting dev folder, branching and merging, and convert to branch functions. Screenshot highlighting main folder, branching an merging, and convert to branch functions.

Step 16- Expand the Trunk\Dev branch. Right click the BuildAutomation folder then select ‘Add Items to Folder’ to add your nuget.config and packages.config files from C:\VS\BuildAutomation.

Screenshot of the trunk/dev branch highlighting build automation and add items to folder functions.

Step 17- Right click the ‘BuildAutomation’ folder again then select ‘Check In Pending Changes’. This will copy the files to the Dev\BuildAutomation folder in DevOps Repos (Dev Source Control).

Screenshot of build automation function highlighting check in pending changes.

Step 18- Switch to your Code_Merge workspace.

Screenshot of source control explorer highlighting code_merge workspace.

Step 19- Right click the Dev branch then select ‘Get Latest Version’. This will copy the files from Dev Source Control to your C:\Code_Merge\Dev\BuildAutomation folder. Do the same for the Main branch.

Screenshot of source control explorer highlighting dev branch and get latest version function.

Step 20- Right click the Dev branch then select ‘Branching and Merging’ > ‘Merge’. This will copy the files from C:\Code_Merge\Dev\BuildAutomation to C:\Code_Merge\Main\BuildAutomation folder.

Screenshot of dev branch highlighting branching and merging and merge function.

Step 21- For the Target branch, browse to your Trunk/Main branch then click Next twice then Finish.

Screenshot of trunk/main branch.

Step 22- Right click the Main folder then select ‘Check In Pending Changes’. This will copy the files to the Main\BuildAutomation folder in DevOps Repos (Main Source Control).

Screenshot in main folder highlighting check in pending changes.

Azure Pipeline

Step1- Download this JSON template from github: xpp-classic-ci.json.

Step2- Login to Azure DevOps then go to your Project > Pipelines.

Step 3- Click on the 3 dots next to ‘New pipeline’ then select ‘Import a pipeline’.

Screenshot of azure DevOps project pipelines highlighting ellipsis and import pipeline.

Step 4- Import the xpp-classic-ci.json file from Step 1. and click ‘browse’. Navigate to the JSON file then click ‘import’.

Screenshot of JSON file highlighting browse. Screenshot of JSON file file highlighting import.

Step 5- Navigate to the Variables tab and change the NugetConfigsPath to BuildAutomation.

Screenshot of variables tab highlighting variables button and NugetConfigsPatch.

Step 6- Navigate back to the Tasks tab and make the following changes:

  1. Pipeline
    • Agent pool: Azure Pipelines
    • Agent Specification: windows-2019 Tasks tab highlighting pipeline, agent poo and agent specification.
  2. Get Sources:
    • Select a source: TFVC
    • Workspace mappings: Set the Server path to $/<project name>/Trunk/MainTask bar highlighting get sources, TFVC and the server path.
  3. Update Model Version
    • X++ Source Location: $(MetadataPath)Task bar highlighting X++ source location.
  4. Build solution **\*.sln:Task tab highlighting build solution and MSBuild Arguments.
  5. Create Deployable Package:
    • X++ Tools Path: $(NuGetsPath)\\$(ToolsPackage)Task tab highlighting Crete Deployable Package and X++ tools path.
    • Note: Take note of the double backslash “\\” above.
  6. Add Licenses to Deployable Package:
    • Right click on this task then select ‘Disable selected task’.Task bar highlighting add licenses to deployable package and disable selected tasks.

Step 7- Click ‘Save & queue’ to run the pipeline.

Step 8- If the pipeline runs successfully, a software deployable package in ZIP format will be generated. To download the ZIP file:

  1. Open the “X++ Classic Pipeline-import” pipeline from DevOps Project > Pipelines.Screenshot of recently run pipelines highlighting X++ classic pipeline-import.
  2. Click the successful run with a check mark.screenshot of X++ classic pipeline-import highlighting the successful run
  3. Click on the published hyperlink:Pipeline summary highlighting the published hyperlink.
  4. Expand the drop folder. Click the 3 dots to the right of the ZIP file then select ‘Download artifacts’. Save the ZIP file to your local drive.Screenshot of published artifacts highlighting the drop folder and download artifacts option.
  5. In LCS > Asset Library > Software deployable package. Click the + Sign to add/upload the ZIP file as a software deployable package in LCS.LCS asset library highlighting software deployable package files.


Take note that this Build Automation is limited to compilation and packaging only. Database synchronization and other features that require the runtime AOS are not supported.

Since there is a limit of 2GB storage for Azure Artifacts (for free Azure DevOps organizations), make sure to delete old and unused versions of the NuGet packages to free up space. You will be charged if you exceed this limit. You’ll also need to purchase add-ons if you need to run multiple pipelines at the same time.

Finally, when you update your environment to a different Platform version, always ensure that the packages.config file and the Azure DevOps Artifact files are updated accordingly.

If you have more questions about Build Automation using Azure Pipeline please contact us.

Read Case Study of a Manufacturer's Dynamics 365 Implementation with Encore

"We met our three project goals of 100% completion of critical business requirements at Go Live, completed with 90% Best Practices or better, and GO Live done in a timely manner."

Read Case Study

What Is a D365 Implementation Really Like?

Read Case Study