The table below lists the different MSBuild arguments you can define to setup your build pipeline.
MSBuild argument
Value
Description
AppxPackageDir
$(Build.ArtifactStagingDirectory)\AppxPackages
Defines the folder to store the generated artifacts.
AppxBundlePlatforms
$(Build.BuildPlatform)
Enables you to define the platforms to include in the bundle.
AppxBundle
Always
Creates an .msixbundle/.appxbundle with the .msix/.appx files for the platform specified.
UapAppxPackageBuildMode
StoreUpload
Generates the .msixupload/.appxupload file and the _Test folder for sideloading.
UapAppxPackageBuildMode
CI
Generates the .msixupload/.appxupload file only.
UapAppxPackageBuildMode
SideloadOnly
Generates the _Test folder for sideloading only.
AppxPackageSigningEnabled
true
Enables package signing.
PackageCertificateThumbprint
Certificate Thumbprint
This value must match the thumbprint in the signing certificate, or be an empty string.
PackageCertificateKeyFile
Path
The path to the certificate to use. This is retrieved from the secure file metadata.
PackageCertificatePassword
Password
The password for the private key in the certificate. We recommend that you store your password in Azure Key Vault and link the password to variable group. You can pass the variable to this argument.
Before building the packaging project the same way the wizard in Visual Studio does using the MSBuild command line, the build process can version the MSIX package that’s being produced by editing the Version attribute of the Package element in the Package.appxmanifest file. In Azure Pipelines, this can be achieved by using an expression for setting a counter variable that gets incremented for every build, and a PowerShell script that uses the System.Xml.Linq.XDocument class in .NET to change the value of the attribute.
Sample YAML File that defines the MSIX Build Pipeline
To sign the MSIX (or APPX) package the pipeline needs to retrieve the signing certificate. To do this, add a DownloadSecureFile task prior to the VSBuild task.
This will give you access to the signing certificate via signingCert.
yml
- task:DownloadSecureFile@1 name:signingCert displayName:'Download CA certificate' inputs: secureFile:'[Your_Pfx].pfx'
Next, update the MSBuild task to reference the signing certificate:
The PackageCertificateThumbprint argument is intentionally set to an empty string as a precaution. If the thumbprint is set in the project but does not match the signing certificate, the build will fail with the error: Certificate does not match supplied signing thumbprint.
Review parameters
The parameters defined with the $() syntax are variables defined in the build definition, and will change in other build systems.
The UpdateSettings element is used to tell the system when to check for updates and whether to force the user to update. The full schema reference, including the supported namespaces for each version of Windows 10, can be found in the docs at bit.ly/2TGWnCR.
If you add the .appinstaller file to the packaging project and set its Package Action property to Content and the Copy to Output Directory property to Copy if newer, you can then add another PowerShell task to the YAML file that updates the Version attributes of the root and MainPackage elements and saves the updated file to the staging directory:
You’d then distribute the .appinstaller file to your end users and let them double-click on this one instead of the .msix file to install the packaged app.
Continuous Deployment
The app installer file itself is an uncompiled XML file that can be edited after the build, if required. This makes it easy to use when you deploy your software to multiple environments and when you want to separate the build pipeline from the release process.
If you create a release pipeline in the Azure Portal using the “Empty job” template and use the recently set up build pipeline as the source of the artifact to be deployed, you can then add the PowerShell task to the release stage in order to dynamically change the values of the two Uri attributes in the .appinstaller file to reflect the location to which the app is published.
A Release Pipeline Task That Modifies the Uris in the .appinstaller File
In the task above, the URI is set to the UNC path of an Azure file share. Because this is where the OS will look for the MSIX package when you install and update the app, I’ve also added another command-line script to the release pipeline that first maps the file share in the cloud to the local Z:\ drive on the build agent before it uses the xcopy command to copy the .appinstaller and .msix files there:
yml
- script:|
net use Z: \\filesharestorageccount.file.core.windows.net\myfileshare
/u:AZURE\filesharestorageccount
3PTYC+ociHIwNgCnyg7zsWoKBxRmkEc4Aew4FMzbpUl/
dydo/3HVnl71XPe0uWxQcLddEUuq0fN8Ltcpc0LYeg==
xcopy $(System.DefaultWorkingDirectory)\_MsixDesktopApp\drop Z:\ /Y
displayName:'Publish App Installer File and MSIX package'
If you host your own on-premises Azure DevOps Server, you may of course publish the files to your own internal network share.
If you choose to publish to a Web server, you can tell MSBuild to generate a versioned .appinstaller file and an HTML page that contains a download link and some information about the packaged app by supplying a few additional arguments in the YAML file:
If you set up a release pipeline that publishes the contents of the drop folder to your intranet or any other Web site, and the Web server supports byte-range requests and is configured properly, your end users can use this link to directly install the app without downloading the MSIX package first.
Note
The ability to use the ms-appinstaller URI (Uniform Resource Identifier) scheme (protocol) can be controlled by an IT professional (an administrator). To enable ms-appinstaller on your network, set the Group Policy EnableMSAppInstallerProtocol (/windows/client-management/mdm/policy-csp-desktopappinstaller) to enabled (see Policy CSP - DesktopAppInstaller). For more info, see Installing Windows 10 apps from a web page.
This module explores deployment options for containerized apps and delves into the features of Azure DevOps and Azure Pipelines. It guides users in setting up automated pipelines for container apps, covering agent pool configuration and secret variables management.