Skip to content

Discover --update-packages candidates from restore feeds - #137

Draft
georgepwall1991 wants to merge 1 commit into
mainfrom
cursor/feed-faithful-package-updates-af32
Draft

georgepwall1991 wants to merge 1 commit into
mainfrom
cursor/feed-faithful-package-updates-af32

Conversation

@georgepwall1991

Copy link
Copy Markdown
Owner

--update-packages used to learn "latest version" by HTTP-GETting api.nuget.org/v3-flatcontainer for every pin in Directory.Packages.props. NuGet.Config was never read.

That had two silent-wrong outcomes:

  1. Private-feed packages looked up to date. A package that lives only on Azure Artifacts, GitHub Packages, Artifactory, or an air-gapped mirror returned 404. The lookup treated that as "does not exist" and did not record a failed check, so an org whose internal packages were all behind heard Everything up to date!.
  2. Dependency confusion. If anyone published Contoso.Core 99.0.0 on nuget.org, CPMigrate proposed that upgrade, wrote it into the props file, and --bisect would keep it if tests stayed green.

--outdated, --audit, --deprecated, and --licenses already go through dotnet, which honours NuGet.Config, credential providers, and source mapping. --update-packages now does the same.

What changed

  • New IUpdateCandidateSource / RestoreBackedUpdateCandidateSource runs ScanOutdatedPackagesAsync per project through GroupedScanScheduler. "Latest" is dotnet list package --outdated against the caller's feeds.
  • A package present in the props file but absent from every outdated row is simply not a candidate (the dependency-confusion guard).
  • Fail closed: any project whose outdated scan does not finish exits 8 (IncompleteAnalysis), prints the project names plus "A project that cannot restore against your configured feeds cannot be updated safely.", and writes nothing — no backup, no props edit, including --dry-run and --output Json.
  • Removed NuGetVersionLookupService, INuGetVersionLookupService, and NuGetRetryPolicy. Self-update (cpmigrate --update) still talks to nuget.org, which is where CPMigrate itself is published.
  • --doctor enumerates enabled sources via dotnet nuget list source --format Detailed and probes each HTTP source (200 = reachable, 401/403 = authenticated, anything else names the source). Falls back to the nuget.org service-index probe only when listing fails.

Tests

  • RestoreBackedUpdateCandidateSourceTests: highest-wins merge, direct vs transitive, prerelease pass-through, one failed project in UnscannedProjects, completion-order independence, bounded peak concurrency.
  • Fail-closed: one unscanned project → exit 8, props bytes unchanged, IBackupManager never called (including dry-run and JSON).
  • Private-feed: a props pin absent from every outdated row is never proposed.
  • Doctor source enumeration and per-source status rendering.
  • Existing PackageUpdateService* fixtures migrated from INuGetVersionLookupService mocks to FakeUpdateCandidateSource.

No output schema bump: Warnings and integer exitCode already exist. Exit 8 for --update-packages is a deliberate contract change so this path matches every other scan.

Open in Web Open in Cursor 

Replace the nuget.org-only HTTP lookup with dotnet list package --outdated
so NuGet.Config sources, credentials, and source mapping decide "latest".
Fail closed (exit 8) when any project cannot be scanned, and probe every
configured source from --doctor instead of claiming nuget.org is reachable.

Co-authored-by: George Wall <georgepwall1991@users.noreply.github.com>

This branch has not been deployed

No deployments
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.

2 participants