Skip to content

Revert NuGet-client migration (#629, #647) to unblock ADO main builds - #654

Merged
Alexandre Zollinger Chohfi (azchohfi) merged 3 commits into
mainfrom
azchohfi-revert-nuget-client-migration
Jul 16, 2026
Merged

Revert NuGet-client migration (#629, #647) to unblock ADO main builds#654
Alexandre Zollinger Chohfi (azchohfi) merged 3 commits into
mainfrom
azchohfi-revert-nuget-client-migration

Conversation

@azchohfi

Copy link
Copy Markdown
Contributor

Reverts the NuGet-client migration (#629) and its stacked coverage PR (#647).

Tracks #653.

Why

After migrating NugetService to the official NuGet client libraries, main builds fail on ADO due to a security issue: #629 pins the NuGet.* packages to the prerelease 7.9.0-rc.36120 sourced from the dnceng dotnet-tools public feed (not nuget.org). The security gate flags consuming a prerelease from a secondary public feed. This was always intended as temporary — the NuGet.UseSystemTextJsonDeserialization switch needed to keep the Native AOT publish clean isn't in a nuget.org stable yet.

What this reverts

Conflict resolution notes

Several coverage PRs merged after #629 built on top of its surface, so a plain revert left conflicts. Resolved as follows:

Validation

  • dotnet build winapp.sln -c Debug0 warnings / 0 errors
  • Test project builds clean; UI-command and NuGet-service test suites pass (447 passed / 0 failed / 1 skipped).
  • No remaining references to dotnet-tools, 7.9.0, or packageSourceMapping in nuget.config / Directory.Packages.props / .pipelines/release-nuget.config.

Re-landing

This migration should be reapplied only once stable NuGet.Protocol 7.9.0 and all related NuGet.* packages are published on nuget.org (not on dnceng dotnet-tools or any other secondary public feed). At that point: repoint the pins to the nuget.org stable, and drop the dotnet-tools source, packageSourceMapping, and the release-nuget.config upstream. See #653.

Copilot AI review requested due to automatic review settings July 16, 2026 18:30

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Reverts the NuGet-client migration and related coverage to remove prerelease NuGet.* dependencies that block ADO builds.

Changes:

  • Restores the hand-rolled NuGet service.
  • Removes NuGet-client packages, feeds, configuration, and tests.
  • Reverts related documentation and update/cache behavior.

Reviewed changes

Copilot reviewed 35 out of 35 changed files in this pull request and generated 8 comments.

Show a summary per file
File Description
src/winapp-CLI/WinApp.Cli/WinApp.Cli.csproj Removes NuGet-client dependencies and AOT switch.
src/winapp-CLI/WinApp.Cli/Services/WorkspaceSetupService.cs Removes NuGet configuration rooting.
src/winapp-CLI/WinApp.Cli/Services/PackageInstallationService.cs Restores legacy cache/dependency handling.
src/winapp-CLI/WinApp.Cli/Services/NugetSourceProvider.cs Deletes configured-source support.
src/winapp-CLI/WinApp.Cli/Services/NugetService.Dependencies.cs Deletes client-based dependency resolver.
src/winapp-CLI/WinApp.Cli/Services/NugetPackageDownloader.cs Deletes client-based downloader.
src/winapp-CLI/WinApp.Cli/Services/INugetService.cs Restores legacy interface contract.
src/winapp-CLI/WinApp.Cli/Services/BuildToolsService.cs Removes pinned-version normalization.
src/winapp-CLI/WinApp.Cli/Helpers/HostBuilderExtensions.cs Removes deleted service registrations.
src/winapp-CLI/WinApp.Cli/Commands/UpdateCommand.cs Restores legacy update behavior.
src/winapp-CLI/WinApp.Cli.Tests/WorkspaceSetupServiceConfigRootTests.cs Deletes configuration-root tests.
src/winapp-CLI/WinApp.Cli.Tests/WinApp.Cli.Tests.csproj Removes NuGet AOT test switch.
src/winapp-CLI/WinApp.Cli.Tests/UpdateCommandTests.cs Deletes update-command coverage.
src/winapp-CLI/WinApp.Cli.Tests/PackageInstallationServiceTests.cs Deletes installation-service coverage.
src/winapp-CLI/WinApp.Cli.Tests/NugetServiceVersionRangeTests.cs Deletes range-resolution tests.
src/winapp-CLI/WinApp.Cli.Tests/NugetServiceTests.cs Restores legacy NuSpec tests.
src/winapp-CLI/WinApp.Cli.Tests/NugetServiceInstallGraphTests.cs Deletes graph-integrity tests.
src/winapp-CLI/WinApp.Cli.Tests/NugetServiceFeedTests.cs Deletes custom-feed tests.
src/winapp-CLI/WinApp.Cli.Tests/NugetServiceDependencyTests.cs Deletes dependency-resolution tests.
src/winapp-CLI/WinApp.Cli.Tests/NugetServiceCoverageTests.cs Deletes migration coverage.
src/winapp-CLI/WinApp.Cli.Tests/NugetPackageDownloaderCoverageTests.cs Deletes downloader coverage.
src/winapp-CLI/WinApp.Cli.Tests/NugetFeedTestHelpers.cs Deletes local-feed helpers.
src/winapp-CLI/WinApp.Cli.Tests/FakeNugetService.cs Restores the legacy fake.
src/winapp-CLI/WinApp.Cli.Tests/BuildToolsServiceTests.cs Removes normalization regression test.
src/winapp-CLI/WinApp.Cli.Tests/BaseCommandTests.cs Removes cancellation-token overload.
src/winapp-CLI/Directory.Packages.props Removes prerelease NuGet pins.
nuget.config Removes secondary feed and source mapping.
docs/usage.md Removes private-feed documentation.
docs/fragments/skills/winapp-cli/setup.md Removes private-feed guidance.
docs/dotnet-run-support.md Restores AOT blocker text.
.pipelines/release-nuget.config Removes upstream-feed explanation.
.github/plugin/skills/winapp-cli/setup/SKILL.md Synchronizes generated setup guidance.
.claude/skills/winapp-setup/SKILL.md Synchronizes Claude setup guidance.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +93 to +98
protected async Task<int> ParseAndInvokeWithCaptureAsync(Command command, string[] manifestArgs)
=> await ParseAndInvokeWithCaptureAsync(command, manifestArgs, TestContext.CancellationToken);

/// <summary>
/// Overload that invokes with a caller-supplied cancellation token (e.g. a pre-cancelled one) so
/// tests can exercise a command's <see cref="OperationCanceledException"/> handling deterministically.
/// </summary>
protected async Task<int> ParseAndInvokeWithCaptureAsync(Command command, string[] manifestArgs, CancellationToken cancellationToken)
{
var parseResult = command.Parse(manifestArgs);
parseResult.InvocationConfiguration.Output = TestAnsiConsole.Profile.Out.Writer;
parseResult.InvocationConfiguration.Error = ConsoleStdErr;
return await parseResult.InvokeAsync(parseResult.InvocationConfiguration, cancellationToken: cancellationToken);
return await parseResult.InvokeAsync(parseResult.InvocationConfiguration, cancellationToken: TestContext.CancellationToken);
/// Returns the directory for a specific package version in the NuGet global packages cache.
/// Uses the standard NuGet layout: {cache}/{lowercase-id}/{version}/
/// </summary>
DirectoryInfo GetNuGetPackageDir(string packageName, string version);
Comment on lines +51 to +53
// Check if already installed in NuGet global cache
var packageDir = nugetService.GetNuGetPackageDir(packageName, version);
if (packageDir.Exists)
// version (e.g. "1.0" vs "1.0.0") spuriously counting as an update,
// and a lower "latest" ever silently downgrading the pinned version.
if (NugetService.CompareVersions(latestVersion, package.Version) > 0)
if (latestVersion != package.Version)
Comment on lines 78 to 82
catch (Exception ex)
{
taskContext.AddStatusMessage($"{UiSymbols.Warning} Failed to check {package.Name}: {ex.Message}");
// Keep current version on error, but remember the failure so the
// command exits non-zero and does not claim everything is up to date.
// Keep current version on error
updatedConfig.SetVersion(package.Name, package.Version);
Comment on lines +177 to +181
The CLI currently has NativeAOT compilation errors related to Newtonsoft.Json and NuGet.Protocol. These must be resolved before the NuGet package can include the CLI binaries.

**Error summary:**
- 146 trim/AOT analysis errors
- Related to reflection-heavy code in Newtonsoft.Json
Comment on lines +113 to +116
// Check if already installed in NuGet global cache
var packageDir = nugetService.GetNuGetPackageDir(packageName, version);
if (packageDir.Exists)
{
Comment on lines +112 to 114
// Already installed on disk?
if (packageDir.Exists)
{
@github-actions

github-actions Bot commented Jul 16, 2026

Copy link
Copy Markdown
Contributor

Build in progress — metrics below are from a previous commit and will update when the current build finishes.

Build Metrics Report

Binary Sizes

Artifact Baseline Current Delta
CLI (ARM64) 36.77 MB 32.38 MB 📉 -4.40 MB (-11.96%)
CLI (x64) 36.95 MB 32.69 MB 📉 -4.26 MB (-11.54%)
MSIX (ARM64) 15.36 MB 13.57 MB 📉 -1.79 MB (-11.66%)
MSIX (x64) 16.30 MB 14.41 MB 📉 -1.89 MB (-11.58%)
NPM Package 32.06 MB 28.30 MB 📉 -3.76 MB (-11.72%)
NuGet Package 32.09 MB 28.32 MB 📉 -3.77 MB (-11.74%)

Test Results

3224 passed, 4 skipped out of 3228 tests in 566.1s (-114 tests, -171.5s vs. baseline)

Test Coverage

85.2% line coverage, 79.1% branch coverage · ⚠️ -1.1% vs. baseline

CLI Startup Time

42ms median (x64, winapp --version) · ✅ -7ms vs. baseline


Updated 2026-07-16 19:03:18 UTC · commit 1ca10dc · workflow run

…629)"

This reverts the NuGet-client migration (#629) to unblock ADO main builds,
which fail on the prerelease NuGet.* 7.9.0-rc packages sourced from the
dnceng dotnet-tools feed (not nuget.org). See #653.

Conflict resolution for coverage PRs that landed on top of #629:
- FakeNugetService.cs restored to its pre-#629 form.
- BaseCommandTests.cs: reverted #629 changes but kept the generic
  ParseAndInvokeWithCaptureAsync(..., CancellationToken) overload, which is
  unrelated test infra used by UI-command cancellation tests (#645).
- Deleted PackageInstallationServiceTests.cs and UpdateCommandTests.cs
  (new in #629; later expanded by #640/#641 for the migrated code).
- Deleted PackageInstallationServiceCacheMarkerTests.cs (added by #641;
  exercised the migrated NugetService via now-removed NugetFeedTestHelpers
  and INugetService.IsPackageInstalled).

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: d55408ba-4e7d-41aa-95a0-f7c801632eaf
@azchohfi
Alexandre Zollinger Chohfi (azchohfi) force-pushed the azchohfi-revert-nuget-client-migration branch from db896e4 to 1ca10dc Compare July 16, 2026 18:42
@azchohfi
Alexandre Zollinger Chohfi (azchohfi) merged commit c46d03b into main Jul 16, 2026
20 checks passed
@azchohfi
Alexandre Zollinger Chohfi (azchohfi) deleted the azchohfi-revert-nuget-client-migration branch July 16, 2026 20:39
Alexandre Zollinger Chohfi (azchohfi) added a commit that referenced this pull request Jul 17, 2026
… (#671)

Raise NuGet/update/install per-file coverage to >=95% (#630)

Bucket 2 of the QA-gate follow-up wave — re-covers the pre-migration NuGet
client that #654 restored.

Coverage: UpdateCommand.cs 100%, PackageInstallationService.cs 100%,
NugetService.cs 99.4% (only the unreachable InstallPackageRecursiveAsync
present-key guard remains, documented via <remarks> #630).

Product (behavior-preserving test seams only):
- GetUserProfileDirectory seam so the %USERPROFILE% fallback is hermetically
  testable (eliminates a documented ceiling).
- HttpGetAsync seam (default delegate = HttpClient.GetAsync) so restore/
  download/version-resolution run offline against canned responses.
- Normalize transitive dependency version ranges via ParseMinimumVersion
  before recursing, and skip the fetch when the minimum is empty (open
  lower-bound ranges like "(,2.0.0]"), mirroring the on-disk
  ResolveDependenciesAsync guard. Prevents a malformed flat-container URL that
  silently dropped transitive deps. No-op for exact versions.

Tests: NugetServiceOfflineTests (restore/download/transitive/diamond-dedup/
version-filtering/nuspec-parsing/HTTP-error/open-lower-bound guard),
PackageInstallationServiceTests, UpdateCommandTests. Debug + Release
(both projects, warnings-as-errors) 0W/0E.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants