docs/ReleaseProcess.md
This document describes the .NET MAUI release process, which uses the Arcade SDK for building packages and publishing them to NuGet.org and Workload Set channels.
The .NET MAUI release process consists of two main phases:
azure-pipelines-internal.ymlmaui-release-internal.ymlThis process leverages the .NET Arcade infrastructure, which is a set of shared tools and services used across the .NET ecosystem to standardize build processes, dependency management, and package publishing.
azure-pipelines-internal.yml)The azure-pipelines-internal.yml pipeline is responsible for building, packing, and signing the .NET MAUI packages and workloads. This pipeline runs automatically on a schedule (daily at 5:00 UTC) for the main branch and is also triggered on commits to main, release branches, and tags. The pipeline runs in the internal Azure DevOps environment (dnceng/internal) where it has access to signing certificates and secured resources.
Source Provisioning: Sets up the build environment with necessary dependencies like Android SDKs.
Build: Builds the .NET MAUI projects in the repository.
Pack: Creates NuGet packages for the .NET MAUI libraries.
Sign: Signs the packages with Microsoft's certificate (only on official internal builds).
Build Workloads: Constructs the workload manifests and packages required for the .NET MAUI SDK.
Publish to BAR: After successful build and pack, the packages' metadata are published to the Build Asset Registry (BAR) in Maestro, which is used by the .NET SDK to consume these packages.
maui-release-internal.yml)The maui-release-internal.yml pipeline is responsible for taking the packed artifacts and publishing them to the appropriate channels. This pipeline is not automatically triggered and must be manually run. Like the build pipeline, it also runs in the internal Azure DevOps environment where it has access to the necessary API keys and secured resources.
Publish to Workload Set Channel:
Release Packs:
Release Manifests:
The release pipeline accepts several parameters:
commitHash: The commit hash to download NuGet packages frompushWorkloadSet: Whether to publish to the Workload Set channelpushNugetOrg: Whether to push to NuGet.orgpushPackages: Controls if packages are actually pushed (allows for dry runs)nugetIncludeFilters and nugetExcludeFilters: Filters for controlling which packages are publishedThe complete release process follows these steps:
Build and package using azure-pipelines-internal.yml
Determine the commit hash of the build to be released
Run the maui-release-internal.yml pipeline with:
The release pipeline uses Darc to:
The release pipeline will then:
The packages are now available for consumption via:
The .NET MAUI release process operates using two repositories:
Public GitHub Repository: https://github.com/dotnet/maui
Internal Azure DevOps Mirror: https://dev.azure.com/dnceng/internal/_git/dotnet-maui
azure-pipelines-internal.yml and maui-release-internal.yml pipelines run against this mirrorThe use of the internal mirror ensures that the signing process and access to internal feeds are properly secured while still maintaining an open-source development model in the public repository. Changes are synchronized from the public repository to the internal mirror, ensuring that the released packages contain the same code that is publicly visible.
Arcade is Microsoft's .NET Core engineering system, providing shared tools, SDK, and services for .NET repository builds. Arcade standardizes:
Darc is a tool within the Arcade infrastructure used to manage dependencies and coordinate asset reuse across the .NET ecosystem. In the .NET MAUI release process, Darc plays a critical role:
Maestro is the service that maintains the Build Asset Registry (BAR), which serves as the central database tracking all assets (packages, blobs, etc.) produced by .NET builds. The release process uses Maestro to:
The maui-release-internal.yml pipeline uses Darc to:
Find the Build: Using the commit hash parameter, Darc identifies the corresponding build in the BAR.
$buildJson = & $darc get-build --ci --repo "${{ parameters.ghRepo }}" --commit "$(COMMIT)" --output-format json
$barId = $buildJson | ConvertFrom-Json | Select-Object -ExpandProperty "id" -First 1
Gather Assets: Once the BAR ID is obtained, Darc collects all the packages from internal feeds.
& $darc gather-drop --ci --id $barId -o "$(Build.StagingDirectory)\nupkgs" --azdev-pat $(System.AccessToken) --verbose
Channel Association: For workload sets, Darc adds the build to the appropriate workload channel.
& $darc add-build-to-channel --ci --channel "$workloadSetsChannel" --id "$barId" --skip-assets-publishing
Publishing: The gathered packages are then published to NuGet.org and other appropriate channels based on pipeline parameters.