Veriland ConsultingVeriland Consulting
  • Water Utilities (MaxWater) →

    • Water Utilities OverviewSpecialist modular platform for UK water utilities — meter-to-cash, asset lifecycle, SCADA, Ofwat compliance.
    • MaxWater Platform & ModulesSix independent modules — pick what you need, own everything we build.
    • Day in the LifeSix interactive stories showing how MaxWater transforms daily work across every department of a water utility.
    • Day in the Life: OperationsSee how MaxWater detects a failing pump at 2 AM and gets it fixed before anyone notices.
    • Day in the Life: ProcurementFrom emergency parts order to delivery — automated procurement across the supply chain.
    • Day in the Life: ComplianceOfwat reporting, DWI sampling, and audit preparation — all automated, all audit-ready.
    • Day in the Life: FinanceCapital project budgeting, AMP funding, cost allocation, and invoice matching.
    • Day in the Life: Project ManagementAMP obligation tracking, earned value, regulatory packages, and programme board reporting.
    • Day in the Life: CustomerMeter reading, billing, customer complaints, and leak detection — the customer-facing story.
  • Fixed‑Price Accelerator Packages →

    • Business Central AcceleratorA rapid, fixed‑price implementation of Business Central for mid-market businesses looking to modernise finance, invoicing, stock and reporting — without complexity.
    • CRM AcceleratorA fast, simple CRM setup built on Dynamics 365 Sales or Customer Service — helping mid-market teams get better pipeline visibility and consistent customer follow‑up.
    • F&O AcceleratorA streamlined version of Dynamics 365 Finance & Operations for mid-market organisations needing stronger financial control, supply chain visibility, and structured operations.
    • AI Agent AcceleratorDeploy 1–2 AI agents that automate repetitive tasks (like reconciliations, order processing, or support responses) with a fixed, predictable cost.
    • Power Platform AcceleratorReplace spreadsheets and manual approvals with automated workflows, low‑code apps, and digital forms built on Power Platform.
    • Migration Packs (ERP / CRM)Move from legacy systems (Sage, Xero, QuickBooks, Access, Salesforce, etc.) to modern Microsoft platforms with a predictable, fixed‑scope migration.
  • Finance, Stock & Operations →

    • Business Central (SMB ERP)A modern, all‑in‑one cloud ERP for mid-market organisations. Manage finance, sales, stock, projects, and operations in one simple system that grows with you.
    • Dynamics 365 Finance & Operations (F&O)Enterprise‑grade finance, supply chain, and operations for mid‑market organisations that need deeper control and automation across their business.
  • Products

    • MaxWAM – Work Asset Management (Mobile, Offline, AI)A mobile‑first, offline‑capable asset maintenance solution with work orders, inspections, compliance checks, and AI‑assisted technician workflows.
    • MaxBudget – AI‑Backed Budget Management for ProcurementGives finance teams real‑time budget visibility for all purchase requests — including committed spend that hasn't been paid yet — reducing overspending and surprises.
    • MaxPortal – Ready‑to‑Use Portal for D365 BC / F&OA configurable customer/vendor/employee portal for Business Central or F&O, enabling self‑service access to orders, invoices, tickets, documents, and status updates.
    • MaxWater – Modular Platform for Water UtilitiesSix independent modules for water utility operations: meter‑to‑cash, asset lifecycle, SCADA integration, field service, Ofwat reporting, and capital project governance.
  • Insights

    • BlogInsights, tips, and thought leadership on Dynamics 365, Azure, and AI for UK businesses.
    • Case StudiesSee how we've helped other businesses transform with Dynamics 365 and AI.
    • Guides & TutorialsFree video tutorials and step-by-step walkthroughs for Dynamics 365, Power Platform, and Azure.
  • Veriland Difference

    • How We WorkDiscover our agile, transparent approach to delivering successful projects.
    • Why Choose VerilandLearn what sets our expertise and partner-driven approach apart.
    • Delivery ExcellenceOur commitment to quality, on-time delivery, and continuous improvement.
    • Security & TrustHow we protect your data and ensure enterprise-grade security.
    • Our Microsoft PartnershipLeveraging our status as a trusted Microsoft Partner for your success.
  • Book discovery call
  • Contact sales
  • Contact support
