In the previous post, I described how to use Windows Packaging Project in Visual Studio to build a MSIX package manually.
I also mentioned the difference between running the application normally (when your WPF/WinForms app project is marked as a startup project) and running the application from a package (when the package project is the startup project).
For normal development, you’d ll be probably running the application normally, but it is useful to have the opportunity to test the package directly from the Visual Studio – there may be tiny differences between these two modes.
Once your application is ready, you’ll want to distribute it to the end users. Commonly there is also a small group of “beta testers” or “early adpoters” who’ll want to get preview releases. You may also want to have internal builds.
Therefore, we can create several release channels:
Since the Dev version will not go through the CI/CD process, let’s update the Package manifest to be the manifest for the Dev version.
When you set the Package project as a startup project and run it, the application should install automatically in the Start menu.
I am using Azure DevOps which is a natural choice for most .NET developers. However, if you prefer any other CI/CD solution, don’t worry – everything we’ll do can be automated using command line tools, and Azure DevOps only provides UI for these operations.
I have created a new Build pipeline using the new YAML pipelines. They don’t have such comfortable UI as the classic pipelines, but they store the entire pipeline together with the source code and can be versioned with full utilization of branches, which is super-important in larger projects because the structure of the solution evolves over time, there are always some new components and so on.
If you store your source codes within Azure Repos, it is the easiest way. If your repo is elsewhere (External Git, SVN), choose the appropriate option.
My sample project is on GitHub, so I am choosing it.
On the next step, I’ve selected the repository and authenticated with my GitHub account.
Now select .NET Desktop even if your app is in .NET Core – we’ll remove most of the code anyway:
Azure DevOps now opens the YAML editor you can use to define your build process.
Our process consists of 3 steps:
Since we want to have the Preview and Production consistent, we’ll build both within the same build from the same sommit. Thanks to this, when you make sure that the Preview version is working, you can publish the same source code as a stable version.
The YAML file starts with the following code:
trigger:
- master
pool:
vmImage: 'windows-latest'
variables:
solution: '**/*.sln'
buildPlatform: 'x86'
buildConfiguration: 'Release'
msixInstallUrl: https://wugdaysdemoapp.azurewebsites.net
packageVersion: 1.0.0
packageName: 'WUG Days Demo App'
jobs:
- job: BuildMSIX
strategy:
matrix:
Preview:
channelName: 'preview'
packageIdSuffix: '-preview'
packageNameSuffix: ' [PREVIEW]'
Production:
channelName: 'production'
packageIdSuffix: ''
packageNameSuffix: ''
steps:
- task: PowerShell@2
inputs:
targetType: 'inline'
script: |
[xml]$manifest= get-content ".\src\WpfCoreDemo.Package\Package.appxmanifest"
$manifest.Package.Identity.Version = "$(packageVersion).$(Build.BuildId)"
$manifest.Package.Identity.Name = "demo-864d9095-955f-4d3c-adb0-6574a5acb88b$(packageIdSuffix)"
$manifest.Package.Properties.DisplayName = "$(packageName)$(packageNameSuffix)"
$manifest.Package.Applications.Application.VisualElements.DisplayName = "$(packageName)$(packageNameSuffix)"
$manifest.save(".\src\WpfCoreDemo.Package\Package.appxmanifest")
- task: VSBuild@1
inputs:
solution: '$(solution)'
msbuildArgs: '/restore /p:AppInstallerUri=$(msixInstallUrl)/$(channelName) /p:AppxPackageDir="$(Build.ArtifactStagingDirectory)/$(channelName)" /p:UapAppxPackageBuildMode=SideLoadOnly /p:GenerateAppInstallerFile=true'
platform: '$(buildPlatform)'
configuration: '$(buildConfiguration)'
- task: PublishBuildArtifacts@1
inputs:
PathtoPublish: '$(Build.ArtifactStagingDirectory)'
ArtifactName: 'drop'
publishLocation: 'Container'
In the rest of the file, we define the build tasks:
When the build finishes, your packages will be published in the drop artifact:
You can see that there are two folders in the artifact, and each holds the index.html page, the app installer file and a versioned folder with the MSIX package itself.
That’s for building the packages. In the next post, I’ll show how to release the packages.