Docs menu

Package managers

How NuGet restore works on Primcloud: supported sources, private feeds, credentials via environment variables, and lockfile behavior.

On this page

.NET has one package manager: NuGet. Every dependency you declare (a <PackageReference> in a project file, a packages.config for legacy projects, a dotnet-tools.json for local tools) is a NuGet package resolved through NuGet feeds.

Primcloud runs NuGet restore as part of every build. This page covers what runs, how to point at private feeds, and how to opt into lockfile-enforced restores.

Supported package sources#

By default, NuGet restores from nuget.org, the public NuGet Gallery.

To add or override sources, drop a nuget.config file at the repo root. The .NET SDK reads it during restore:

nuget.config
<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <packageSources>
    <clear />
    <add key="nuget.org" value="https://api.nuget.org/v3/index.json" />
    <add key="my-private-feed" value="https://pkgs.example.com/nuget/v3/index.json" />
  </packageSources>
</configuration>

<clear /> drops any inherited sources; the remaining <add> entries are the exhaustive list restore consults.

The build does not modify nuget.config. Everything the .NET SDK supports (source mapping, package prefix reservations, source ordering) works the same on Primcloud as it does locally.

Install behavior#

Two commands run during the build phase, in order:

1. dotnet tool restore: only if .config/dotnet-tools.json exists at the repo root. This installs any local .NET tools your build depends on (formatters, source generators, EF Core CLI, and so on) into ~/.dotnet/tools and puts them on PATH for the rest of the build.

2. dotnet publish: this internally runs dotnet restore first, resolving every <PackageReference> and legacy packages.config dependency against the configured NuGet sources, then compiling and publishing the app.

Both commands write their outputs to the shared NuGet package cache (see .NET on Primcloud → Cache behavior).

The build sets two NuGet-related environment variables at build time:

Variable Value Effect
NUGET_PACKAGES Path to the cached NuGet layer Every restore writes to and reads from the persistent cache.
NUGET_XMLDOC_MODE skip XML doc files are skipped during restore, for a smaller layer and faster install.

Private packages and registries#

If your nuget.config points at a private feed, you need to hand credentials to the SDK at build time. The .NET SDK reads them from environment variables named after the feed:

  • NuGetPackageSourceCredentials_<feed-name>__Username
  • NuGetPackageSourceCredentials_<feed-name>__Password (encrypted) or NuGetPackageSourceCredentials_<feed-name>__ClearTextPassword

<feed-name> is the key attribute of the <add> element in your nuget.config, with any characters other than letters and digits replaced by underscores.

Note

There's a double underscore before Username/Password.

Set these in the Secrets panel in the dashboard; they take effect on the next build.

Example. For the private feed above:

nuget.config
<add key="my-private-feed" value="https://pkgs.example.com/nuget/v3/index.json" />

Set:

  • NuGetPackageSourceCredentials_my_private_feed__Username = your username or PAT ID
  • NuGetPackageSourceCredentials_my_private_feed__ClearTextPassword = your token

Both are stored as secrets in Primcloud and are never surfaced in build logs.

Lockfiles#

Lockfiles are opt-in on .NET. Without one, dotnet restore picks the highest matching version for each <PackageReference> on every build. Set RestorePackagesWithLockFile on a project to generate and enforce one:

MyApp.csproj
<PropertyGroup>
  <RestorePackagesWithLockFile>true</RestorePackagesWithLockFile>
</PropertyGroup>

The next dotnet restore (locally or on Primcloud) produces a packages.lock.json alongside the project file. Commit it. From then on:

  • Restore fails if the lockfile disagrees with the version graph the <PackageReference> values would resolve to.
  • To lock more strictly on CI-style builds where the graph shouldn't change, add RestoreLockedMode=true. Primcloud's builds are not CI in the .NET sense, so this is opt-in behavior at your discretion.

Without a lockfile, the build still succeeds if the graph is resolvable, but two builds of the same commit can produce different dependency graphs if a package publishes a new patch between them.