Skip to content

Explicit Microsoft.SourceLink.GitHub PackageReference silently disables SourceLink on .NET 8+ SDKs #1652

@thomhurst

Description

@thomhurst

Summary

On SDKs that bundle SourceLink as implicit SDKs (.NET 8+), adding an explicit <PackageReference Include=\"Microsoft.SourceLink.GitHub\" PrivateAssets=\"all\" /> silently disables SourceLink rather than enabling or replacing it. Build succeeds with no warnings, but resulting packages have:

  • No SourceLink JSON in the PDB
  • No PathMap normalization (paths remain non-deterministic)
  • Reproducible debug entry is still set, so the PE looks deterministic by header, but embedded source paths are not mapped

The docs (both the README and many blog posts/templates) still instruct users to add this package. On a modern SDK, following that guidance breaks SourceLink.

Environment

  • .NET SDK: 10.0.202 (also confirmed in 11.0.100-preview.2)
  • Microsoft.SourceLink.GitHub NuGet package: 10.0.202
  • Central Package Management via Directory.Packages.props with GlobalPackageReference
  • Strong-named, multi-targeted library (netstandard2.0;net8.0;net9.0;net10.0)

Reproduction

Directory.Packages.props:

<Project>
  <PropertyGroup>
    <ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>
  </PropertyGroup>
  <ItemGroup>
    <GlobalPackageReference Include=\"Microsoft.SourceLink.GitHub\" Version=\"10.0.202\" PrivateAssets=\"all\" />
  </ItemGroup>
</Project>

Directory.Build.props:

<Project>
  <PropertyGroup>
    <ContinuousIntegrationBuild>true</ContinuousIntegrationBuild>
    <PublishRepositoryUrl>true</PublishRepositoryUrl>
    <EmbedUntrackedSources>true</EmbedUntrackedSources>
  </PropertyGroup>
</Project>

Then dotnet build -c Release. Inspect the produced PDB — no SourceLink custom debug information entry (CC110556-A091-4D38-9FEC-25AB9A351A6A), no obj/*/*.sourcelink.json file.

Root cause trace

  1. NuGet restores Microsoft.SourceLink.GitHub directly and imports its build/Microsoft.SourceLink.GitHub.props/.targets.
  2. Its transitive deps (Microsoft.SourceLink.Common, Microsoft.Build.Tasks.Git) resolve in project.assets.json as \"buildTransitive/_._\": {} — the empty-assets marker — because developmentDependency=true packages don't flow their build assets through a PrivateAssets=all parent. Common's InitializeSourceControlInformation.targets / Microsoft.SourceLink.Common.targets never get imported via NuGet.
  3. NuGet still generates the PkgMicrosoft_SourceLink_Common path property (from restore), even though its build assets are _._.
  4. The SDK-bundled Microsoft.NET.Sdk.SourceLink.props contains:
    <SuppressImplicitGitSourceLink Condition=\"'$(PkgMicrosoft_SourceLink_Common)' != ''\">true</SuppressImplicitGitSourceLink>
    <ImportGroup Condition=\"'$(SuppressImplicitGitSourceLink)' != 'true'\">
      <Import Project=\"...\Microsoft.Build.Tasks.Git\build\Microsoft.Build.Tasks.Git.props\" />
      <Import Project=\"...\Microsoft.SourceLink.Common\build\Microsoft.SourceLink.Common.props\" />
      <Import Project=\"...\Microsoft.SourceLink.GitHub\build\Microsoft.SourceLink.GitHub.props\" />
      ...
    </ImportGroup>
    Because PkgMicrosoft_SourceLink_Common is now set, SuppressImplicitGitSourceLink=true fires → SDK's bundled Common and Microsoft.Build.Tasks.Git imports are skipped.

Net result: GitHub.targets is imported alone, without the LocateRepository task or the InitializeSourceControlInformationFromSourceControlManager target. @(SourceRoot) is never populated → _GenerateSourceLinkFile does nothing → /sourcelink: switch is never passed to csc → no SourceLink CDI in PDB → paths are not PathMap-normalized.

Full preprocess (msbuild -pp) and PE-debug-directory verification available in thomhurst/TUnit#5579.

Fix that worked for us

Remove the explicit Microsoft.SourceLink.GitHub PackageReference entirely. The SDK then auto-imports Common + Build.Tasks.Git + GitHub from $(DotnetRoot)/sdk/<ver>/Sdks/Microsoft.SourceLink.*, and everything works.

Suggested improvements

Any one of these would have made this far easier to diagnose:

  1. Docs: Update the README to say "on .NET SDK 8+, don't add Microsoft.SourceLink.GitHub — it's implicit; add it only for older SDKs or custom hosts."
  2. Warning: Have Microsoft.SourceLink.GitHub.targets emit a warning if it's imported but Microsoft.SourceLink.Common.targets hasn't been imported (detectable by a well-known property set in Common's targets). This would catch the buildTransitive/_._ scenario.
  3. Suppression condition: Narrow the SDK's SuppressImplicitGitSourceLink check so it only fires when Common's build assets actually imported, not merely when the Pkg* path property is set (since NuGet sets that even for _._ assets).

Happy to contribute a docs PR if helpful.

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions