From 3275d197e65672f1170cfe789a4119c38cca31c6 Mon Sep 17 00:00:00 2001 From: James Maes Date: Sun, 8 Nov 2026 07:30:38 -0600 Subject: [PATCH 1/8] ci: build on the shared ci-workflows Windows workflow Locked restore, warnings-as-errors build, dotnet format, core tests with the 100% coverage gate and the PowerShell analyzer/Pester checks run on the KOF Windows host runner; the review-gate scripts lint and test on node.yaml. Co-Authored-By: Claude Opus 5.5 --- .gitea/workflows/build.yaml | 47 +++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) create mode 100644 .gitea/workflows/build.yaml diff --git a/.gitea/workflows/build.yaml b/.gitea/workflows/build.yaml new file mode 100644 index 0000000..b91e641 --- /dev/null +++ b/.gitea/workflows/build.yaml @@ -0,0 +1,47 @@ +name: build +on: + push: + branches: ['**'] + tags: ['v*'] +jobs: + windows: + uses: self:KofTwentyTwo/ci-workflows/.gitea/workflows/windows.yaml@native-workflows + secrets: inherit + with: + commands: | + dotnet restore MarkdownViewr.Windows.slnx -p:Platform=x64 --locked-mode + dotnet build MarkdownViewr.Windows.slnx -p:Platform=x64 -warnaserror --no-restore + # The WinUI app project is built directly so the format workspace can load its generated XAML code. + dotnet build src/MarkdownViewr.Windows/MarkdownViewr.Windows.csproj -p:Platform=x64 -warnaserror --no-restore + $env:Platform = 'x64' + dotnet format MarkdownViewr.Windows.slnx --verify-no-changes --severity warn --no-restore + Remove-Item Env:Platform + dotnet test tests/MarkdownViewr.Windows.Core.Tests --no-build --settings coverage.runsettings --collect:"XPlat Code Coverage" --logger trx --results-directory TestResults + ./build/Assert-Coverage.ps1 -ResultsDirectory TestResults -Packages MarkdownViewr.Windows.Core + # PowerShell build scripts: analyzer and Pester boundary tests with pinned modules saved to the job's temp directory. + $modules = Join-Path ($env:RUNNER_TEMP ?? [IO.Path]::GetTempPath()) "psmodules-$env:GITHUB_RUN_ID" + Save-PSResource -Name PSScriptAnalyzer -Version 1.25.0 -Repository PSGallery -TrustRepository -Path $modules + Save-PSResource -Name Pester -Version 5.7.1 -Repository PSGallery -TrustRepository -Path $modules + Import-Module (Join-Path $modules PSScriptAnalyzer/1.25.0/PSScriptAnalyzer.psd1) + Import-Module (Join-Path $modules Pester/5.7.1/Pester.psd1) + foreach ($file in Get-ChildItem -LiteralPath build -Recurse -File | Where-Object Extension -In '.ps1', '.psm1', '.psd1') { + # Casing runs in its own pass: command metadata races other rules in 1.25.0 (PSScriptAnalyzer#1708). + $findings = @( + Invoke-ScriptAnalyzer -Path $file.FullName -Settings ./PSScriptAnalyzerSettings.psd1 -IncludeRule PSUseCorrectCasing + Invoke-ScriptAnalyzer -Path $file.FullName -Settings ./PSScriptAnalyzerSettings.psd1 -ExcludeRule PSUseCorrectCasing + ) + if ($findings.Count -gt 0) { $findings | Format-Table; throw "Script analysis failed: $($file.Name)" } + } + $pester = New-PesterConfiguration + $pester.Run.Path = @('build/Assert-Coverage.Tests.ps1', 'build/GitHubRepository.Tests.ps1', 'build/Distribution.Tests.ps1', 'build/InstalledUpdates.Tests.ps1', 'build/PackageBytes.Tests.ps1', 'build/ReleaseSigning.Tests.ps1') + $pester.Run.PassThru = $true + if ((Invoke-Pester -Configuration $pester).Result -ne 'Passed') { throw 'Pester tests failed' } + scripts: + uses: self:KofTwentyTwo/ci-workflows/.gitea/workflows/node.yaml@v1 + with: + node-version: '24' + install: npm ci --ignore-scripts + commands: | + npm run lint + npm test + npm audit signatures -- 2.54.0 From 4c7406723c440d05f540701a6a1f4e059ffc24f8 Mon Sep 17 00:00:00 2001 From: James Maes Date: Sun, 8 Nov 2026 07:31:55 -0600 Subject: [PATCH 2/8] build: pin SDK 10.0.403 and refresh the lock files The KOF Windows runner provides SDK 10.0.403, whose implicit ILLink reference is 10.0.14; locked restore failed against the 10.0.12 entries the 10.0.401 pin produced. Co-Authored-By: Claude Opus 5.5 --- global.json | 2 +- src/MarkdownViewr.Windows.Core/packages.lock.json | 8 ++++---- src/MarkdownViewr.Windows/packages.lock.json | 2 +- tests/MarkdownViewr.Windows.Core.Tests/packages.lock.json | 2 +- tests/MarkdownViewr.Windows.UiTests/packages.lock.json | 2 +- .../MarkdownViewr.Windows.UpdateProbe/packages.lock.json | 2 +- 6 files changed, 9 insertions(+), 9 deletions(-) diff --git a/global.json b/global.json index 163a6e1..d9997a0 100644 --- a/global.json +++ b/global.json @@ -1,6 +1,6 @@ { "sdk": { - "version": "10.0.401", + "version": "10.0.403", "rollForward": "latestFeature" } } diff --git a/src/MarkdownViewr.Windows.Core/packages.lock.json b/src/MarkdownViewr.Windows.Core/packages.lock.json index 81362b8..15041c7 100644 --- a/src/MarkdownViewr.Windows.Core/packages.lock.json +++ b/src/MarkdownViewr.Windows.Core/packages.lock.json @@ -32,9 +32,9 @@ }, "Microsoft.NET.ILLink.Tasks": { "type": "Direct", - "requested": "[10.0.12, )", - "resolved": "10.0.12", - "contentHash": "xi+BDjFpW+Sb+MHFHaH6Y/gV9I8BluFwRXc1QyCdoZbIK26eNiBeFuMTe/FMwc33G1wdHCyDg7CVTmb8OdQrMQ==" + "requested": "[10.0.14, )", + "resolved": "10.0.14", + "contentHash": "YlTamXppEQls6DYWt7RdUuwWDb0lyw/vXCaGeQpLCpsLmfwGuCkOz/vIGgMTV7ECsJcavkCOkxZXv9s8rdAHkQ==" }, "AngleSharp": { "type": "Transitive", @@ -54,4 +54,4 @@ "net10.0/win-x64": {}, "net10.0/win-x86": {} } -} +} \ No newline at end of file diff --git a/src/MarkdownViewr.Windows/packages.lock.json b/src/MarkdownViewr.Windows/packages.lock.json index b04eca2..2eeba7d 100644 --- a/src/MarkdownViewr.Windows/packages.lock.json +++ b/src/MarkdownViewr.Windows/packages.lock.json @@ -289,4 +289,4 @@ } } } -} +} \ No newline at end of file diff --git a/tests/MarkdownViewr.Windows.Core.Tests/packages.lock.json b/tests/MarkdownViewr.Windows.Core.Tests/packages.lock.json index 946aa88..2bee00b 100644 --- a/tests/MarkdownViewr.Windows.Core.Tests/packages.lock.json +++ b/tests/MarkdownViewr.Windows.Core.Tests/packages.lock.json @@ -144,4 +144,4 @@ } } } -} +} \ No newline at end of file diff --git a/tests/MarkdownViewr.Windows.UiTests/packages.lock.json b/tests/MarkdownViewr.Windows.UiTests/packages.lock.json index 2e549fd..42dffcb 100644 --- a/tests/MarkdownViewr.Windows.UiTests/packages.lock.json +++ b/tests/MarkdownViewr.Windows.UiTests/packages.lock.json @@ -230,4 +230,4 @@ } } } -} +} \ No newline at end of file diff --git a/tests/MarkdownViewr.Windows.UpdateProbe/packages.lock.json b/tests/MarkdownViewr.Windows.UpdateProbe/packages.lock.json index 49b7edc..ffb409a 100644 --- a/tests/MarkdownViewr.Windows.UpdateProbe/packages.lock.json +++ b/tests/MarkdownViewr.Windows.UpdateProbe/packages.lock.json @@ -34,4 +34,4 @@ "net10.0-windows7.0/win-x64": {}, "net10.0-windows7.0/win-x86": {} } -} +} \ No newline at end of file -- 2.54.0 From 135256c9f1a23c16ecba3bd749a0b779134c568f Mon Sep 17 00:00:00 2001 From: James Maes Date: Sun, 8 Nov 2026 07:32:50 -0600 Subject: [PATCH 3/8] build: keep the final newline in the refreshed lock file Co-Authored-By: Claude Opus 5.5 --- src/MarkdownViewr.Windows.Core/packages.lock.json | 2 +- src/MarkdownViewr.Windows/packages.lock.json | 2 +- tests/MarkdownViewr.Windows.Core.Tests/packages.lock.json | 2 +- tests/MarkdownViewr.Windows.UiTests/packages.lock.json | 2 +- tests/MarkdownViewr.Windows.UpdateProbe/packages.lock.json | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/MarkdownViewr.Windows.Core/packages.lock.json b/src/MarkdownViewr.Windows.Core/packages.lock.json index 15041c7..25cb5ba 100644 --- a/src/MarkdownViewr.Windows.Core/packages.lock.json +++ b/src/MarkdownViewr.Windows.Core/packages.lock.json @@ -54,4 +54,4 @@ "net10.0/win-x64": {}, "net10.0/win-x86": {} } -} \ No newline at end of file +} diff --git a/src/MarkdownViewr.Windows/packages.lock.json b/src/MarkdownViewr.Windows/packages.lock.json index 2eeba7d..b04eca2 100644 --- a/src/MarkdownViewr.Windows/packages.lock.json +++ b/src/MarkdownViewr.Windows/packages.lock.json @@ -289,4 +289,4 @@ } } } -} \ No newline at end of file +} diff --git a/tests/MarkdownViewr.Windows.Core.Tests/packages.lock.json b/tests/MarkdownViewr.Windows.Core.Tests/packages.lock.json index 2bee00b..946aa88 100644 --- a/tests/MarkdownViewr.Windows.Core.Tests/packages.lock.json +++ b/tests/MarkdownViewr.Windows.Core.Tests/packages.lock.json @@ -144,4 +144,4 @@ } } } -} \ No newline at end of file +} diff --git a/tests/MarkdownViewr.Windows.UiTests/packages.lock.json b/tests/MarkdownViewr.Windows.UiTests/packages.lock.json index 42dffcb..2e549fd 100644 --- a/tests/MarkdownViewr.Windows.UiTests/packages.lock.json +++ b/tests/MarkdownViewr.Windows.UiTests/packages.lock.json @@ -230,4 +230,4 @@ } } } -} \ No newline at end of file +} diff --git a/tests/MarkdownViewr.Windows.UpdateProbe/packages.lock.json b/tests/MarkdownViewr.Windows.UpdateProbe/packages.lock.json index ffb409a..49b7edc 100644 --- a/tests/MarkdownViewr.Windows.UpdateProbe/packages.lock.json +++ b/tests/MarkdownViewr.Windows.UpdateProbe/packages.lock.json @@ -34,4 +34,4 @@ "net10.0-windows7.0/win-x64": {}, "net10.0-windows7.0/win-x86": {} } -} \ No newline at end of file +} -- 2.54.0 From 42220c0e06c27b0d97d447319ce3d0df428913d6 Mon Sep 17 00:00:00 2001 From: James Maes Date: Sun, 8 Nov 2026 07:35:29 -0600 Subject: [PATCH 4/8] ci: run the coverage gate as a separate pwsh process Assert-Coverage.ps1 reports a shortfall with exit 1, which only stops the build when the script runs as a native process. Co-Authored-By: Claude Opus 5.5 --- .gitea/workflows/build.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitea/workflows/build.yaml b/.gitea/workflows/build.yaml index b91e641..1dddc72 100644 --- a/.gitea/workflows/build.yaml +++ b/.gitea/workflows/build.yaml @@ -17,7 +17,7 @@ jobs: dotnet format MarkdownViewr.Windows.slnx --verify-no-changes --severity warn --no-restore Remove-Item Env:Platform dotnet test tests/MarkdownViewr.Windows.Core.Tests --no-build --settings coverage.runsettings --collect:"XPlat Code Coverage" --logger trx --results-directory TestResults - ./build/Assert-Coverage.ps1 -ResultsDirectory TestResults -Packages MarkdownViewr.Windows.Core + pwsh -NoProfile -File ./build/Assert-Coverage.ps1 -ResultsDirectory TestResults -Packages MarkdownViewr.Windows.Core # PowerShell build scripts: analyzer and Pester boundary tests with pinned modules saved to the job's temp directory. $modules = Join-Path ($env:RUNNER_TEMP ?? [IO.Path]::GetTempPath()) "psmodules-$env:GITHUB_RUN_ID" Save-PSResource -Name PSScriptAnalyzer -Version 1.25.0 -Repository PSGallery -TrustRepository -Path $modules -- 2.54.0 From fb835015661d982f2ecc196c6ad8d88b55306142 Mon Sep 17 00:00:00 2001 From: James Maes Date: Sun, 8 Nov 2026 07:38:23 -0600 Subject: [PATCH 5/8] ci: create the module directory before saving the pinned modules Co-Authored-By: Claude Opus 5.5 --- .gitea/workflows/build.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitea/workflows/build.yaml b/.gitea/workflows/build.yaml index 1dddc72..0dd4802 100644 --- a/.gitea/workflows/build.yaml +++ b/.gitea/workflows/build.yaml @@ -20,6 +20,7 @@ jobs: pwsh -NoProfile -File ./build/Assert-Coverage.ps1 -ResultsDirectory TestResults -Packages MarkdownViewr.Windows.Core # PowerShell build scripts: analyzer and Pester boundary tests with pinned modules saved to the job's temp directory. $modules = Join-Path ($env:RUNNER_TEMP ?? [IO.Path]::GetTempPath()) "psmodules-$env:GITHUB_RUN_ID" + New-Item -ItemType Directory -Force -Path $modules | Out-Null Save-PSResource -Name PSScriptAnalyzer -Version 1.25.0 -Repository PSGallery -TrustRepository -Path $modules Save-PSResource -Name Pester -Version 5.7.1 -Repository PSGallery -TrustRepository -Path $modules Import-Module (Join-Path $modules PSScriptAnalyzer/1.25.0/PSScriptAnalyzer.psd1) -- 2.54.0 From 1105a4d076a7a592e128e73abf4904fb8c56d51b Mon Sep 17 00:00:00 2001 From: James Maes Date: Sun, 8 Nov 2026 07:42:14 -0600 Subject: [PATCH 6/8] ci: let the Pester suites see child exit codes They assert on failing child processes themselves; the shared workflow's native-exit-code preference turned those expected failures into errors. Co-Authored-By: Claude Opus 5.5 --- .gitea/workflows/build.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.gitea/workflows/build.yaml b/.gitea/workflows/build.yaml index 0dd4802..e2bbee9 100644 --- a/.gitea/workflows/build.yaml +++ b/.gitea/workflows/build.yaml @@ -33,6 +33,8 @@ jobs: ) if ($findings.Count -gt 0) { $findings | Format-Table; throw "Script analysis failed: $($file.Name)" } } + # The Pester suites assert on child processes' exit codes themselves. + $PSNativeCommandUseErrorActionPreference = $false $pester = New-PesterConfiguration $pester.Run.Path = @('build/Assert-Coverage.Tests.ps1', 'build/GitHubRepository.Tests.ps1', 'build/Distribution.Tests.ps1', 'build/InstalledUpdates.Tests.ps1', 'build/PackageBytes.Tests.ps1', 'build/ReleaseSigning.Tests.ps1') $pester.Run.PassThru = $true -- 2.54.0 From 6e69f9619d8c061e34e7aecc5d31e1cc142e7196 Mon Sep 17 00:00:00 2001 From: James Maes Date: Sun, 8 Nov 2026 07:45:49 -0600 Subject: [PATCH 7/8] ci: call the shared workflow from ci-workflows main Co-Authored-By: Claude Opus 5.5 --- .gitea/workflows/build.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitea/workflows/build.yaml b/.gitea/workflows/build.yaml index e2bbee9..edd04e5 100644 --- a/.gitea/workflows/build.yaml +++ b/.gitea/workflows/build.yaml @@ -5,7 +5,7 @@ on: tags: ['v*'] jobs: windows: - uses: self:KofTwentyTwo/ci-workflows/.gitea/workflows/windows.yaml@native-workflows + uses: self:KofTwentyTwo/ci-workflows/.gitea/workflows/windows.yaml@main secrets: inherit with: commands: | -- 2.54.0 From aff40e88574e4fe62991fa2da5405752f392178a Mon Sep 17 00:00:00 2001 From: James Maes Date: Sun, 8 Nov 2026 07:48:42 -0600 Subject: [PATCH 8/8] ci: pin the shared workflow to v1 Co-Authored-By: Claude Opus 5.5 --- .gitea/workflows/build.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitea/workflows/build.yaml b/.gitea/workflows/build.yaml index edd04e5..be341ea 100644 --- a/.gitea/workflows/build.yaml +++ b/.gitea/workflows/build.yaml @@ -5,7 +5,7 @@ on: tags: ['v*'] jobs: windows: - uses: self:KofTwentyTwo/ci-workflows/.gitea/workflows/windows.yaml@main + uses: self:KofTwentyTwo/ci-workflows/.gitea/workflows/windows.yaml@v1 secrets: inherit with: commands: | -- 2.54.0