Skip to content

Allow to use global packages folder#15483

Closed
drognanar wants to merge 1 commit intomicrosoft:mainfrom
drognanar:global_packages
Closed

Allow to use global packages folder#15483
drognanar wants to merge 1 commit intomicrosoft:mainfrom
drognanar:global_packages

Conversation

@drognanar
Copy link
Member

Fixes #15469

Copilot AI review requested due to automatic review settings March 12, 2026 13:42
/// Gets the local NuGet cache directory used by test assets.
/// Test assets are restored into this directory by Build.cs via <c>dotnet restore --packages</c>.
/// </summary>
public static string TestAssetsNuGetCacheDirectory { get; } = Path.Combine(RepoRootDirectory, ".packages");
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
public static string TestAssetsNuGetCacheDirectory { get; } = Path.Combine(RepoRootDirectory, ".packages");
public static string TestAssetsNuGetCacheDirectory { get; } = Path.Combine(RepoRootDirectory, "artifacts", ".packages");

I'd move it here to make it less confusing. Tests are responsible for managing that folder.

Copy link
Member Author

Choose a reason for hiding this comment

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

this should now be moved

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Updates integration/acceptance test infrastructure to use a consistent, repo-local NuGet packages cache (.packages) without relying on pipeline-level NUGET_PACKAGES overrides, addressing #15469.

Changes:

  • Introduces a shared TestAssetsNuGetCacheDirectory and updates test code to use it instead of hardcoding .packages paths.
  • Forces restore for the acceptance integration tests project into the repo-local .packages folder and updates package content paths accordingly.
  • Removes NUGET_PACKAGES overrides from Azure Pipelines and adjusts NuGet.config/test config rewriting behavior.

Reviewed changes

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

Show a summary per file
File Description
test/Microsoft.TestPlatform.TestUtilities/IntegrationTestEnvironment.cs Adds a central .packages path constant and uses it for test package resolution.
test/Microsoft.TestPlatform.Acceptance.IntegrationTests/Microsoft.TestPlatform.Acceptance.IntegrationTests.csproj Sets restore/package content paths to use repo-local .packages.
test/Microsoft.TestPlatform.Acceptance.IntegrationTests/Extension/CompatibilityRowsBuilder.cs Switches hardcoded .packages path usage to the shared constant.
test/Microsoft.TestPlatform.Acceptance.IntegrationTests/Build.cs Uses the shared .packages path for test package operations.
test/Microsoft.TestPlatform.Acceptance.IntegrationTests/AcceptanceTestBase.cs Changes NuGet.config rewriting to inject globalPackagesFolder pointing to the shared .packages path.
azure-pipelines.yml Removes pipeline-level NUGET_PACKAGES override.
azure-pipelines-official.yml Removes pipeline-level NUGET_PACKAGES override.
NuGet.config Removes default globalPackagesFolder entry and updates comments to reflect new injection approach.

You can also share your feedback on Copilot code review. Take the survey.

Comment on lines +13 to +14
<!-- Restore packages to the local .packages directory so integration tests can find them at a known path. -->
<RestorePackagesPath>$(RepoRoot).packages\</RestorePackagesPath>
Copy link

Copilot AI Mar 12, 2026

Choose a reason for hiding this comment

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

$(RepoRoot).packages\... concatenates without a path separator between $(RepoRoot) and .packages, and it hardcodes backslashes (which can be treated as a literal character on non-Windows). This can produce an invalid restore/content path (e.g., C:\repo.packages\... or a path containing \ on Linux), breaking restore and file inclusion. Prefer building the path with an explicit separator (e.g., $(RepoRoot)\.packages\...) or via an MSBuild property using System.IO.Path::Combine and then reuse that property for both RestorePackagesPath and Content Include.

