Maintenance release v1.1.0: .NET 10, defect fixes, CI and repo hardening - #11
Merged
Conversation
.NET 9 enters EOL on 2026-11-10. Because FieldKit publishes SelfContained + PublishSingleFile, the runtime is baked into the exe, so every download after that date would ship an unpatched runtime with no servicing path. .NET 10 is LTS through 2028-11-14. - TargetFramework net9.0-windows -> net10.0-windows - System.Management and System.ServiceProcess.ServiceController 9.0.0 -> 10.0.11 (supersedes stale Dependabot PRs #9 and #10, which proposed 10.0.9) - Version 1.0.0 -> 1.1.0, app.manifest assemblyIdentity to match - Pin the SDK in global.json so the build is reproducible rather than floating to whatever SDK is newest on the machine - Update README build instructions and ROADMAP UI note Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
MainWindow's parameterless constructor created a Logger, and the real constructor chained through it via `: this()` before overwriting the field. The orphaned Logger opened a StreamWriter that nothing ever disposed. The symptom was on disk: five zero-byte FieldKit-*.log files in the build output directory, one per app launch. App already held the %TEMP% log path with FileShare.Read, so the orphan's open failed, the Logger constructor's fallback swallowed it, and it landed in AppContext.BaseDirectory instead. App.xaml uses Startup= with no StartupUri, so MainWindow is only ever constructed through the two-arg overload. The parameterless constructor is deleted rather than patched. Also adds a DispatcherUnhandledException handler. Tasks already catch their own failures, so anything reaching it is a UI-layer bug; the app now logs it and keeps the log path visible instead of vanishing. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
`dotnet build` never exercised single-file packing, self-contained runtime bundling, or compression, so CI was green on a configuration that is not the one released. Adds a publish step plus a size assertion that fails if the self-contained runtime goes missing. - dotnet-version 9.0.x -> 10.0.x - actions/checkout v5 -> v7, actions/setup-dotnet v4 -> v6 - gitignore publish/ so the new output directory stays untracked Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Closes three Material gaps from the pre-publish repo audit run for the v1.1.0 release. - CodeQL static analysis on push, PR, and a weekly schedule. Uses manual build mode rather than buildless so the analyzer gets full type resolution across the partial classes WPF generates from XAML. Pinned to codeql-action v4 (the repo's "latest" release is a bundle tag, not the action major). - CHANGELOG.md covering v1.0.0 and v1.1.0, in Keep a Changelog format. - Issue forms for bugs and features, a PR template, and a security contact link that routes reports to the private advisory flow instead of a public issue. - README: .NET badge 9.0 -> 10.0, and a changelog link from Download. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The analyze step reads workflow run metadata; without actions:read it fails on some repo configurations. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
You are seeing this message because GitHub Code Scanning has recently been set up for this repository, or this pull request contains the workflow file for the Code Scanning tool. What Enabling Code Scanning Means:
For more information about GitHub Code Scanning, check out the documentation. |
Review of the previous commit found that the new DispatcherUnhandledException handler turned a crash into a false success report. RunSelectedTasksAsync's finally block unconditionally set the status bar to "Run complete" and the progress bar to 100%, and ShowCompletionSummary sat outside that finally. So an exception escaping the loop meant: remaining operations never ran, the in-flight row stayed "Running", no summary appeared -- and the UI asserted the run had finished. Before the handler existed the process died, which is wrong but unmistakable. The run loop now owns its own failure: logs the abort, marks unfinished operations "Aborted", shows a distinct dialog, and reports "Run aborted" at 0%. Verified with a structural harness covering clean run, escaped exception, and contained task failure -- 7/7 assertions. Two related fixes: - The handler was subscribed before the startup sequence, contradicting its own doc comment and killing the deliberate Shutdown(1) path for failures inside the disclaimer dialog. It now subscribes after the main window shows. - Closing the window mid-run called _runCts.Dispose() while the run loop still read the token, so every remaining operation failed with ObjectDisposedException -- reading in the log as many broken operations rather than one lifecycle bug. Now cancels and lets the loop dispose. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The publish check asserted only that FieldKit.exe existed and was >= 20 MB. Measured: publishing with IncludeNativeLibrariesForSelfExtract=false yields a 58.8 MB exe that passes that floor while scattering five native DLLs beside it (D3DCompiler_47_cor3, PenImc_cor3, PresentationNative_cor3, vcruntime140_cor3, wpfgfx_cor3). Uploading just the exe would then ship a requireAdministrator binary that resolves those from its launch directory. The check now asserts the publish directory contains nothing but the exe and its pdb, with a size band rather than a one-sided floor. - Retain the published exe as a build artifact. It was previously destroyed with the runner, so a failed assertion left nothing to inspect and the exe was never smoke-tested off the author's machine. - global.json claimed to pin the SDK; rollForward latestFeature is a floor, not a pin, so both the README and CHANGELOG asserted a guarantee the config disabled. Kept as a floor -- the SDK in use determines which runtime is embedded in the self-contained exe, and a self-contained app only gets runtime fixes when rebuilt -- and lowered it to 10.0.100 so contributors on the GA SDK are not blocked. Docs now describe it as a minimum. - CodeQL also analyzes `actions`. GitHub already identifies this repo as having analyzable workflows, so the three workflow files added in this branch were the one thing it added scanning for that went unscanned. - Dependabot now covers the github-actions ecosystem; without it the action pins get no update PRs and drift silently. - Explicit permissions block on build.yml. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This was referenced Aug 15, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What this changes
Maintenance release. No new operations — this moves the runtime off a version heading for end of support, fixes two defects, and closes the Material gaps from the pre-publish repo audit.
Why
.NET 9 reaches end of support on 2026-11-10. FieldKit publishes as
SelfContained+PublishSingleFile, so the runtime is embedded in the shipped exe — every download after that date would have carried an unpatched runtime with no servicing path. .NET 10 is LTS through 2028-11-14.Contents
b9092e5global.jsonc1de7f9Logger; handle unhandled UI exceptionsfaf0f4cb3a91b6CHANGELOG.md, issue and PR templates0cb5977actions: readpermissionThe Logger defect
MainWindow's parameterless constructor created aLogger, and the real constructor chained through it via: this()before overwriting the field. The orphan opened aStreamWriterthat nothing ever disposed.The symptom was on disk: five zero-byte
FieldKit-*.logfiles in the build output directory, one per launch.Appalready held the%TEMP%log path withFileShare.Read, so the orphan's open failed, theLoggerconstructor's fallback swallowed it, and it landed inAppContext.BaseDirectoryinstead.App.xamlusesStartup=with noStartupUri, soMainWindowis only ever built through the two-arg overload — the parameterless constructor is deleted rather than patched.Why CI changed
dotnet buildnever exercised single-file packing, self-contained runtime bundling, or compression, so CI was green on a configuration that is not the one released. There is now a publish step and a size assertion that fails if the self-contained runtime goes missing.How it was verified
dotnet build FieldKit.sln --configuration Release— 0 warnings, 0 errors on SDK 10.0.400dotnet publishproduces a 63 MB single-file exe;FileVersionreads1.1.0.0Notes for the reviewer
Pre-publish audit evidence:
Notes/ATLAS/analysis/github-repo-audit_tsudo-fieldkit_2026-08-15.md(paved-road runPR-20260814-001).Not in scope, deliberately: the dead
dryRunplumbing (32 references across 12 task classes, left behind when Preview Only was removed ina6d6ff3) — kept separate so the runtime upgrade stays bisectable.