release.yml Developer Guide
Authoritative documentation for .github/workflows/release.yml, which coordinates production and pre-release promotions for pushes to master, alpha, canary, and V105-LTS (see the workflow on.push.branches list for the current set).
Quick Reference
| Branch | Job Id | Runner | Build Script | Kill Switch Variable | Discord Webhook |
|---|---|---|---|---|---|
master |
release-master |
windows-2025-vs2026 |
Scripts/Build/build.proj (Build/Pack) |
vars.RELEASE_DISABLED |
secrets.DISCORD_WEBHOOK_MASTER |
V105-LTS |
release-v105-lts |
windows-2025-vs2026 |
Scripts/Build/build.proj |
vars.RELEASE_DISABLED |
secrets.DISCORD_WEBHOOK_MASTER |
canary |
release-canary |
windows-2025-vs2026 |
Scripts/Build/canary.proj |
vars.CANARY_DISABLED |
secrets.DISCORD_WEBHOOK_CANARY |
alpha |
release-alpha |
windows-2025-vs2026 |
Scripts/Build/nightly.proj |
vars.NIGHTLY_DISABLED |
secrets.DISCORD_WEBHOOK_NIGHTLY |
Common characteristics:
- Every job runs only when the push target matches its branch and the corresponding kill switch reports
enabled=true. - SDK setup: install .NET 9.0.x and 10.0.x. Jobs that publish preview TFMs also run Setup .NET Preview (unless repository variable
USE_DOTNET_PREVIEWisfalse) and Pin SDK via global.json, which resolvessdk.versionusingDOTNET_PREVIEW_SDK_BAND/Get-ListedSdkVersionwhen preview is enabled, or stable 10.x → 9.x when preview is disabled (see GitHub Actions Workflows). - The
release-v105-ltsjob pins stable SDKs only (no preview setup step). - Orchestrated Build and Pack steps pass
/p:UseArtifactsOutput=true, so outputs go underartifacts/bin/andartifacts/packages/on the runner. Push and Get Version steps tryartifacts/...first, then fall back to legacyBin/...for compatibility with older layouts or local debugging. - Package publishing relies on
secrets.NUGET_API_KEY.
Kill Switches
- Stored under Repository Settings → Actions → Variables.
- Each job exits early if its switch evaluates to
'true', logging a warning that includes remediation steps. - When disabled, the pipeline still shows as successful but with most steps skipped, making it clear releases are paused intentionally.
Job Deep Dive
1. release-master (Stable)
Trigger: push to master.
- Release Kill Switch Check (
vars.RELEASE_DISABLED)- Emits
enabledoutput consumed by every subsequent step.
- Emits
- Checkout + SDK setup + Pin SDK via global.json + tooling
- Setup .NET (9.0.x / 10.0.x), optional Setup .NET Preview when
USE_DOTNET_PREVIEWis notfalse, then Pin SDK via global.json (preview band or stable per variables).
- Setup .NET (9.0.x / 10.0.x), optional Setup .NET Preview when
- Restore, Build, Pack via
Scripts/Build/build.projwith/p:UseArtifactsOutput=true. - Push NuGet Packages
- Collects
artifacts/packages/Release/*.nupkgandBin/Packages/Release/*.nupkg. - Uses
dotnet nuget push ... --skip-duplicate. - Records
packages_publishedoutput for notification gating.
- Collects
- Get Version
- Prefers
artifacts/bin/Release/net48/Krypton.Toolkit.dll, thenBin/Release/net48/Krypton.Toolkit.dll. - Falls back to
Krypton.Toolkit 2022.csproj<Version>or default100.25.1.1.
- Prefers
- Announce Release on Discord (if packages published and webhook present)
- Posts embed with version, package list, TFM coverage, and nuget.org links.
2. release-v105-lts (105 LTS line)
Trigger: push to V105-LTS.
Same overall pipeline as release-master, but:
- Discord: uses
DISCORD_WEBHOOK_MASTER(same secret as master). - SDK: installs 9.0.x / 10.0.x and Pin SDK via global.json using stable 10.x → 9.x only (no Setup .NET Preview step in this job).
3. release-canary (Canary channel)
Highlights:
- Kill switch
vars.CANARY_DISABLED. - Build/Pack uses
Scripts/Build/canary.projwithConfiguration=Canaryand/p:UseArtifactsOutput=true. - Packages:
artifacts/packages/Canary/thenBin/Packages/Canary/. Binaries for version:artifacts/bin/Canary/net48/Krypton.Toolkit.dllthenBin/Canary/net48/Krypton.Toolkit.dll; fallback100.25.1.1. - Discord uses
DISCORD_WEBHOOK_CANARYand points to.Canarynuget.org packages.
4. release-alpha (Nightly/alpha channel)
Characteristics:
- Kill switch
vars.NIGHTLY_DISABLED. - Uses
Scripts/Build/nightly.projwithConfiguration=Nightlyand/p:UseArtifactsOutput=true. - Produces packages under
artifacts/packages/Nightly/(withBin/Packages/Nightly/as fallback for discovery scripts). - Discord uses
DISCORD_WEBHOOK_NIGHTLY, referencing.Nightlypackages. NuGet publishing for scheduled alpha/nightly drops may also be handled bynightly.yml; see that workflow for schedule-driven pushes.
Shared step details
SDK and global.json
Workflow steps named Pin SDK via global.json run PowerShell that:
- Lists SDKs with
dotnet --list-sdks. - Chooses a version via
Get-ListedSdkVersion(matches the scripts in.github/workflows/release.yml). - Writes repo-root
global.jsonwith"rollForward": "latestFeature".
Preview vs stable selection is driven by repository variables USE_DOTNET_PREVIEW, DOTNET_PREVIEW_SETUP_VERSION, and DOTNET_PREVIEW_SDK_BAND (see GitHub Actions Workflows).
NuGet publishing logic
- Packages iterate serially; failures log warnings but do not fail the workflow (resilience for flaky pushes).
- Successful pushes toggle
$publishedAnyto$true, which determines whether Discord announcements run. - Missing
NUGET_API_KEYskips publishing gracefully; ensure repo secrets are populated before enabling release branches.
Version Discovery
Priority order:
- Assembly version via
[System.Reflection.AssemblyName]::GetAssemblyName(...). <Version>node fromKrypton.Toolkit 2022.csproj.- Hard-coded fallback (channel-specific).
Outputs version and tag, enabling downstream release automation or manual tagging.
Extending the Workflow
- New Release Channel: Duplicate a job, change branch filter, update kill switch variable name, and point to the correct MSBuild project and Discord webhook.
- Custom Notifications: Add steps after
Announce ...conditioned on the same outputs (packages_published+ kill switch). - Artifact Sharing: Insert
actions/upload-artifactafter pack steps if packages must be inspected before publishing. - Telemetry: Wrap
dotnetcommands with additional logging by piping toTee-Objector storing logs inLogs/.
Troubleshooting Playbook
| Symptom | Diagnosis | Action |
|---|---|---|
| Job skipped entirely | Branch mismatch or kill switch true |
Verify github.ref and repository variables. |
dotnet nuget push failing with 403 |
Expired or missing NUGET_API_KEY |
Rotate key in repo secrets; rerun job. |
| Discord step skipped | packages_published=false or missing webhook secret |
Confirm packages actually produced, check secret names. |
| Version fallback used unexpectedly | Assembly or csproj not accessible | Ensure build outputs exist under artifacts/bin/... or Bin/...; confirm UseArtifactsOutput matches the layout you expect. |
Operational Checklist
- [ ] Confirm kill switch variable is
falsebefore triggering releases. - [ ] Monitor package push logs for
already existsmessages; duplicates are expected on reruns. - [ ] Validate Discord message in the target channel after publication.
- [ ] Tag repository manually if you rely on the
get_versionoutput for git tagging.