fix(releases): stabilize acceptance and pin verified signing builder (#37)
The protected releases encountered two blockers: the full111-test Windows acceptance suite ran into its600-second process budget, and Microsoft's signing action dependency installer conflicted with the caller's NuGet source mapping. A subsequent completed run exposed an immediate keyboard assertion reading jk before the required jkg value. Allow900 seconds for each full published/installed suite and60 minutes for all three suites plus packaging/update probes. Individual test deadlines, assertions and filters remain unchanged. Keep the exact jkg assertion, first awaiting that exact native textbox value within the existing10-second deadline; FlaUI5.0.0's UntilInputIsProcessed only sleeps100ms. Add this exact case to the focused hosted regression job. No input is replayed and a genuinely lost key still fails. Pin published immutable standards1.1.1 at96cbdf208a15c9c524676bd15ff9e323228a952b. The owner personally reviewed its signing fix in PR44; it merged normally and production builder release38322016784 succeeds. The fixed official dependency staging verifies the exact package SHA256 and NuGet signatures without changing application package source mapping, OIDC trust or signing verification. Preserve only the previously approved exact Syft entry in the setup plan, retaining restrictive container regression tests. Refs #33. EXE/ZIP first, MSI next release (#36), following the latest owner decision. No app release exists; preserved failed1.0.0 tags will not be rewritten. New app candidates will use1.0.1/stable and1.0.1-beta.1/dev after this reviewed exact-head CI passes. Validation: zero-warning app/test builds and test formatting;42 process/registry/setup boundary tests pass, zero skips; configured PowerShell analysis, actionlint, medium-and-above workflow security gate and all commit hooks pass. The scan's five preexisting low self-repository recommendations remain unchanged. Fresh full native/published/installed hosted acceptance is running. Local baseline and changed keyboard runs both stop earlier at missing FindText, so neither verifies the hosted jkg fix. Temporary fixture diagnostics removed; original user previews/profiles preserved. Substantial AI assistance: Codex GPT-6. Genuine final-head maintainer review under K22-AI-01 is required before merge. This PR contains no application behavior change or weakened assertion. --------- Signed-off-by: James Maes <james@kof22.com> Co-authored-by: Codex GPT-6 <noreply@openai.com>
This commit was merged in pull request #37.
This commit is contained in:
1 parent
38dd5c1488
commit
4c0ccc71f3
11 files changed
+97
-15
No files matched your search
@@ -44,7 +44,7 @@ jobs:
|
||||
shell: pwsh
|
||||
run: >-
|
||||
dotnet test tests/MarkdownViewr.Windows.UiTests --no-build
|
||||
--filter 'FullyQualifiedName~SourceHighlighting|FullyQualifiedName~Settings_NewWindowPanelDefaults|FullyQualifiedName~Settings_ContentsPresentation|FullyQualifiedName~Settings_ContentsTooltip|FullyQualifiedName~Themes_PalettePreviewAndDefaultChoice|FullyQualifiedName~Settings_PrintingDefaults|FullyQualifiedName~Settings_PrintingDraft|FullyQualifiedName~ThemeTransfer_NativePickerCancels|FullyQualifiedName~Print_UserWidthAndBorders|FullyQualifiedName~ReadingKeys_ScrollCommands|FullyQualifiedName~Source_ShowReloadAndHide|FullyQualifiedName~ThemeEditor_AllTypography|FullyQualifiedName~ThemeEditor_NewCustomTheme|FullyQualifiedName~Appearance_WidthCssAndPrint|FullyQualifiedName~Toolbar_ReadingCommandsAndMenus|FullyQualifiedName~Toolbar_EditorAndPrint|FullyQualifiedName~ThemeTransfer_BatchFutureInvalidAndDisabledExport|FullyQualifiedName~ReadingKeys_HeadingSequences|FullyQualifiedName~Source_BidirectionalScroll|FullyQualifiedName~Source_RawHtmlHeadingProvenance|FullyQualifiedName~Extensions_NativePreferences|FullyQualifiedName~Windows_LocalDocumentLinks|FullyQualifiedName~ActivationInboxTests|FullyQualifiedName~Outline_NestedCollapse'
|
||||
--filter 'FullyQualifiedName~SourceHighlighting|FullyQualifiedName~Settings_NewWindowPanelDefaults|FullyQualifiedName~Settings_ContentsPresentation|FullyQualifiedName~Settings_ContentsTooltip|FullyQualifiedName~Themes_PalettePreviewAndDefaultChoice|FullyQualifiedName~Settings_PrintingDefaults|FullyQualifiedName~Settings_PrintingDraft|FullyQualifiedName~ThemeTransfer_NativePickerCancels|FullyQualifiedName~Print_UserWidthAndBorders|FullyQualifiedName~ReadingKeys_ScrollCommands|FullyQualifiedName~ReadingKeys_FindAndTextFocus|FullyQualifiedName~Source_ShowReloadAndHide|FullyQualifiedName~ThemeEditor_AllTypography|FullyQualifiedName~ThemeEditor_NewCustomTheme|FullyQualifiedName~Appearance_WidthCssAndPrint|FullyQualifiedName~Toolbar_ReadingCommandsAndMenus|FullyQualifiedName~Toolbar_EditorAndPrint|FullyQualifiedName~ThemeTransfer_BatchFutureInvalidAndDisabledExport|FullyQualifiedName~ReadingKeys_HeadingSequences|FullyQualifiedName~Source_BidirectionalScroll|FullyQualifiedName~Source_RawHtmlHeadingProvenance|FullyQualifiedName~Extensions_NativePreferences|FullyQualifiedName~Windows_LocalDocumentLinks|FullyQualifiedName~ActivationInboxTests|FullyQualifiedName~Outline_NestedCollapse'
|
||||
--logger 'trx;LogFileName=reader-regressions.trx'
|
||||
--results-directory artifacts/reader-regressions
|
||||
- name: Retain native regression evidence
|
||||
@@ -63,7 +63,8 @@ jobs:
|
||||
installed-updates:
|
||||
name: installed-updates
|
||||
runs-on: windows-latest
|
||||
timeout-minutes: 45
|
||||
# Three complete UI suites plus packaging, installation and update probes.
|
||||
timeout-minutes: 60
|
||||
permissions:
|
||||
contents: read
|
||||
steps:
|
||||
|
||||
@@ -95,7 +95,7 @@ jobs:
|
||||
|
||||
release:
|
||||
needs: [verify, gates, security, codeql, scripts, fuzzing]
|
||||
uses: KofTwentyTwo/standards/.github/workflows/release-velopack.yml@93b1d6163a4c466ae443e98b62786fc4d80d33bd # v1.1.0
|
||||
uses: KofTwentyTwo/standards/.github/workflows/release-velopack.yml@96cbdf208a15c9c524676bd15ff9e323228a952b # v1.1.1
|
||||
permissions:
|
||||
contents: write # create and publish the GitHub release
|
||||
id-token: write # sign attestations; Azure OIDC when signing
|
||||
|
||||
@@ -47,17 +47,17 @@ Describe 'Required checks match standalone workflow jobs' `
|
||||
|
||||
Describe 'Generated repository administration' `
|
||||
{
|
||||
It 'allows the digest-pinned security containers without permitting arbitrary container actions' `
|
||||
It 'allows the digest-pinned security and SBOM 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.Count | Should -Be 4
|
||||
$policy.patterns_allowed | Should -Contain 'KofTwentyTwo/standards/*@*'
|
||||
$containers = @($policy.patterns_allowed | Where-Object { $_.StartsWith('docker://', [StringComparison]::Ordinal) })
|
||||
$containers.Count | Should -Be 2
|
||||
$containers.Count | Should -Be 3
|
||||
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 -Match '^docker://ghcr\.io/(gitleaks/gitleaks:v8\.30\.1|aquasecurity/trivy:0\.75\.0|anchore/syft:v1\.54\.1)@sha256:[0-9a-f]{64}$'
|
||||
$container | Should -Not -Match '\*'
|
||||
}
|
||||
}
|
||||
|
||||
@@ -79,7 +79,8 @@ function Get-GitHubRepositoryPlan
|
||||
# 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')
|
||||
'docker://ghcr.io/aquasecurity/trivy:0.75.0@sha256:af6acf9a6b85dfe389a1941505c0ce9efef52a4719635e1a962f022a3d855daa',
|
||||
'docker://ghcr.io/anchore/syft:v1.54.1@sha256:3eb5379ba7b409c3f4069b686110527af0c47df993fa5c10d13e7cf34f49b1aa')
|
||||
}
|
||||
},
|
||||
@{ Method = 'PUT'; Path = "$root/environments/release"; Body = @{ deployment_branch_policy = @{ protected_branches = $false; custom_branch_policies = $true } } },
|
||||
|
||||
@@ -13,11 +13,27 @@ Describe 'Installed update smoke boundaries' `
|
||||
$script:SmokeArtifacts = Join-Path (Split-Path -Parent $PSScriptRoot) 'artifacts'
|
||||
$script:SmokeAppId = [regex]::Match((Get-Content -LiteralPath (Join-Path (Split-Path -Parent $PSScriptRoot) 'src/MarkdownViewr.Windows.Core/AppIdentity.cs') -Raw), '(?m)^\s*Id\s*=\s*"([a-z0-9][a-z0-9-]*)"').Groups[1].Value
|
||||
$ast = [Management.Automation.Language.Parser]::ParseFile($script:SmokeHarness, [ref]$null, [ref]$null)
|
||||
foreach($name in @('Assert-SmokeCliVersion', 'Get-SmokeDefaultChoiceSnapshot', 'Get-SmokeFileRegistration', 'Assert-SmokeFileRegistrationRemoved', 'Assert-SmokeInstallationOwner'))
|
||||
foreach($name in @('Assert-SmokeCliVersion', 'Get-SmokeDefaultChoiceSnapshot', 'Get-SmokeFileRegistration', 'Assert-SmokeFileRegistrationRemoved', 'Assert-SmokeInstallationOwner', 'Invoke-SmokeProcess'))
|
||||
{
|
||||
$function = $ast.Find({ param($node) $node -is [Management.Automation.Language.FunctionDefinitionAst] -and $node.Name -eq $name }, $true)
|
||||
. ([scriptblock]::Create($function.Extent.Text))
|
||||
}
|
||||
$script:repositoryRoot = $TestDrive
|
||||
$script:outputRoot = $TestDrive
|
||||
$script:vpk = 'not-a-fixture-tool'
|
||||
$script:smokeProcessNumber = 0
|
||||
}
|
||||
|
||||
It 'terminates a hung child process and fails the smoke gate' `
|
||||
{
|
||||
$shell = (Get-Process -Id $PID).Path
|
||||
{ Invoke-SmokeProcess -File $shell -Arguments @('-NoProfile', '-Command', 'Start-Sleep -Seconds 30') -TimeoutSeconds 1 } | Should -Throw '*Process timed out*'
|
||||
}
|
||||
|
||||
It 'rejects a failing child process and retains its output' `
|
||||
{
|
||||
$shell = (Get-Process -Id $PID).Path
|
||||
{ Invoke-SmokeProcess -File $shell -Arguments @('-NoProfile', '-Command', "Write-Output 'fixture failure'; exit 7") -TimeoutSeconds 10 } | Should -Throw '*Process failed (7)*fixture failure*'
|
||||
}
|
||||
|
||||
It 'requires an actual matching manifest inside the resolved artifact boundary before uninstall' `
|
||||
|
||||
@@ -435,7 +435,9 @@ try
|
||||
$env:K22_UITEST_CHANNEL = 'stable'
|
||||
$env:K22_UITEST_INSTALLED = '0'
|
||||
$env:K22_UITEST_EXE = Join-Path $buildRoot "publish/0.1.0/$mainExe"
|
||||
Invoke-SmokeProcess -File 'dotnet' -Arguments @('test', "$repositoryRoot/tests/$name.UiTests", '--no-build', '--logger', 'console;verbosity=normal', '--logger', 'trx;LogFileName=published-ui.trx', '--results-directory', $outputRoot) -TimeoutSeconds 600
|
||||
# The full 111-test UI suite takes 572 seconds on a passing hosted runner.
|
||||
# Allow bounded host variation without changing any individual test deadline.
|
||||
Invoke-SmokeProcess -File 'dotnet' -Arguments @('test', "$repositoryRoot/tests/$name.UiTests", '--no-build', '--logger', 'console;verbosity=normal', '--logger', 'trx;LogFileName=published-ui.trx', '--results-directory', $outputRoot) -TimeoutSeconds 900
|
||||
foreach($initial in @($versions[0], $versions[2]))
|
||||
{
|
||||
$initialPackageId = $packageId + '-' + $initial.channel
|
||||
@@ -500,7 +502,7 @@ try
|
||||
$updatedRegistration | ConvertTo-Json | Set-Content -LiteralPath (Join-Path $outputRoot "$channel-registration-after.json")
|
||||
$env:K22_UITEST_INSTALLED = '1'
|
||||
$env:K22_UITEST_EXE = $currentExe
|
||||
Invoke-SmokeProcess -File 'dotnet' -Arguments @('test', "$repositoryRoot/tests/$name.UiTests", '--no-build', '--filter', 'FullyQualifiedName!~CheckForUpdates_InALooseBuild', '--logger', 'console;verbosity=normal', '--logger', "trx;LogFileName=installed-$channel-ui.trx", '--results-directory', $outputRoot) -TimeoutSeconds 600
|
||||
Invoke-SmokeProcess -File 'dotnet' -Arguments @('test', "$repositoryRoot/tests/$name.UiTests", '--no-build', '--filter', 'FullyQualifiedName!~CheckForUpdates_InALooseBuild', '--logger', 'console;verbosity=normal', '--logger', "trx;LogFileName=installed-$channel-ui.trx", '--results-directory', $outputRoot) -TimeoutSeconds 900
|
||||
$records.Add(@{ kind = 'installed'; channel = $channel; before = $before; after = $after; restarted = $true; appSha256 = $installedHash })
|
||||
}
|
||||
finally
|
||||
|
||||
+1
-1
@@ -7,7 +7,7 @@ which calls the shared `release-velopack.yml` workflow in KofTwentyTwo/standards
|
||||
|
||||
## Workflow baseline
|
||||
|
||||
The signing release builder is pinned to standards v1.1.0 (`93b1d6163a4c466ae443e98b62786fc4d80d33bd`); other shared gates retain v0.1.2. The release caller checks main ancestry and reruns build, coverage, formatting, UI tests, security scans and CodeQL before publication.
|
||||
The signing release builder is pinned to standards v1.1.1 (`96cbdf208a15c9c524676bd15ff9e323228a952b`); other shared gates retain v0.1.2. The release caller checks main ancestry and reruns build, coverage, formatting, UI tests, security scans and CodeQL before publication.
|
||||
The AppKit dependency locks now match the published 0.1.0 packages. Before changing any package version, regenerate the affected locks and verify a locked restore with a clean package cache.
|
||||
|
||||
## Versioning and channels
|
||||
|
||||
@@ -2,6 +2,49 @@
|
||||
|
||||
Updated: 2026-10-12
|
||||
|
||||
## Release blockers after main merge - 2026-10-12
|
||||
|
||||
Standards PR44 was personally reviewed by the owner and merged atb3e4b49.
|
||||
Its version/changelog-only release PR42 merged at96cbdf2; signedv1.1.1 was pushed
|
||||
and release CI38322016784 is running. The app caller now pins that exact builder.
|
||||
No new Azure administration or credentials are required.
|
||||
|
||||
App PR37's first hosted run completed111 published tests:110 passed, one literal
|
||||
keyboard assertion observedjk instead ofjkg. The test now waits for the exactjkg
|
||||
value within its existing10-second deadline before retaining the same assertion.
|
||||
FlaUI5.0.0's UntilInputIsProcessed is only a100ms sleep, not an acknowledgement.
|
||||
The exact test is also included in the focused hosted regression job. Builds and
|
||||
formatting pass; hosted verification remains required. Local baseline and changed
|
||||
runs both stopped earlier at missing FindText, so they do not verify thejkg fix.
|
||||
Temporary diagnostics were removed. Original preview processes/profiles remain
|
||||
untouched. Fresh exact-head hosted acceptance must pass before merge/publication.
|
||||
|
||||
The owner-reviewed application merged through PR35 at38dd5c1. Main CI38294895221
|
||||
passed; retained published111 and installed stable/dev110 reports have zero
|
||||
failures/skips. OpenSSF project15417 assessment is saved at70%, not passing.
|
||||
The exact Syft image is now explicitly owner-approved and allowlisted.
|
||||
|
||||
Neither production release is published. Signedv1.0.0 andv1.0.0-beta.1 tags remain
|
||||
preserved. Dev38299469062 passed acceptance and Azure OIDC login, then failed the
|
||||
official signing action dependency install because --add-source conflicts with
|
||||
NuGet package source mapping. Standards PR44 stages the exact verified dependency
|
||||
without changing caller NuGet policy;40 signing tests and the real package bootstrap
|
||||
pass locally. Production CI signing and final artifact verification remain pending.
|
||||
|
||||
Stable38299469141 attempt2 completed110 of111 published tests without a reported
|
||||
test failure before its600-second process limit. The successful main published
|
||||
suite took572 seconds. The bounded suite budget is now900 seconds; individual
|
||||
test deadlines, assertions, cases and failure handling remain unchanged. The job
|
||||
budget allows all three suites plus packaging/update probes. Two real subprocess
|
||||
regressions verify that hangs and nonzero exits still fail the gate. Fresh hosted
|
||||
acceptance is required; this timing change is not proof of a successful release.
|
||||
|
||||
The owner's latest instruction is EXE/portable ZIP first, MSI next release (#36).
|
||||
Do not cancel runs, alter published assets, replace existing release tags, skip
|
||||
acceptance or claim public downloads. Next: genuine review and green checks for
|
||||
the two fixes, merge the shared builder, update the app's immutable builder pin,
|
||||
then publish new signed release candidates and verify the downloaded artifacts.
|
||||
|
||||
## Current release status - 2026-10-12
|
||||
|
||||
Standards 1.1.0 is published immutably at
|
||||
|
||||
+18
-1
@@ -1,6 +1,23 @@
|
||||
# Development Tasks
|
||||
|
||||
## Current release checklist
|
||||
## Current release checklist - 2026-10-12
|
||||
|
||||
- [x] Merge genuinely owner-reviewed app through PR35 at38dd5c1; all main gates pass.
|
||||
- [x] Preserve signed1.0.0/stable and1.0.0-beta.1/dev tags; no release is published.
|
||||
- [x] Apply only the exact Syft image addition explicitly approved by the owner.
|
||||
- [x] Prove production Azure OIDC login; preserve existing account/profile/trust.
|
||||
- [x] Reproduce signing dependency conflict; standards PR44 real package bootstrap and40 signing tests pass locally.
|
||||
- [x] Measure stable retry110/111 without reported test failures before600-second limit; prepare bounded900-second suite budget with unchanged assertions/deadlines.
|
||||
- [ ] Obtain genuine reviews, pass exact-head hosted checks and merge the release fixes.
|
||||
- [x] Owner personally reviewed standards PR44; merge the signing fix and version-only PR42 through normal protections, then push signedstandards1.1.1.
|
||||
- [x] Update the app caller to fixed builder96cbdf2; preserve caller NuGet mapping and strict signing verification.
|
||||
- [x] Keep the exactjkg assertion while awaiting native text processing within its existing deadline; add the case to focused hosted regressions.
|
||||
- [ ] Verify fresh full hosted acceptance and obtain genuine final-head app review before merge.
|
||||
- [ ] Publish stable/dev EXE and ZIP candidates; verify exact distributed signatures, timestamps, hashes, SBOMs and attestations (#33).
|
||||
- [ ] Update user download links only after actual verified publication.
|
||||
- [ ] Deliver signed and acceptance-tested MSI installers in the next release (#36), following the owner's latest decision.
|
||||
|
||||
## Prior release checklist
|
||||
|
||||
- [x] Correct the disabled-editor tooltip exception; accepted application code321816c.
|
||||
- [x] Final signing caller b1dc874 / CI38276579007 passes all hosted checks, including published111 and stable/dev110 acceptance each, zero failures/skips.
|
||||
|
||||
@@ -35,8 +35,8 @@ signing service. Never export a PFX or put administrative passwords in CI.
|
||||
|
||||
## Enable the reviewed builder
|
||||
|
||||
The release caller pins standards v1.1.0 at
|
||||
`93b1d6163a4c466ae443e98b62786fc4d80d33bd`. Its reviewed builder supports the
|
||||
The release caller pins standards v1.1.1 at
|
||||
`96cbdf208a15c9c524676bd15ff9e323228a952b`. Its reviewed builder supports the
|
||||
explicit ownership catalog and verifies final shipped bytes/signatures. The
|
||||
configured catalog is:
|
||||
|
||||
|
||||
@@ -1032,6 +1032,8 @@ public partial class AppTests
|
||||
SendReadingKey(VirtualKeyShort.KEY_J);
|
||||
SendReadingKey(VirtualKeyShort.KEY_K);
|
||||
SendReadingKey(VirtualKeyShort.KEY_G);
|
||||
// FlaUI's input helper sleeps briefly; it does not acknowledge native text processing.
|
||||
session.WaitFor(() => string.Equals(query.AsTextBox().Text, "jkg", StringComparison.Ordinal) ? query : null, "the complete literal keyboard query 'jkg'");
|
||||
Assert.Equal("jkg", query.AsTextBox().Text);
|
||||
WaitForFindCount(session, "0 of 0");
|
||||
Assert.True(scroller.Patterns.Scroll.Pattern.VerticalScrollPercent.Value < 10);
|
||||
|
||||
Reference in new issue
Block a user