Show folder-mode discovery breadcrumb only at debug verbosity - #730
Merged
Nikola Metulev (nmetulev) merged 3 commits intoAug 11, 2026
Merged
Conversation
`winapp run` printed "No .csproj/.sln/.slnx with a runnable app found in
'<path>' - running it as a build-output folder." at Information level whenever
the input resolved to a directory.
That path is not exceptional. It is what every `dotnet run` through the
Microsoft.Windows.SDK.BuildTools.WinApp package does, because the targets point
winapp at $(OutputPath). The result was a scary-looking line on a completely
routine, successful run:
> dotnet run -- --devtools
No .csproj/.sln/.slnx with a runnable app found in '...\win-x64' - running
it as a build-output folder.
App launched (PID: 33808)
The message is still useful when someone points at a source directory expecting
a build and wants to know why nothing was built, so it moves to Debug rather
than being removed - `--verbose` still shows it.
RunCommandTests runs at LogLevel.Debug, so it cannot observe default-verbosity
output. A companion class pinned to LogLevel.Information covers the suppression;
it fails if the level is moved back to Information.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: a209763e-7185-4986-bf0b-98e52c06b4be
Copilot started reviewing on behalf of
Alexandre Zollinger Chohfi (azchohfi)
August 11, 2026 21:54
View session
Contributor
There was a problem hiding this comment.
Pull request overview
Moves the folder-mode discovery breadcrumb to debug verbosity while retaining troubleshooting visibility via --verbose.
Changes:
- Gates the breadcrumb on
LogLevel.Debug. - Adds tests for debug and default verbosity behavior.
- Reuses shared manifest test data.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.
| File | Description |
|---|---|
RunCommand.cs |
Restricts the breadcrumb to debug verbosity. |
RunCommandTests.cs |
Verifies breadcrumb visibility at debug and Information levels. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Two review follow-ups: - The check-docs gate requires a docs update alongside a CLI change. Because the breadcrumb is now debug-only, `docs/usage.md` explains how to surface it: the `winapp run` section already describes folder-vs-project mode selection, so the note lives there and points at --verbose for diagnosing an unexpected mode. - Code-quality flagged Path.Combine for silently dropping earlier arguments when a later segment is rooted. Path.Join has no such behavior and is what the rest of the test project uses. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: a209763e-7185-4986-bf0b-98e52c06b4be
Contributor
Build Metrics ReportBinary Sizes
Test Results❌ 4550 passed, 1 failed, 5 skipped out of 4556 tests in 665.2s (+2 tests, +20.1s vs. baseline) Test Coverage✅ 89.1% line coverage, 82.4% branch coverage · ✅ no change vs. baseline CLI Startup Time50ms median (x64, Updated 2026-08-11 22:24:35 UTC · commit |
Nikola Metulev (nmetulev)
approved these changes
Aug 11, 2026
Nikola Metulev (nmetulev)
deleted the
azchohfi-folder-mode-breadcrumb-debug
branch
August 11, 2026 22:47
Nikola Metulev (nmetulev)
pushed a commit
that referenced
this pull request
Aug 12, 2026
## Problem `RunDotnetProcessAsync_Cancellation_KillsProcessTree` fails intermittently on CI — it just took down `build-and-package` on #730, which is a docs/logging-only PR: ``` System.IO.IOException: The process cannot access the file '...\winapp_treekill_dff98ff32ad34e73be394cf6119af1dc.pid' because it is being used by another process. at System.IO.File.InternalReadAllTextAsync(...) at DotNetServiceTests.WaitForPidFileAsync(...) DotNetServiceTests.cs:1864 at DotNetServiceTests.RunDotnetProcessAsync_Cancellation_KillsProcessTree() ...:1748 ``` ## Root cause `WaitForPidFileAsync` polls for the PID file the spawned PowerShell root writes with `Set-Content`: ```csharp if (File.Exists(pidFile)) { var text = (await File.ReadAllTextAsync(pidFile, cancellationToken)).Trim(); // ← throws ``` `File.Exists` turns true the instant `Set-Content` **creates** the file, but PowerShell still holds the write handle for a short window afterwards. A read landing inside that window fails with a sharing violation, and the exception escaped the polling loop instead of being treated as "not ready yet". Reproduced directly rather than inferred: ```powershell $fs = [System.IO.File]::Open($pidFile, 'Create', 'Write', 'None') [System.IO.File]::Exists($pidFile) # True [System.IO.File]::ReadAllText($pidFile) # IOException: ... being used by another process ``` That is exactly the CI error, and it explains why it's load-dependent: the window is tiny, so it only loses the race on a busy agent. ## Fix Catch the transient IO failure and keep polling. A sharing violation here means "not written yet" — precisely the condition the loop already exists to wait out. An empty or partially written file needed no new handling: the existing `int.TryParse` guard already keeps polling until the value parses. ## Validation - Target test passed 3/3 locally after the change. - `WaitForPidFileAsync` has exactly one caller, so the blast radius is that one test. - No docs needed: `check-docs` keys off `src/winapp-CLI/**/Commands/`, and this is test-only. --------- Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: a209763e-7185-4986-bf0b-98e52c06b4be
This was referenced Aug 14, 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.
Problem
winapp runprinted this at Information level (the default verbosity) whenever the input resolved to a directory:That path isn't exceptional — it's what every
dotnet runthrough theMicrosoft.Windows.SDK.BuildTools.WinApppackage does, because the targets point winapp at$(OutputPath). So a completely routine, successful run looked like something had gone wrong:Change
One line — the breadcrumb moves from
LogLevel.InformationtoLogLevel.Debug.It isn't removed, because it still earns its place: it's how someone who pointed at a source directory expecting a build discovers why nothing was built.
--verbosestill shows it.Tests
RunCommandTestsruns atLogLevel.Debug(the level--verboseselects), so it structurally cannot observe what a default-verbosity run prints — a test added there would have passed before and after this change.So there are two:
RunCommand_FolderMode_AtDebugVerbosity_PrintsDiscoveryBreadcrumbDebug--verboseRunCommand_FolderMode_AtDefaultVerbosity_OmitsDiscoveryBreadcrumbInformationThe second lives in a small companion class pinned to
LogLevel.Information, following the existingBuildToolsServicePrintErrorsTestspattern. I verified it genuinely pins the behavior by reverting the production line toInformationand confirming it fails, then restoring it.TestManifestContentchangedprivate→internalso the companion class can reuse it rather than duplicating the manifest XML.Validation
10/10 tests pass in the affected area. Regression check confirmed the new test fails without the fix.