Veriland Consulting

What We Do

  • Microsoft D365 F&O
  • Microsoft D365 CE
  • Microsoft D365 BC
  • Azure Ecosystem
  • Copilot for Business
  • AI Agents
  • Power Platform

Products

  • MaxWAM
  • MaxBudget
  • MaxPortal

Services

  • D365 as a Service
  • Team as a Service
  • Pay-As-You-Go Support

Insights

  • Case Studies

Company

  • About Us
  • Contact

Connect

  • Charter House, Charter Way
  • Macclesfield, SK10 2NG
  • 01625 569 777
  • enquiries@veriland.co.uk
Microsoft Cloud Partner Program
Privacy PolicyCookie PolicyTerms & ConditionsCustomer ComplaintsModern Slavery Statement
Company Reg: 08209902© 2026 Veriland Consulting. All rights reserved.
  1. Insights
  2. Guides

How to Build a Deployment Package for Dynamics 365 Finance & Operations

  • Watch the Full Tutorial
  • Why a Proper Build Pipeline Matters
  • Prerequisites
  • Step 1: Prepare Your Azure DevOps Project
  • Step 2: Choose Your Source Control Strategy
  • Step 3: Create a New Pipeline Using the Classic Editor
  • Step 4: Configure the Get Sources Task
  • Step 5: Restore the F&O NuGet Packages
  • Step 6: Stamp the Model Version with the Build Number
  • Step 7: Compile the X++ Solution
  • Step 8: Capture Compile Logs
  • Step 9: Add the NuGet Tool Installer Task
  • Step 10: Create the Deployable Package
  • Step 11: Publish the Build Artefact
  • Step 12: Configure Variables and the Continuous Integration Trigger
  • Step 13: Run the Pipeline and Verify the Deployable Package
  • Next Steps
D365 F&OVideo Tutorial 14:0019 May 2026 14 min watch + 8 min read

Presented by Mahmut Bulbul · D365 Consultant, Veriland Consulting

Watch the Full Tutorial

~14 minutes hands-on walkthrough covering source control choice, classic build pipeline setup, F&O-specific tasks, NuGet restore quirks, the deployable package task, and the CI trigger

This guide walks through every task required to stand up a continuous integration build pipeline for a Dynamics 365 Finance and Operations codebase in Azure DevOps. By the end you will have a pipeline that compiles your X++ models, stamps the build number into every model descriptor, and publishes a deployable package as a versioned artefact — ready for the release pipeline covered in Part 2.

Both source control approaches are covered side by side: Team Foundation Version Control (TFVC), which remains the default for many established F&O teams, and Git, which Microsoft now recommends for new projects. The pipeline tasks downstream are identical regardless of which you choose.

If you have not yet provisioned a developer environment, start with our companion guide first: How to Set Up a Unified Development Environment (UDE) for Dynamics 365 Finance & Operations.

Why a Proper Build Pipeline Matters

Many F&O teams still package code on a developer's local machine — open Visual Studio, right-click the model, hit Create Deployable Package. That works for a solo developer on a single branch, but it falls apart the moment you add a second developer, a second environment, or an auditor asking which commit produced the package running in production.

Reproducibility

Every build runs on a clean agent, with the same NuGet packages, the same MSBuild arguments, the same platform and application versions. The .zip produced at build 247 can be regenerated from the same commit hash at any point in the future without relying on a developer's local machine state.

Audit Trail

Every pipeline run records who triggered it, which commit was built, which platform and application versions were used, how long it took, and what artefacts it produced. When a deployment issue is traced back to a specific build, the pipeline run is the single source of truth.

Multi-Developer Collaboration

