Skip to content

Local NuGet Server

Before publishing Pragmatic.Design packages to a public registry, you’ll want to consume them from a real project. The cleanest path is a local NuGet server: packages are dotnet packed from the monorepo, pushed to the local server, and consumed from test projects exactly as they would be from nuget.org.

This guide covers BaGetter, a community-maintained fork of BaGet with current dependency updates.

  • Docker Desktop (Windows) or Docker Engine (Linux/macOS)
  • The Pragmatic.Design repository checked out locally
Terminal window
docker run --rm --name bagetter \
-p 5555:8080 \
-v $PWD/.bagetter-data:/data \
-e ApiKey=dev-key \
-e Storage__Type=FileSystem \
-e Storage__Path=/data/packages \
-e Database__Type=Sqlite \
-e Database__ConnectionString="Data Source=/data/bagetter.db" \
-e Search__Type=Database \
bagetter/bagetter:latest

BaGetter is now available at http://localhost:5555.

Open it in a browser to verify the UI loads.

Create or update NuGet.Config at the repo root (the file already exists; add the BaGetter source to it):

<packageSources>
<add key="local-bagetter" value="http://localhost:5555/v3/index.json" />
<add key="nuget.org" value="https://api.nuget.org/v3/index.json" />
</packageSources>

Or register it globally once:

Terminal window
dotnet nuget add source http://localhost:5555/v3/index.json --name local-bagetter

From the repo root:

Terminal window
dotnet pack Pragmatic.Design.slnx --configuration Release --output ./artifacts

Packages land under ./artifacts/ with their MinVer-resolved version (e.g. Pragmatic.Result.0.1.0-preview.0.984.nupkg).

Terminal window
for pkg in ./artifacts/*.nupkg; do
dotnet nuget push "$pkg" \
--source http://localhost:5555/v3/index.json \
--api-key dev-key \
--skip-duplicate
done

.snupkg (symbol packages) are pushed the same way — BaGetter handles symbol server endpoints automatically.

In any test project’s .csproj:

<ItemGroup>
<PackageReference Include="Pragmatic.Result" Version="0.1.0-preview.*" />
</ItemGroup>

Then:

Terminal window
dotnet restore

NuGet resolves the reference from BaGetter first (local) and falls back to nuget.org if not found.

MinVer derives the version from the most recent nuget-v* tag plus commit height. To test a specific version:

Terminal window
# Tag locally (not pushed to origin)
git tag nuget-v0.1.0-preview.1
# Pack again — packages now versioned 0.1.0-preview.1
dotnet pack Pragmatic.Design.slnx --configuration Release --output ./artifacts
# Push to BaGetter
for pkg in ./artifacts/*.nupkg; do
dotnet nuget push "$pkg" --source http://localhost:5555/v3/index.json --api-key dev-key --skip-duplicate
done
# When done, remove the local tag
git tag -d nuget-v0.1.0-preview.1

If you need a fresh state (e.g. you pushed a broken build):

Terminal window
docker stop bagetter
rm -rf .bagetter-data

Then restart the container.

“Package already exists” — BaGetter rejects re-pushes of the exact same version. Either bump (new commit ⇒ new MinVer height) or use --skip-duplicate.

NuGet.exe restore finds old version from cache — clear the local cache:

Terminal window
dotnet nuget locals all --clear

Package missing README / LICENSEDirectory.Build.props packs them automatically. If a module lacks its own README, the repo-root README is used as fallback.