Skip to content

Commit c286985

Browse files
authored
Merge pull request #245 from Krypton-Suite/alpha-github-workflow-canary-lts-release
Alpha GitHub workflow canary lts release
2 parents 3a7cc0a + d2aed6f commit c286985

182 files changed

Lines changed: 13850 additions & 16575 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
Lines changed: 305 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,305 @@
1+
# New BSD 3-Clause License (https://github.com/Krypton-Suite/Standard-Toolkit/blob/master/LICENSE)
2+
# Modifications by Peter Wagner (aka Wagnerp), Simon Coghlan (aka Smurf-IV), tobitege et al. 2026 - 2026. All rights reserved.
3+
#
4+
# Build and release Canary LTS NuGet packages. Only runs on the V105-LTS branch.
5+
# KILL-SWITCH: Set repository variable CANARY_LTS_DISABLED=true to disable.
6+
# Location: Repository Settings → Secrets and variables → Actions → Variables tab
7+
8+
name: Canary LTS Release
9+
10+
on:
11+
push:
12+
branches:
13+
- V105-LTS
14+
workflow_dispatch:
15+
16+
jobs:
17+
canary-lts-release:
18+
runs-on: windows-latest
19+
if: github.ref == 'refs/heads/V105-LTS' && (github.event_name == 'push' || github.event_name == 'workflow_dispatch')
20+
21+
steps:
22+
- name: Canary LTS Release Kill Switch Check
23+
id: canary_lts_kill_switch
24+
shell: pwsh
25+
run: |
26+
$ErrorActionPreference = 'Stop'
27+
$disabled = '${{ vars.CANARY_LTS_DISABLED }}'
28+
29+
if ($disabled -eq 'true') {
30+
Write-Host "::warning:: Canary LTS Release workflow is currently DISABLED via kill switch (CANARY_LTS_DISABLED=true)"
31+
Write-Host "To re-enable: Go to Repository Settings -> Secrets and Variables -> Actions -> Variables -> Set CANARY_LTS_DISABLED to 'false'."
32+
echo "enabled=false" >> $env:GITHUB_OUTPUT
33+
} else {
34+
Write-Host "Canary LTS Release kill switch check has passed, continuing..."
35+
echo "enabled=true" >> $env:GITHUB_OUTPUT
36+
}
37+
38+
- name: Checkout
39+
if: steps.canary_lts_kill_switch.outputs.enabled == 'true'
40+
uses: actions/checkout@v6
41+
42+
- name: Setup .NET
43+
if: steps.canary_lts_kill_switch.outputs.enabled == 'true'
44+
uses: actions/setup-dotnet@v5
45+
with:
46+
dotnet-version: |
47+
9.0.x
48+
10.0.x
49+
50+
- name: Setup .NET 11 (Preview)
51+
if: steps.canary_lts_kill_switch.outputs.enabled == 'true'
52+
uses: actions/setup-dotnet@v5
53+
with:
54+
dotnet-version: 11.0.x
55+
dotnet-quality: preview
56+
57+
- name: Force .NET 11 SDK via global.json
58+
if: steps.canary_lts_kill_switch.outputs.enabled == 'true'
59+
run: |
60+
$sdkVersion = (dotnet --list-sdks | Select-String "11.0").ToString().Split(" ")[0]
61+
Write-Output "Using SDK $sdkVersion"
62+
@"
63+
{
64+
"sdk": {
65+
"version": "$sdkVersion",
66+
"rollForward": "latestFeature"
67+
}
68+
}
69+
"@ | Out-File -Encoding utf8 global.json
70+
71+
- name: Setup MSBuild
72+
if: steps.canary_lts_kill_switch.outputs.enabled == 'true'
73+
uses: microsoft/setup-msbuild@v2
74+
with:
75+
msbuild-architecture: x64
76+
77+
- name: Setup NuGet
78+
if: steps.canary_lts_kill_switch.outputs.enabled == 'true'
79+
uses: NuGet/setup-nuget@v2.0.1
80+
81+
- name: Cache NuGet
82+
if: steps.canary_lts_kill_switch.outputs.enabled == 'true'
83+
uses: actions/cache@v5
84+
with:
85+
path: ~/.nuget/packages
86+
key: ${{ runner.os }}-nuget-${{ hashFiles('**/*.csproj') }}
87+
restore-keys: |
88+
${{ runner.os }}-nuget-
89+
90+
- name: Setup WebView2 SDK
91+
if: steps.canary_lts_kill_switch.outputs.enabled == 'true'
92+
shell: pwsh
93+
run: |
94+
if (-not (Test-Path "WebView2SDK")) { mkdir WebView2SDK }
95+
$packageId = "Microsoft.Web.WebView2"
96+
$latestVersion = $null
97+
try {
98+
$searchUrl = "https://azuresearch-usnc.nuget.org/query?q=$packageId&prerelease=false&semVerLevel=2.0.0&take=1"
99+
$searchResponse = Invoke-RestMethod -Uri $searchUrl -Method Get
100+
if ($searchResponse.data -and $searchResponse.data.Count -gt 0) {
101+
$latestVersion = $searchResponse.data[0].version
102+
}
103+
} catch {
104+
try {
105+
$apiUrl = "https://api.nuget.org/v3-flatcontainer/$packageId/index.json"
106+
$response = Invoke-RestMethod -Uri $apiUrl -Method Get
107+
if ($response.versions) {
108+
$stableVersions = $response.versions | Where-Object { $_ -notmatch '[-]' -and $_ -match '^\d+\.\d+\.\d+$' }
109+
if ($stableVersions) {
110+
$latestVersion = $stableVersions | Sort-Object { [System.Version]$_ } -Descending | Select-Object -First 1
111+
}
112+
}
113+
} catch {}
114+
}
115+
if (-not $latestVersion) { $latestVersion = "1.0.3595.46" }
116+
Write-Host "Using WebView2 SDK version: $latestVersion"
117+
dotnet add "Source/Current/Krypton Components/Krypton.Utilities/Krypton.Utilities.csproj" package Microsoft.Web.WebView2 --version $latestVersion
118+
dotnet restore "Source/Current/Krypton Components/Krypton.Utilities/Krypton.Utilities.csproj"
119+
$nugetBasePath = "$env:USERPROFILE\.nuget\packages\microsoft.web.webview2\$latestVersion"
120+
$coreDll = Get-ChildItem -Path $nugetBasePath -Recurse -Name "Microsoft.Web.WebView2.Core.dll" | Select-Object -First 1
121+
Copy-Item (Join-Path $nugetBasePath $coreDll) "WebView2SDK\"
122+
$winFormsDll = Get-ChildItem -Path $nugetBasePath -Recurse -Name "Microsoft.Web.WebView2.WinForms.dll" | Select-Object -First 1
123+
Copy-Item (Join-Path $nugetBasePath $winFormsDll) "WebView2SDK\"
124+
$loaderDll = Get-ChildItem -Path $nugetBasePath -Recurse -Name "WebView2Loader.dll" | Select-Object -First 1
125+
Copy-Item (Join-Path $nugetBasePath $loaderDll) "WebView2SDK\"
126+
dotnet remove "Source/Current/Krypton Components/Krypton.Utilities/Krypton.Utilities.csproj" package Microsoft.Web.WebView2
127+
128+
- name: Restore
129+
if: steps.canary_lts_kill_switch.outputs.enabled == 'true'
130+
run: dotnet restore "Source/Current/Krypton Components/Krypton Toolkit Suite 2022 - VS2022.slnx"
131+
132+
- name: Prepare Code Signing Certificate (Optional)
133+
if: steps.canary_lts_kill_switch.outputs.enabled == 'true'
134+
id: prepare_cert
135+
shell: pwsh
136+
run: |
137+
$ErrorActionPreference = 'Continue'
138+
if ($env:AUTHENTICODE_CERT_BASE64) {
139+
Write-Host "Preparing Authenticode signing certificate..."
140+
$certBytes = [Convert]::FromBase64String($env:AUTHENTICODE_CERT_BASE64)
141+
$certPath = "$env:RUNNER_TEMP\codesign.pfx"
142+
[System.IO.File]::WriteAllBytes($certPath, $certBytes)
143+
Write-Host "Certificate saved to: $certPath"
144+
echo "cert_path=$certPath" >> $env:GITHUB_OUTPUT
145+
echo "cert_available=true" >> $env:GITHUB_OUTPUT
146+
} else {
147+
Write-Host "Authenticode certificate not provided - signing will be skipped"
148+
echo "cert_available=false" >> $env:GITHUB_OUTPUT
149+
}
150+
env:
151+
AUTHENTICODE_CERT_BASE64: ${{ secrets.AUTHENTICODE_CERT_BASE64 }}
152+
153+
- name: Build Canary
154+
if: steps.canary_lts_kill_switch.outputs.enabled == 'true'
155+
shell: pwsh
156+
run: |
157+
$ErrorActionPreference = 'Stop'
158+
$buildArgs = 'Scripts/Build/canary.proj /t:Build /p:Configuration=Canary /p:Platform="Any CPU"'
159+
160+
if (${{ steps.prepare_cert.outputs.cert_available }} -eq 'true') {
161+
$buildArgs += ' /p:EnableAuthenticodeSigning=true'
162+
$buildArgs += " /p:AuthenticodeCertificatePath=`"${{ steps.prepare_cert.outputs.cert_path }}`""
163+
if ($env:AUTHENTICODE_CERT_PASSWORD) {
164+
$buildArgs += " /p:AuthenticodeCertificatePassword=`"$env:AUTHENTICODE_CERT_PASSWORD`""
165+
}
166+
Write-Host "Building with Authenticode signing enabled"
167+
} else {
168+
Write-Host "Building without Authenticode signing"
169+
}
170+
171+
msbuild $buildArgs
172+
env:
173+
AUTHENTICODE_CERT_PASSWORD: ${{ secrets.AUTHENTICODE_CERT_PASSWORD }}
174+
175+
- name: Pack Canary
176+
if: steps.canary_lts_kill_switch.outputs.enabled == 'true'
177+
run: msbuild "Scripts/Build/canary.proj" /t:Pack /p:Configuration=Canary /p:Platform="Any CPU"
178+
179+
- name: Push NuGet Packages to nuget.org
180+
if: steps.canary_lts_kill_switch.outputs.enabled == 'true'
181+
id: push_nuget
182+
shell: pwsh
183+
run: |
184+
$ErrorActionPreference = 'Stop'
185+
if (-not $env:NUGET_API_KEY) {
186+
Write-Warning "NUGET_API_KEY not set - skipping NuGet push"
187+
echo "packages_published=false" >> $env:GITHUB_OUTPUT
188+
exit 0
189+
}
190+
191+
$packages = Get-ChildItem "Artefacts/Packages/Canary/*.nupkg" -ErrorAction SilentlyContinue
192+
$publishedAny = $false
193+
194+
if ($packages) {
195+
foreach ($package in $packages) {
196+
Write-Output "Pushing Canary LTS package: $($package.Name)"
197+
try {
198+
$output = dotnet nuget push "$($package.FullName)" --api-key $env:NUGET_API_KEY --source https://api.nuget.org/v3/index.json --skip-duplicate 2>&1 | Out-String
199+
Write-Output $output
200+
if ($output -notmatch "already exists" -and $output -notmatch "was not pushed") {
201+
$publishedAny = $true
202+
Write-Host "Package $($package.Name) was published"
203+
} else {
204+
Write-Host "Package $($package.Name) already exists - skipped"
205+
}
206+
} catch {
207+
Write-Warning "Failed to push $($package.Name): $_"
208+
}
209+
}
210+
} else {
211+
Write-Output "No NuGet packages found to push"
212+
}
213+
214+
echo "packages_published=$publishedAny" >> $env:GITHUB_OUTPUT
215+
env:
216+
NUGET_API_KEY: ${{ secrets.NUGET_API_KEY }}
217+
218+
- name: Get Version
219+
if: steps.canary_lts_kill_switch.outputs.enabled == 'true'
220+
id: get_version
221+
shell: pwsh
222+
run: |
223+
$ErrorActionPreference = 'Stop'
224+
$version = $null
225+
226+
try {
227+
$dllPath = Get-ChildItem "Artefacts/Canary/net48/Krypton.Toolkit.dll" -ErrorAction Stop
228+
$assemblyVersion = [System.Reflection.AssemblyName]::GetAssemblyName($dllPath.FullName).Version
229+
$version = $assemblyVersion.ToString()
230+
Write-Host "Got version from assembly: $version"
231+
} catch {
232+
Write-Host "Could not read version from assembly: $_"
233+
}
234+
235+
if (-not $version) {
236+
try {
237+
$proj = 'Source/Current/Krypton Components/Krypton.Toolkit/Krypton.Toolkit 2022.csproj'
238+
[xml]$projXml = Get-Content $proj
239+
$versionNode = $projXml.SelectSingleNode("//Version")
240+
if ($versionNode) {
241+
$version = $versionNode.InnerText.Trim()
242+
Write-Host "Got version from csproj: $version"
243+
}
244+
} catch {
245+
Write-Host "Could not read version from csproj: $_"
246+
}
247+
}
248+
249+
if (-not $version) {
250+
Write-Warning "Version not found, using fallback."
251+
$version = "100.25.1.1"
252+
}
253+
254+
Write-Host "Final determined version: $version"
255+
echo "version=$version" >> $env:GITHUB_OUTPUT
256+
echo "tag=v$version-canary-lts" >> $env:GITHUB_OUTPUT
257+
258+
- name: Announce Canary LTS Release on Discord
259+
if: steps.canary_lts_kill_switch.outputs.enabled == 'true' && steps.push_nuget.outputs.packages_published == 'True'
260+
shell: pwsh
261+
run: |
262+
if (-not $env:DISCORD_WEBHOOK_CANARY) {
263+
Write-Warning "DISCORD_WEBHOOK_CANARY not set - skipping Discord notification"
264+
exit 0
265+
}
266+
267+
$payload = @{
268+
embeds = @(
269+
@{
270+
title = "🐤 Krypton Toolkit Canary LTS Release"
271+
description = "A new canary pre-release from the V105-LTS branch is now available!"
272+
color = 16776960
273+
fields = @(
274+
@{
275+
name = "📌 Version"
276+
value = "``${{ steps.get_version.outputs.version }}``"
277+
inline = $true
278+
}
279+
@{
280+
name = "🌿 Branch"
281+
value = "V105-LTS"
282+
inline = $true
283+
}
284+
@{
285+
name = "📦 NuGet Packages"
286+
value = "• [Krypton.Toolkit.Canary](https://www.nuget.org/packages/Krypton.Toolkit.Canary)`n• [Krypton.Ribbon.Canary](https://www.nuget.org/packages/Krypton.Ribbon.Canary)`n• [Krypton.Navigator.Canary](https://www.nuget.org/packages/Krypton.Navigator.Canary)`n• [Krypton.Workspace.Canary](https://www.nuget.org/packages/Krypton.Workspace.Canary)`n• [Krypton.Docking.Canary](https://www.nuget.org/packages/Krypton.Docking.Canary)`n• [Krypton.Standard.Toolkit.Canary](https://www.nuget.org/packages/Krypton.Standard.Toolkit.Canary)"
287+
inline = $false
288+
}
289+
@{
290+
name = "📄 Release Notes"
291+
value = "[View Changelog](https://github.com/Krypton-Suite/Standard-Toolkit/blob/V105-LTS/Documents/Changelog/Changelog.md)"
292+
inline = $false
293+
}
294+
)
295+
footer = @{
296+
text = "Canary LTS (V105-LTS)"
297+
}
298+
timestamp = (Get-Date).ToUniversalTime().ToString("yyyy-MM-ddTHH:mm:ss.fffZ")
299+
}
300+
)
301+
} | ConvertTo-Json -Depth 10
302+
303+
Invoke-RestMethod -Uri "${{ secrets.DISCORD_WEBHOOK_CANARY }}" -Method Post -Body $payload -ContentType "application/json"
304+
env:
305+
DISCORD_WEBHOOK_CANARY: ${{ secrets.DISCORD_WEBHOOK_CANARY }}