When two developers commit X++ changes to the same Metadata folder, the pipeline picks both up on the next continuous integration trigger and produces a single deployable package containing both changes. No more "who built last?" confusion.

Predictable Release Pipelines

Part 2 of this series — the release pipeline — depends on a clean, well-named, well-versioned input artefact. Without an automated build producing that artefact consistently, every release becomes a manual, error-prone exercise.

Prerequisites

Prerequisites

  • Azure DevOps project — an existing project with Boards, Repos, Pipelines, and Artifacts enabled. If you do not have one, create it from your Azure DevOps organisation dashboard
  • Agent pool — at least one agent pool available to your project. The Microsoft-hosted Azure Pipelines pool works for most F&O builds; self-hosted agents are optional
  • Source control set up — your F&O codebase already committed to either TFVC or Git, with the standard Metadata, Build, and Projects folders in place
  • Dynamics 365 Finance and Operations Tools extension — installed from the Azure DevOps Marketplace. This provides the Update Model Version and Create Deployable Package tasks used in the pipeline
  • packages.config and nuget.config files — the standard Microsoft-supplied F&O NuGet configuration, committed to your source repository under a NugetConfigs folder
  • Project Collection Build Service permissions — for TFVC, the build service identity needs Check-in and Read access to the Trunk/Dev branch. For Git, it needs Read access to the repository

Step 1: Prepare Your Azure DevOps Project

Verify the project structure and agent pool availability

Sign in to your Azure DevOps organisation and open the project that holds your F&O codebase. The project landing page shows you the navigation rail on the left — Repos, Pipelines, and Project Settings are the three areas used in this guide.

Open Organization Settings then Agent pools to confirm at least one pool is available to this project. The Azure Pipelines pool is the Microsoft-hosted default and is sufficient for most F&O builds.

Service connections do not need to be configured at this stage. The build pipeline does not require any. They become relevant in Part 2 when the release pipeline deploys to an environment.

Azure DevOps project landing page showing the standard navigation rail with Repos, Pipelines, and Project Settings highlighted.Figure 1: Azure DevOps project landing page — Repos, Pipelines, and Project Settings are the three areas used in this guide.

Step 2: Choose Your Source Control Strategy

Decide between TFVC and Git for your repository

Finance and Operations developers typically use one of two source control systems. The pipeline tasks downstream are identical regardless of which you choose.

Team Foundation Version Control (TFVC) is hierarchical: branches such as Trunk, Dev, and SIT are represented as folders on the server. Inside each branch, the standard F&O layout applies — Metadata, Build, Projects, and NugetConfigs at the top level.

TFVC server-side branching structure for an F&O codebase showing Trunk, Dev, and SIT branches as folders on the server.Figure 2: TFVC server-side branching structure — Trunk, Dev, and SIT branches as folders on the server.

Git uses true branches rather than folders. A fresh repository starts with a single main branch, and the team builds out its branching strategy from there. The folder layout inside each branch is identical to TFVC.

Git repository file view showing the standard F&O folder layout — identical contents to TFVC, different version-control model.Figure 3: Git repository file view — identical folder layout to TFVC, different version-control model.

Which to pick? Microsoft's modern recommendation is Git, particularly for new projects. Mature teams already running on TFVC do not need to migrate solely for pipeline support — both work equally well with the build tasks covered in this guide.

Step 3: Create a New Pipeline Using the Classic Editor

Bypass the YAML wizard and use the visual editor

From Pipelines, click New pipeline. Azure DevOps will steer you towards the YAML-based wizard by default. For F&O builds, the classic editor is significantly easier to learn from and debug.

Scroll to the bottom of the source selection page and click the small Use the classic editor link. From here, select your source — TFVC or Azure Repos Git — and pick the branch or folder to build from.

On the template selection screen, choose Empty Job at the top. This drops you onto a blank pipeline canvas with a single Agent job 1 already in place.

