XamlNexus release policy
September 15, 2026 ยท View on GitHub
Releases are driven by pull requests merged into main. The workflow uses a push trigger because NuGet Trusted Publishing rejects pull_request_target. It resolves the merged PR associated with the pushed commit and reads its labels and description. Direct pushes without a matching merged PR skip publishing; feature branch pushes do not trigger the workflow.
Repository setup
Create these labels:
release:stablerelease:previewrelease:nonerelease:retry(supplemental label for retrying an unpublished version)
Configure NuGet Trusted Publishing:
- On nuget.org, create a trusted publishing policy for repository owner
PaperHammer, repositoryXamlNexus, and workflow filerelease-merged-pull-request.yml(filename only). - Set the policy environment to
production, matching the release job's GitHub environment. Grant publishing permission for theXamlNexuspackage to the appropriate package owner. - In GitHub Settings > Secrets and variables > Actions, add a repository secret named
NUGET_USERcontaining your nuget.org username (profile name, not email address).
The release job requests an OIDC token and uses NuGet/login@v1 to obtain a temporary API key immediately before uploading. A stored NUGET_API_KEY is no longer required. Keep the environment name consistent between the job and the NuGet policy.
Protect main and require:
- changes to arrive through pull requests;
- the
Validate pull requeststatus check; - resolved review conversations;
- no force pushes or branch deletion.
The release job uses the GitHub production environment. Configure its protection rules under Settings > Environments; required reviewers are optional and will pause the job for approval if enabled. Publishing-labeled PRs publish after merge and any required environment approval; PRs without a release label do not publish.
Publishing pull requests
- Set
Version,AssemblyVersion, andPackageVersioninsrc/XamlNexus/XamlNexus.csprojfor the release. Normally the version must exceed the base branch version. If that version was merged but publishing never completed, addrelease:retryto permit the same version. Downgrades are always rejected. Existing tags block new publishing PRs; only rerunning the release for the same commit may reuse a tag. - Apply exactly one publishing channel:
release:stableorrelease:preview. The optionalrelease:retrylabel must accompany one of these; it cannot be used alone or withrelease:none. - Write user-visible changes in the PR description. The entire description becomes the GitHub Release body; no special markers are required. Put review-only details in PR comments instead.
- Merge the pull request into
mainafter validation succeeds.
Stable labels require a stable semantic version such as 1.2.0. Preview labels require a prerelease version such as 1.3.0-preview.1.
The merged workflow checks out the exact merge commit, rebuilds and tests the solution, creates the .NET tool package, pushes it to NuGet, and creates the corresponding GitHub Release. Existing tags are reused only when they already point to the same merge commit, which makes a partially failed release safe to rerun without moving a published tag.
Non-publishing pull requests
Omit release labels or use release:none. Other labels (such as bug) do not trigger publishing. The project version does not need to change, and the merged workflow exits without accessing publishing secrets.