Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Nuget private source - possible to set condition in PackageReference?

Tags:

c#

.net

nuget

I'm setting up a private nuget source via github. All is working well, using a nuget.config like this (credentials section redacted):

<configuration>
  <packageSources>
    <add key="github" value="https://nuget.pkg.github.com/<my-company>/index.json" />
  </packageSources>
  <packageSourceCredentials>...</packageSourceCredentials>
</configuration>

Note, I'm not clearing other packageSources: I still need to use the public nuget source. I'm just adding an additional private source in addition.

As I said, all is working, and I can add packages just fine from either source. But I got to worrying when I checked the PackageReference entries in the csproj. It doesn't indicate which source to use for the package.

For example, in this instance, MyCompany.Common is coming from my private source, and Newtonsoft.Json is coming from the public nuget source.

  <ItemGroup>
    <PackageReference Include="MyCompany.Common" Version="1.0.0" />
    <PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
  </ItemGroup>

But what if there is a public package with the same name? I tried this, and scarily it works. So in other words, if someone guesses my private package name, the next time someone clones the repo and builds, it's quite likely Visual Studio will fetch the package from the wrong source.

Is there a way to prevent this? I've been reading the Nuget PackageReference docs and the only thing that seems even remotely close might be a Condition:

<PackageReference Include="Newtonsoft.Json" Version="9.0.1" Condition="'$(TargetFramework)' == 'net452'" />

But it looks like this is more to set conditions based on solution/project/system configuration, not package source.

Is there a conditional that can specify the package source? Or is there something else that can specify the nuget source for a particular package?

I think this might be related to this article.

like image 787
David784 Avatar asked Oct 28 '25 08:10

David784


2 Answers

There is an interesting post here

https://azure.microsoft.com/en-us/resources/3-ways-to-mitigate-risk-using-private-package-feeds/

I found the most practical way is to go with the lock mode, with which you will have a package.lock.json file like this

"dependencies": {
    ".NETCoreApp,Version=v5.0": {
      "Newtonsoft.Json": {
        "type": "Direct",
        "requested": "[12.0.1, )",
        "resolved": "12.0.1",
        "contentHash": "pBR3wCgYWZGiaZDYP+HHYnalVnPJlpP1q55qvVb+adrDHmFMDc1NAKio61xTwftK3Pw5h7TZJPJEEVMd6ty8rg=="
      }
    }
  }

The contentHash should secure the package.

The lock mode can be enabled by

<PropertyGroup>
    <RestorePackagesWithLockFile>true</RestorePackagesWithLockFile>
</PropertyGroup>
like image 111
lastr2d2 Avatar answered Oct 30 '25 23:10

lastr2d2


Microsoft now offers Package Source Mapping starting with NuGet 6.0 and Visual Studio 2022: (excerpt from https://learn.microsoft.com/en-us/nuget/consume-packages/package-source-mapping#enabling-package-source-mapping)

Enabling Package Source Mapping

To opt into this feature, you must have a nuget.config file. Having a single nuget.config at the root of your repository is considered a best practice. See nuget.config documentation to learn more.

  • Declare your desired package sources in your nuget.config file.
  • Following your source declarations, add a element that specifies the desired mappings for each source.
  • Declare exactly one packageSource element for each source in use.
    • Add as many patterns as you find necessary.
Define the package sources, nuget.org and contoso.com. -->
<!-- `clear` ensures no additional sources are inherited from another config file. -->
<packageSources>
  <clear />
  <!-- `key` can be any identifier for your source. -->
  <add key="nuget.org" value="https://api.nuget.org/v3/index.json" />
  <add key="contoso.com" value="https://contoso.com/packages/" />
</packageSources>

Define mappings by adding package patterns beneath the target source. -->
Contoso.* packages and NuGet.Common will be restored from contoso.com, everything else from nuget.org. -->
<packageSourceMapping>
key value for <packageSource> should match key values from <packageSources> element -->
  <packageSource key="nuget.org">
    <package pattern="*" />
  </packageSource>
  <packageSource key="contoso.com">
    <package pattern="Contoso.*" />
    <package pattern="NuGet.Common" />
  </packageSource>
</packageSourceMapping>
like image 38
Yuriy Gettya Avatar answered Oct 31 '25 01:10

Yuriy Gettya



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!