The empty pipeline canvas after selecting Empty Job, showing the five tabs: Tasks, Variables, Triggers, Options, and History.Figure 4: The empty pipeline canvas after selecting Empty Job. The five tabs — Tasks, Variables, Triggers, Options, History — are where the rest of the configuration happens.

Step 4: Configure the Get Sources Task

Set the pipeline to pull a clean copy of your code on every run

The first task on the canvas — Get sources — is added automatically based on the source you selected on the previous screen. For TFVC, it shows your repository root with workspace mappings; for Git, it shows the repository and branch.

Set Clean to true, and select Sources and output directory from the dropdown. This ensures every build starts from a fresh checkout, with no leftover binaries or cached metadata from a previous run.

Leave Label sources turned off unless your team uses TFVC labels for traceability — most do not, and the pipeline run number plus the Update Model Version task in Step 6 provide all the traceability you need.

Get sources task configured with Clean enabled. Workspace mapping points at the Trunk/Dev folder for TFVC.Figure 5: Get sources task configured with Clean enabled. Workspace mapping points at the Trunk/Dev folder for TFVC; for Git this section shows the repository and branch.

Step 5: Restore the F&O NuGet Packages

Add a NuGet custom install task for F&O platform packages

Click the plus button on Agent job 1, search for NuGet, and add the task. F&O builds do not use the standard NuGet restore command. They use the custom install command with specific arguments.

Set the Command to custom, and provide the following Command and arguments value:

install -NonInteractive $(NugetConfigsPath)\packages.config -ConfigFile $(NugetConfigsPath)\nuget.config -Verbosity Detailed -ExcludeVersion -OutputDirectory $(NugetsPath)

This instructs NuGet to install every package listed in your packages.config — including the four F&O packages: the platform compiler package, the platform metadata package, the application metadata package, and the application suite metadata package. Together these give the build agent everything it needs to compile X++ code.

The ExcludeVersion flag is important: it causes NuGet to install each package into a folder named after the package only, not package-and-version. This keeps the downstream MSBuild references stable across platform updates — you change the package version in packages.config, but the folder paths in your MSBuild arguments stay the same.

This is the most common point of failure in F&O build pipelines. If the NuGet restore fails, check that the NugetConfigsPath and NugetsPath variables (defined in Step 12) match the actual folder structure in your repository. Also confirm that the packages.config and nuget.config files are committed and up to date.

NuGet custom install task with the custom command and arguments configured for F&O platform package restoration.Figure 6: NuGet custom install task. The custom command with install arguments gives the agent the F&O build tools — standard NuGet restore is not sufficient.

Step 6: Stamp the Model Version with the Build Number

Automatically write the build number into every model descriptor

Add an Update Model Version task. This task is provided by the Dynamics 365 Finance and Operations Tools extension from the Azure DevOps Marketplace; if it does not appear in the task list, install the extension first.

Configure the task as follows:

X++ Source Location: $(MetadataPath)

Descriptor Search Pattern: **\Descriptor\*.xml

Lowest Layer to Update: ISV (for ISV products) or CUS (for customer code)

Version Number: $(Build.BuildNumber)

The effect: on every successful build, every model descriptor in your codebase is stamped with the build's own number. When a model is later deployed to an environment, the version shown in the environment's model list traces directly back to the pipeline run that produced it.

Update Model Version task configured with MetadataPath, Descriptor search pattern, and Build.BuildNumber for downstream traceability.Figure 7: Update Model Version task — every model descriptor stamped with $(Build.BuildNumber) for downstream traceability.

Step 7: Compile the X++ Solution

Run MSBuild over your F&O solution with the right reference paths

Add a Visual Studio Build task. Set the Solution to **\*.sln to match any solution file under the source root, and the Visual Studio version to 2022.

The MSBuild Arguments line is where F&O build pipelines diverge most from standard .NET builds. You need to point MSBuild at the F&O metadata directory, the NuGet package locations for platform and application references, and the output directory for compiled binaries.

Output is written to $(Build.BinariesDirectory), a temporary folder referenced by the Create Deployable Package task in Step 10.