AGENTS.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
- `Source/Testing/Krypton Components/TestForm`: WinForms sample app used to validate changes
1313
- `Source/Testing/TestHarnesses`: Small repro/test harnesses (e.g., `ThemeSwapRepro`)
1414
- `Scripts//Testing/`: Build and packaging scripts (`build-stable.cmd`, `build-canary.cmd`, `build-nightly.cmd`, `build.proj`)
15-
- `Artefacts/`: Build outputs by configuration (e.g., `Artefacts/Debug`)
15+
- `Artefacts/`: Build outputs ( .NET 8+ centralized layout: `bin/`, `obj/`, `package/`, `publish/` under `Artefacts/`)
1616
- `Documents/`, `Assets/`, `Logs/`: Docs, images, and build logs
1717

1818
## Build, Test, and Development Commands
@@ -22,7 +22,7 @@
2222
- `dotnet run --project "Source/Testing/Krypton Components/TestForm/TestForm.csproj" -c Debug`
2323
- Preset builds (Windows cmd):
2424
- `Scripts/Testing/build-stable.cmd` | `Scripts/Testing/build-canary.cmd` | `Scripts/Testing/build-nightly.cmd`
25-
- Outputs land in `Artefacts/<Configuration>/`. Supported TFMs include `net472`, `net48`, `net481`, `net8.0-windows`, `net9.0-windows`, `net10.0-windows`, `net11.0-windows`
25+
- Outputs land in `Artefacts/bin/<ProjectName>/<Pivot>/`; NuGet packages in `Artefacts/package/<Configuration>/`. Supported TFMs include `net472`, `net48`, `net481`, `net8.0-windows`, `net9.0-windows`, `net10.0-windows`, `net11.0-windows`
2626

2727
## Coding Style & Naming Conventions
2828
- Line endings/encoding: CRLF, UTF-8 with BOM

Directory.Build.props

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,10 @@
11
<Project>
2+
<!-- .NET 8+ centralized artifacts output (see https://learn.microsoft.com/en-us/dotnet/core/sdk/artifacts-output) -->
3+
<PropertyGroup>
4+
<UseArtifactsOutput>true</UseArtifactsOutput>
5+
<ArtifactsPath>$(MSBuildThisFileDirectory)Artefacts</ArtifactsPath>
6+
</PropertyGroup>
7+
28
<Choose>
39
<When Condition="'$(Configuration)' == 'Canary'">
410
<PropertyGroup>

0 commit comments

Comments
 (0)