Create deployable packages in Azure Pipelines

If you want to deploy customizations to an environment, a deployable package is required in Microsoft Dynamics Lifecycle Services (LCS). You can create this package by using Azure Pipelines during a build or release process.

This article assumes a working knowledge of Azure Pipelines.

Note

Add the task to a pipeline

To add the task to the build of your YML or Classic pipeline, search the task list for Create Deployable Package. The following table describes the options that are available for this task.

Input name Mandatory Description
X++ Tools Path Yes The path of the location of the X++ tools. This location is either the PackagesLocalDirectory\bin folder location on a build VM, or the location of the extracted NuGet file of the Compiler Tools NuGet package.
Location of the X++ binaries to package Yes The path that contains the folders that contain all the binaries for the X++ packages (modules) that you want to include in the deployable package. If this task is used in a build pipeline, this folder is typically the same as the compiler output folder.
Search pattern for binaries to package Yes Provide a name matching pattern for X++ package (module) names inside the path that is specified in the Location of the X++ binaries to package option. You can also specify a list of names instead of search patterns, or you can specify exclusion filters so that, for example, test packages aren't included. The search pattern looks for folders and validates that they contain a bin sub-folder with X++ assemblies. For more information, see File matching patterns reference.
Filename and path for the deployable package Yes The path and file name of the deployable package. The output file is a zip file, and the file name typically includes version information to make the file easy to identify.

Note

With the introduction of the unified developer experience, a new version of this task was released that is capable of generating the package in both the LCS and Power Platform unified package formats. To generate the package in the Power Platform unified package format at the "path for the cloud deployable package" location, select the Create Power Platform Unified Package checkbox, and then enter the platform and application version used. The search pattern and tools package path are still honored as before. The LCS package creation option is selected by default and is generated the same way it was before, with the option to turn off creating the LCS package. The Platform and Application version fields are ignored.

NuGet dependency

When this task is run on the build VM, NuGet is already available, and no action is required. However, when this task is run on hosted agents or other private agents, NuGet must be installed. In this case, Azure DevOps has the NuGet Tool Installer task that you can run before you run the task to create the package.

Note

Because of the introduction of semantic versioning in NuGet version 3.4 and later, you must install version 3.3.0 or earlier.

Search for binaries to package

Compared to the legacy packaging on the build virtual machine, the packaging task has to specify which modules to package and where to find them. In a standard pipeline, X++ modules under compilation are output in the binaries folder of the Azure DevOps agent. The packaging task by default will look in this folder for any X++ binaries. The search looks for folder names. The task will check inside these folders if there is a /bin/ subfolder with X++ assemblies.

Note

If your source control repositores includes third-party binaries such as ISV modules, the packaging step has specifically includes those binaries. See the examples section of this article.

Examples of search patterns

The following example assumes the Location of the X++ binaries to package property is set to its default value of $(Build.BinariesDirectory), which is the location where the X++ compiler produces the binaries.

Search pattern Description
* Find all X++ binaries in $(Build.BinariesDirectory). This is the default value.
*
!*Tests
Find all X++ binaries, exclude any module names that end in Tests.
MyPackage Find a module named MyPackage in the $(Build.BinariesDirectory) folder.
*
$(Build.SourcesDirectory)\Metadata\MyBinaryPackage
Include all X++ binaries in $(Build.BinariesDirectory), as well as a module named MyBinaryPackage in the sources directory (which is the mapped source control repository folder) inside the Metadata folder.
*
!*Tests
$(Build.SourcesDirectory)\Metadata\MyISV1
$(Build.SourcesDirectory)\Metadata\MyISV2
Include all X++ binaries in $(Build.BinariesDirectory), exclude any modules where the names end in Tests, and include two modules named MyISV1 and MyISV2 in the sources directory (which is the mapped source control repository folder) inside the Metadata folder.

Frequently asked questions

In the Create Deployable Package step, what is the workaround for when I get the "There is not enough space on the disk" error?

If the agent running the pipeline runs out of disk space during the Create Deployable Package step, the workaround is to introduce a delete files task in the pipeline just before this task to delete the contents of the $(Build.SourcesDirectory). This task then creates space if no other part of the pipeline is using those files. The Create Deployable Package step is not dependent on the model source files because it is dependent on the build output from the build step.