Visual Studio Build task configured with MSBuild arguments pointing to F&O metadata and NuGet package paths.Figure 8: Visual Studio Build task — the MSBuild arguments wire MSBuild into the F&O NuGet package layout restored by the previous task.

Step 8: Capture Compile Logs

Copy X++ compiler log files into the build artefact

Add a Copy Files task and name it Copy X++ Compile Log Files. The F&O compiler produces three log file types worth keeping around:

  • xppc log files — X++ compiler output, including warnings and errors per model
  • labelc log files — label compiler output, used to diagnose missing or duplicate labels
  • reportsc log files — report compiler output, for SSRS report diagnostics

Set Source Folder to $(Build.SourcesDirectory), Target Folder to $(Build.ArtifactStagingDirectory)\Logs, and the Contents pattern to match all three log types.

These logs are published as part of the build artefact in Step 11. When a build fails or produces unexpected results, this is the first place you look.

Copy Files task configured to capture xppc, labelc, and reportsc log files into the artefact staging directory.Figure 9: Copy Files task capturing xppc, labelc, and reportsc log files into the artefact staging directory.

Step 9: Add the NuGet Tool Installer Task

Ensure NuGet is available for the Create Deployable Package task

Add a NuGet Tool Installer task to the pipeline. Set the Version field to 3.3.0. This makes NuGet available on the build agent so the next task can use it to bundle the deployable package correctly.

NuGet Tool Installer task set to version 3.3.0.Figure 10: NuGet Tool Installer task set to version 3.3.0.

Step 10: Create the Deployable Package

Bundle compiled X++ binaries into a deployable .zip

Add a Create Deployable Package task. This is the task that bundles the compiled X++ binaries with the metadata and dependencies into a single .zip file — the primary output of the entire pipeline.

Configure the following fields:

X++ Tools Path: $(NuGetsPath)\$(ToolsPackage)

Location of the X++ binaries to package: $(Build.BinariesDirectory)

Package Platform Version: match your target environment exactly — for example, 7.0.7367.49

Package Application Version: match your target environment exactly — for example, 10.0.2015.54

Path for the cloud deployable package: $(Build.ArtifactStagingDirectory)\CloudDeployablePackage

The Platform Version and Application Version values are critical. They are stamped into the deployable package metadata and validated by the target environment during deployment. A mismatch between the package version and the environment version causes deployment failures.

Tick Create Lifecycle Services Software Deployable Package. Even though we are not deploying via LCS in the UDE/PPAC world, this checkbox controls whether the task produces the standard .zip format that downstream tools expect.

The Platform Version and Application Version must match your target environment exactly. You can find these values in the Power Platform Admin Center under your environment's Dynamics 365 apps — look at the Finance and Operations Provisioning App version. When your target environment is upgraded, update these values in the pipeline variables immediately.

Create Deployable Package task with Platform and Application Version fields configured to match the target environment.Figure 11: Create Deployable Package task — Platform and Application Version must match the target environment exactly.

Step 11: Publish the Build Artefact

Attach the deployable package to the build run

Add a Publish build artifacts task as the final task on the canvas. This takes everything in $(Build.ArtifactStagingDirectory) — the deployable package .zip, the CloudDeployablePackage folder, and the compile logs — and attaches them to the pipeline run as a downloadable artefact.

Set Path to publish to $(Build.ArtifactStagingDirectory), Artifact name to drop, and Artifact publish location to Azure Pipelines (the default).

Once the build completes, this drop artefact is what the release pipeline in Part 2 will reference as its input.

Publish build artifacts task configured to publish the deployable package and log files as the drop artefact.Figure 12: Publish build artifacts task — the deployable package and supporting files are published as the drop artefact.

Step 12: Configure Variables and the Continuous Integration Trigger

Centralise the NuGet package folder names and wire up the CI trigger

Variables

Switch to the Variables tab. Every $(...) reference used in the tasks above is resolved against this tab. Define each of the following:

