Author SHA1 Message Date
James MaesandClaude Opus 5.5 4fbb457846 ci: first run on ci-workflows v1 (native workflows)
node / node (push) Successful in 20s
build / scripts (push) Successful in 20s
windows / windows (push) Successful in 2m19s
build / windows (push) Successful in 2m19s
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-08 08:26:33 -06:00
james.maes 611cad4881 Merge pull request 'ci: build on the shared ci-workflows Windows workflow' (#9) from ci/shared-windows into main 2026-11-08 13:51:44 +00:00
James MaesandClaude Opus 5.5 579dac6df8 ci: pin the shared workflow to v1
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-08 07:51:25 -06:00
James MaesandClaude Opus 5.5 b4a2734d9e ci: call the shared workflow from ci-workflows main
node / node (push) Successful in 17s
build / scripts (push) Successful in 17s
windows / windows (push) Successful in 2m18s
build / windows (push) Successful in 2m18s
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-08 07:47:22 -06:00
James MaesandClaude Opus 5.5 fe1883d4a4 ci: let the Pester suites see child exit codes
node / node (push) Successful in 22s
build / scripts (push) Successful in 22s
windows / windows (push) Successful in 2m7s
build / windows (push) Successful in 2m7s
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 <noreply@anthropic.com>
2026-11-08 07:42:17 -06:00
James MaesandClaude Opus 5.5 f9cad0128d ci: create the module directory before saving the pinned modules
node / node (push) Successful in 22s
build / scripts (push) Successful in 22s
windows / windows (push) Canceled after 1m13s
build / windows (push) Canceled after 1m13s
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-08 07:38:25 -06:00
James MaesandClaude Opus 5.5 49147f6c28 ci: run the coverage gate as a separate pwsh process
node / node (push) Successful in 24s
build / scripts (push) Successful in 24s
windows / windows (push) Canceled after 1m27s
build / windows (push) Canceled after 1m27s
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 <noreply@anthropic.com>
2026-11-08 07:35:32 -06:00
James MaesandClaude Opus 5.5 61f6d1c1a3 ci: build on the shared ci-workflows Windows workflow
node / node (push) Successful in 21s
build / scripts (push) Successful in 21s
windows / windows (push) Canceled after 1m27s
build / windows (push) Canceled after 1m27s
Locked restore, warnings-as-errors build, dotnet format, core and CLI tests
with the 100% coverage gate, the template pack/instantiate smoke test and the
PowerShell analyzer/Pester checks run on the KOF Windows host runner; the
review-gate scripts lint and test on node.yaml. Pins SDK 10.0.403 (the
runner's SDK) and refreshes the lock files for its ILLink 10.0.14 reference.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-08 07:32:52 -06:00
forge-recovery 60f8c6856a build: pin SDK 10.0.401, the version the committed lock files require (#8)
KofTwentyTwo/ci-policy: ci / fork-guard (push) Skipped
KofTwentyTwo/ci-policy: ci / go-0 (push) Skipped
KofTwentyTwo/ci-policy: ci / go-nix-1 (push) Skipped
KofTwentyTwo/ci-policy: ci / gradle-2 (push) Skipped
KofTwentyTwo/ci-policy: ci / gradle-3 (push) Skipped
KofTwentyTwo/ci-policy: ci / java-docker-4 (push) Skipped
KofTwentyTwo/ci-policy: ci / java-maven-5 (push) Skipped
KofTwentyTwo/ci-policy: ci / manifests-6 (push) Skipped
KofTwentyTwo/ci-policy: ci / nix-7 (push) Skipped
KofTwentyTwo/ci-policy: ci / node-8 (push) Skipped
KofTwentyTwo/ci-policy: ci / python-9 (push) Skipped
KofTwentyTwo/ci-policy: ci / rust-10 (push) Skipped
KofTwentyTwo/ci-policy: ci / rust-12 (push) Skipped
KofTwentyTwo/ci-policy: ci / rust-11 (push) Skipped
KofTwentyTwo/ci-policy: ci / image-build-0 (push) Skipped
KofTwentyTwo/ci-policy: ci / image-build-1 (push) Skipped
KofTwentyTwo/ci-policy: ci / image-build-2 (push) Skipped
KofTwentyTwo/ci-policy: ci / image-build-3 (push) Skipped
KofTwentyTwo/ci-policy: ci / image-build-4 (push) Skipped
KofTwentyTwo/ci-policy: ci / image-build-5 (push) Skipped
KofTwentyTwo/ci-policy: ci / image-build-6 (push) Skipped
KofTwentyTwo/ci-policy: ci / image-build-7 (push) Skipped
KofTwentyTwo/ci-policy: ci / not-enrolled (push) Skipped
KofTwentyTwo/ci-policy: native / fork-deny (push) Skipped
KofTwentyTwo/ci-policy: native / dotnet-1 (push) Skipped
KofTwentyTwo/ci-policy: native / dotnet-2 (push) Skipped
KofTwentyTwo/ci-policy: native / dotnet-3 (push) Skipped
KofTwentyTwo/ci-policy: native / swift-4 (push) Skipped
KofTwentyTwo/ci-policy: native / swift-5 (push) Skipped
KofTwentyTwo/ci-policy: native / swift-6 (push) Skipped
KofTwentyTwo/ci-policy: native / swift-7 (push) Skipped
KofTwentyTwo/ci-policy: native / swift-8 (push) Skipped
KofTwentyTwo/ci-policy: Shared source and config CI / verify (push) Successful in 22s
KofTwentyTwo/ci-policy: Shared source and config CI / secrets (push) Successful in 22s
KofTwentyTwo/ci-policy: Shared .NET CI / secrets (push) Successful in 23s
KofTwentyTwo/ci-policy: Shared source and config CI / gate (push) Successful in 12s
KofTwentyTwo/ci-policy: ci / source-config-13 (push) Successful in 40s
KofTwentyTwo/ci-policy: ci / ci-result (push) Successful in 8s
KofTwentyTwo/ci-policy: Shared .NET CI / verify (push) Successful in 1m1s
KofTwentyTwo/ci-policy: Shared .NET CI / gate (push) Successful in 15s
KofTwentyTwo/ci-policy: native / dotnet-0 (push) Successful in 1m18s
KofTwentyTwo/ci-policy: native / native-result (push) Successful in 5s
2026-11-01 23:27:44 +00:00
10 changed files with 84 additions and 57 deletions

No files matched your search

+66
View File
@@ -0,0 +1,66 @@
name: build
on:
push:
branches: ['**']
tags: ['v*']
jobs:
windows:
uses: self:KofTwentyTwo/ci-workflows/.gitea/workflows/windows.yaml@v1
secrets: inherit
with:
commands: |
dotnet restore Kof22App.slnx -p:Platform=x64 --locked-mode
dotnet build Kof22App.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/Kof22App/Kof22App.csproj -p:Platform=x64 -warnaserror --no-restore
$env:Platform = 'x64'
dotnet format Kof22App.slnx --verify-no-changes --severity warn --no-restore
Remove-Item Env:Platform
dotnet test tests/Kof22App.Core.Tests --no-build --settings coverage.runsettings --collect:"XPlat Code Coverage" --logger trx --results-directory TestResults
dotnet test tests/Kof22App.Cli.Tests --no-build --settings coverage.runsettings --collect:"XPlat Code Coverage" --logger trx --results-directory TestResults
pwsh -NoProfile -File ./build/Assert-Coverage.ps1 -ResultsDirectory TestResults -Packages Kof22App.Core,kof22-app
# Template: pack, install into a private hive, instantiate with and without the CLI, then build, format, test and gate coverage.
$temp = $env:RUNNER_TEMP ?? [IO.Path]::GetTempPath()
$hive = Join-Path $temp "template-hive-$env:GITHUB_RUN_ID"
dotnet pack templates/KofTwentyTwo.Templates.WindowsApp.csproj -c Release -p:Version=0.1.0 -p:RestoreLockedMode=true -o artifacts/template
dotnet new install artifacts/template/KofTwentyTwo.Templates.WindowsApp.0.1.0.nupkg --debug:custom-hive $hive
foreach ($cli in 'true', 'false') {
$directory = "artifacts/template-probe-$cli"
$name = if ($cli -eq 'true') { 'TemplateProbe.WithCli' } else { 'TemplateProbe.NoCli' }
dotnet new k22-winapp -n $name --appId "probe-$cli" --displayName "Probe $cli" --cli $cli -o $directory --debug:custom-hive $hive
dotnet restore "$directory/$name.slnx" -p:Platform=x64 --locked-mode
dotnet build "$directory/$name.slnx" -p:Platform=x64 -warnaserror --no-restore
dotnet format "$directory/$name.slnx" --verify-no-changes --severity warn --no-restore
dotnet test "$directory/tests/$name.Core.Tests" --no-build --settings "$directory/coverage.runsettings" --collect:'XPlat Code Coverage' --results-directory "$directory/TestResults"
if ($cli -eq 'true') {
dotnet test "$directory/tests/$name.Cli.Tests" --no-build --settings "$directory/coverage.runsettings" --collect:'XPlat Code Coverage' --results-directory "$directory/TestResults"
}
pwsh -NoProfile -File "$directory/build/Assert-Coverage.ps1" -ResultsDirectory "$directory/TestResults"
}
# PowerShell build scripts: analyzer and Pester boundary tests with pinned modules saved to the job's temp directory.
$modules = Join-Path $temp "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)
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') {
# One file at a time: recursive analysis can crash inside 1.25.0.
$findings = @(Invoke-ScriptAnalyzer -Path $file.FullName -Settings ./PSScriptAnalyzerSettings.psd1)
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
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 -2
View File
@@ -90,8 +90,8 @@ pre-commit install --hook-type pre-commit --hook-type commit-msg
| `ci / build-test` | Locked restore, zero-warning build, unit tests, 100% coverage gate |
| `ci / format` | `dotnet format --verify-no-changes --severity warn` |
| `ci / ui-tests` | FlaUI end-to-end tests of the app |
| `installed-updates` | Real stable/dev installers, upgrades, restart and published-output UI smoke |
| `powershell`, `javascript` | Tool lint, setup/coverage boundary tests, review tests and dependency signatures |
| `ci / installed-updates` | Real stable/dev installers, upgrades, restart and published-output UI smoke |
| `scripts / powershell`, `scripts / javascript` | Tool lint, setup/coverage boundary tests, review tests and dependency signatures |
| `codeql / analyze (javascript-typescript)` | Static analysis of repository review tooling |
| `review / automated` (single maintainer) | Current-commit automated review acknowledged by the configured human maintainer |
-2
View File
@@ -61,8 +61,6 @@ Prerequisites:
- Optionally Visual Studio 2026 (Windows App SDK workload) or Rider
```powershell
# Once after generation, create and commit the NuGet locks locally:
# dotnet restore Kof22App.slnx -p:Platform=x64
dotnet restore Kof22App.slnx -p:Platform=x64 --locked-mode
dotnet build Kof22App.slnx -p:Platform=x64 -warnaserror
dotnet test Kof22App.slnx -p:Platform=x64 --no-build --filter "FullyQualifiedName!~UiTests"
+8 -17
View File
@@ -18,15 +18,6 @@ dotnet new k22-winapp -n Contoso.Notes --appId contoso-notes --displayName "Cont
--description "Quick notes that stay out of the way." -o Contoso.Notes
```
To try the installable package before its first publication, run from this clone:
```powershell
dotnet pack templates/KofTwentyTwo.Templates.WindowsApp.csproj -c Release -p:Version=0.1.0 -p:RestoreLockedMode=true -o artifacts/template
dotnet new install ./artifacts/template/KofTwentyTwo.Templates.WindowsApp.0.1.0.nupkg
dotnet new k22-winapp -n Contoso.Notes --appId contoso-notes --displayName "Contoso Notes" -o artifacts/Contoso.Notes
# Add --cli false for a GUI-only app; use a fresh output directory each time.
```
| Option | Default | What it sets |
| --- | --- | --- |
| `-n`, `--name` | (required) | Solution, project, namespace, and executable names (`Contoso.Notes.slnx`, `Contoso.Notes.Core`, `Contoso.Notes.exe`), and the repository name in links |
@@ -41,10 +32,8 @@ The copyright year in license headers becomes the current year.
## After generating
The generator omits NuGet dependency lock files. Before the first commit, run
`dotnet restore <name>.slnx -p:Platform=x64` in the generated directory to create
them, then run the README's locked restore, build, test, coverage and format
commands. Commit the resulting
The generator omits dependency lock files. Before the first commit, run the README's
restore, build, test, coverage and format commands, then commit the resulting
`packages.lock.json` files. Install the included hooks with
`pre-commit install --hook-type pre-commit --hook-type commit-msg` after `git init`.
The generated PowerShell tooling gate uses PSScriptAnalyzer 1.25.0.
@@ -52,10 +41,12 @@ The generated PowerShell tooling gate uses PSScriptAnalyzer 1.25.0.
1. Follow [the preview/apply/validate setup runbook](docs/repository-setup.md).
Create the GitHub repository (public, Product tier), push `main`, and apply the
[repository standard's](https://github.com/KofTwentyTwo/standards/blob/main/standards/repository.md)
settings and rulesets. Use the setup tool's required contexts and
[CONTRIBUTING.md](CONTRIBUTING.md)'s check table; standalone job names have no
workflow-name prefix. The source repository additionally requires `template`;
generated application repositories do not.
settings and rulesets, with these required checks: `pr / title`, `pr / dco`,
`pr / dependency-review`, `security / secrets`, `security / sca`,
`security / workflows`, `codeql / analyze (csharp)`, `codeql / analyze (actions)`,
`ci / build-test`, `ci / format`, `ci / ui-tests`, `scripts / powershell`,
`scripts / javascript`, `codeql / analyze (javascript-typescript)`, and
`review / automated` for the single-maintainer policy.
2. Create the `release` environment limited to `v*` tags, and list the repository in the
[standards repository inventory](https://github.com/KofTwentyTwo/standards/blob/main/MAINTAINERS.md#repositories)
(`K22-REPO-42`; the conformance checker fails until it is listed).
-15
View File
@@ -47,21 +47,6 @@ Describe 'Required checks match standalone workflow jobs' `
Describe 'Generated repository administration' `
{
It 'allows the digest-pinned security containers without permitting arbitrary container actions' `
{
$plan = Get-GitHubRepositoryPlan -Repository 'Example/Notes'
$policy = ($plan.Requests | Where-Object Path -Like '*/actions/permissions/selected-actions').Body
$policy.patterns_allowed.Count | Should -Be 3
$policy.patterns_allowed | Should -Contain 'KofTwentyTwo/standards/*@*'
$containers = @($policy.patterns_allowed | Where-Object { $_.StartsWith('docker://', [StringComparison]::Ordinal) })
$containers.Count | Should -Be 2
foreach($container in $containers)
{
$container | Should -Match '^docker://ghcr\.io/(gitleaks/gitleaks:v8\.30\.1|aquasecurity/trivy:0\.75\.0)@sha256:[0-9a-f]{64}$'
$container | Should -Not -Match '\*'
}
}
InModuleScope GitHubRepository `
{
BeforeEach `
+1 -8
View File
@@ -74,14 +74,7 @@ function Get-GitHubRepositoryPlan
@{ Method = 'PUT'; Path = "$root/actions/permissions/workflow"; Body = @{ default_workflow_permissions = 'read'; can_approve_pull_request_reviews = $false } },
@{ Method = 'PUT'; Path = "$root/actions/permissions/fork-pr-contributor-approval"; Body = @{ approval_policy = 'all_external_contributors' } },
@{ Method = 'PUT'; Path = "$root/actions/permissions"; Body = @{ enabled = $true; allowed_actions = 'selected' } },
@{ Method = 'PUT'; Path = "$root/actions/permissions/selected-actions"; Body = @{
github_owned_allowed = $true; verified_allowed = $true
# Exact container actions used by the published v0.1.2 security builder.
patterns_allowed = @('KofTwentyTwo/standards/*@*',
'docker://ghcr.io/gitleaks/gitleaks:v8.30.1@sha256:c00b6bd0aeb3071cbcb79009cb16a60dd9e0a7c60e2be9ab65d25e6bc8abbb7f',
'docker://ghcr.io/aquasecurity/trivy:0.75.0@sha256:af6acf9a6b85dfe389a1941505c0ce9efef52a4719635e1a962f022a3d855daa')
}
},
@{ Method = 'PUT'; Path = "$root/actions/permissions/selected-actions"; Body = @{ github_owned_allowed = $true; verified_allowed = $true; patterns_allowed = @('KofTwentyTwo/standards/*@*') } },
@{ Method = 'PUT'; Path = "$root/environments/release"; Body = @{ deployment_branch_policy = @{ protected_branches = $false; custom_branch_policies = $true } } },
@{ Method = 'POST'; Path = "$root/environments/release/deployment-branch-policies"; Body = @{ name = 'v*'; type = 'tag' } },
@{ Method = 'POST'; Path = "$root/rulesets"; Body = $main },
-6
View File
@@ -66,12 +66,6 @@ and environment protections are retained. API failures stop immediately; earlier
successful requests may remain, so validate and resolve the reported failure before
rerunning. The tool never creates repositories, pushes, merges, tags or releases.
The selected Actions policy permits the shared standards workflows, GitHub-owned
and verified actions, and the exact digest-pinned Gitleaks/Trivy container actions
used by the published security builder. GitHub also checks container actions
against this policy; missing entries prevent the security workflow from starting.
Review these exact references whenever the shared builder pin changes.
## Finish and verify
Register ownership/tier in the standards `MAINTAINERS.md` inventory through a
+1 -1
View File
@@ -1,6 +1,6 @@
{
"sdk": {
"version": "10.0.100",
"version": "10.0.403",
"rollForward": "latestFeature"
}
}
+3 -3
View File
@@ -10,9 +10,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=="
},
"kof22app.core": {
"type": "Project",
+3 -3
View File
@@ -22,9 +22,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=="
}
},
"net10.0/win-arm64": {},