Copilot uses AI. Check for mistakes.
-->
<PackageReference Include="Microsoft.Internal.Dia" Version="$(TestPlatformMSDiaVersion)" PrivateAssets="all" />
<Content Include="..\..\.packages\microsoft.internal.dia\$(TestPlatformMSDiaVersion)\tools\net451\**\*">
<Content Include="$(RepoRoot).packages\microsoft.internal.dia\$(TestPlatformMSDiaVersion)\tools\net451\**\*">
Copy link

Copilot AI Mar 12, 2026

Choose a reason for hiding this comment

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

$(RepoRoot).packages\... concatenates without a path separator between $(RepoRoot) and .packages, and it hardcodes backslashes (which can be treated as a literal character on non-Windows). This can produce an invalid restore/content path (e.g., C:\repo.packages\... or a path containing \ on Linux), breaking restore and file inclusion. Prefer building the path with an explicit separator (e.g., $(RepoRoot)\.packages\...) or via an MSBuild property using System.IO.Path::Combine and then reuse that property for both RestorePackagesPath and Content Include.

Copilot uses AI. Check for mistakes.
Comment on lines +172 to +173
// Point packages folder to vstest's local .packages cache used by test assets.
.Replace("</config>", $"""<add key="globalPackagesFolder" value="{IntegrationTestEnvironment.TestAssetsNuGetCacheDirectory}" /></config>""")
Copy link

Copilot AI Mar 12, 2026

Choose a reason for hiding this comment

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

This injects XML via a string replace on </config>, which is fragile if the copied NuGet.config formatting changes (e.g., whitespace variations, self-closing tags, or additional </config> occurrences from future edits). A more robust approach is to load the file as XML (e.g., XDocument), locate/create the <config> element, and add the <add key="globalPackagesFolder" ... /> node before saving.

Copilot uses AI. Check for mistakes.
<OutputType>Exe</OutputType>
<TargetFrameworks>net9.0;net48</TargetFrameworks>
<!-- Restore packages to the local .packages directory so integration tests can find them at a known path. -->
<RestorePackagesPath>$(RepoRoot).packages\</RestorePackagesPath>
Copy link
Member

Choose a reason for hiding this comment

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

Is this only for the msdia dependency below?

Copy link
Member Author

Choose a reason for hiding this comment

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

pretty much. also reading through how integration tests work.

so far my understanding is that with the global cache:

  1. the Build.cs will handle preparing the artifacts/.packages folder for all acceptance tests. there's a method that will remove all -dev packages before the test runs
  2. test assets such as CLIProject, MSTestV1UnitTestProject, LegacySettingsUnitTestProject are all using the local .packages cacheDid

it would seem that we can fully make this use the global cache. running all tests to validate that this works

Copy link
Member

Choose a reason for hiding this comment

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

Yeah I think the only "problem" here is figuring out where the global cache is, but maybe we could get rid of all the dependencies on that package instead. I am not if the tests are testing something that an integration test does not test.

- Remove globalPackagesFolder from NuGet.config so the main solution build
  uses the default global NuGet cache (~/.nuget/packages/).
- Remove NUGET_PACKAGES overrides from CI pipelines.
- Move test asset NuGet cache from .packages/ to artifacts/.packages/ so it
  lives under the already-gitignored artifacts/ directory.
- Test assets (built by Build.cs) continue to restore into the local cache
  via explicit --packages flag.
- Update AcceptanceTestBase to inject globalPackagesFolder into copied
  NuGet.config for isolated test asset builds.
- Fix msdia Content Include to use $(NuGetPackageRoot) since it is
  restored by the solution build, not by Build.cs test asset restoration.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@nohwnd
Copy link
Member

nohwnd commented Mar 13, 2026

Will merge after #15484 , I touched the same files

@drognanar
Copy link
Member Author

I've applied the feedback.

We should now be using artifacts/.packages, and only use that for the integration test samples (so if integration tests are not being run things should be good).

@nohwnd
Copy link
Member

nohwnd commented Mar 16, 2026

There were too many conflicts, moved your code to new PR, sorry for "stealing it".

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.

Use global package cache instead of .packages

3 participants