App1Package, App2Package, AppSuitePackage — the F&O application NuGet package folder names. These change with each major platform release.

PlatPackage, ToolsPackage — the F&O platform NuGet package folder names. Again, these change with platform versions.

MetadataPath — the relative path from the source root to your Metadata folder. For TFVC it is typically Trunk/Dev/Metadata; for Git it is simply Metadata.

NugetConfigsPath, NugetsPath — the paths under the source root where your packages.config / nuget.config live, and where the NuGet task should write the downloaded packages.

Variables tab showing F&O NuGet package folder names and metadata paths centralised for easy updates.Figure 13: Variables tab — F&O NuGet package folder names and metadata paths centralised so they can be updated in one place.

Continuous Integration Trigger

Switch to the Triggers tab. Tick Enable continuous integration. Tick Batch changes while a build is in progress — this is important. Without it, three rapid commits trigger three separate builds; with batching enabled, the second and third commits are rolled into a single build run, saving agent time and producing one clean artefact.

Add a path filter scoped to your Metadata folder. This is a small but valuable optimisation: every documentation tweak, README update, or pipeline-configuration change that does not touch the X++ Metadata folder skips the build entirely.

Triggers tab with continuous integration enabled, batch changes ticked, and a path filter scoped to the Metadata folder.Figure 14: Triggers tab — CI enabled with batching, path filter scoped to the Metadata folder.

Step 13: Run the Pipeline and Verify the Deployable Package

Save, queue, and confirm that the .zip lands in the drop artefact

Click Save & queue. Pick a branch, add a queue comment if you like, and click Save and run. The pipeline begins executing immediately.

Pipeline runs list showing a successful first run of the build pipeline.Figure 15: Runs list — a successful first run of the build pipeline.

Click into the run to see the detailed view. You will see the Compile X++ job listed below the summary, with each task showing its individual execution time and status. Green checkmarks across all tasks confirm a clean build.

Run detail page showing build succeeded with all tasks completed and one published artefact attached.Figure 16: Run detail page — build succeeded with all tasks completed and one published artefact attached.

Click the 1 published link in the Related box to open the artefacts view. Drill into the drop artefact and you will see the published structure. The headline file is AXDeployableRuntime_[build-number].zip — this is the deployable package that the release pipeline in Part 2 will pick up.

Alongside the .zip, you will see the CloudDeployablePackage folder — the same package in the format Power Platform pipelines expect for PPAC deployments — and the Logs folder containing the xppc, labelc, and reportsc compiler output.

Published drop artefact showing AXDeployableRuntime zip file, CloudDeployablePackage folder, and Logs folder.Figure 17: Published drop artefact — AXDeployableRuntime_[build-number].zip is the deliverable. CloudDeployablePackage is the equivalent for PPAC; Logs contains compiler output.

Next Steps

With the build pipeline running and producing a verified deployable package, the foundation is in place. Here are the next things to do, in order:

Commit a small X++ change and watch the CI trigger fire — confirm the pipeline runs end-to-end on a genuine commit, not just a manual queue, and that the path filter correctly ignores non-Metadata changes.

Update Platform and Application Versions when your target environment is upgraded — these two values on the Create Deployable Package task and the corresponding NuGet package folder names in Variables must stay aligned with the environment you are deploying to.

Document your pipeline variables for your team — particularly the package folder names, which change with every F&O major release and are easy to forget when upgrading.

Move on to Part 2 — The Release Pipeline — where we take the .zip produced here and walk through deploying it automatically to a UDE environment and a downstream sandbox via Power Platform pipelines.

Dynamics 365 F&OAzure DevOpsBuild PipelinesX++ DevelopmentALMTFVCGitUDEDeveloper Tools

Need Help Setting Up Your D365 F&O Build and Release Pipelines?

Our ex-Microsoft consultants configure end-to-end ALM pipelines, automate deployable package creation, and get your D365 F&O team shipping X++ code with confidence.

Book a Discovery CallView Managed Services
Or call us directly: 01625 569 777