dotnet pack
|
This section documents MSBuild 18.9, the .NET SDK 10.0.402 (with its This content was generated with the assistance of AI and should be verified against the official documentation before being relied on in production. The C# Reference bibliography lists the reference material consulted while preparing these pages. |
dotnet pack builds a project and creates a NuGet package (.nupkg) from it, using MSBuild properties instead of a
hand-written .nuspec. This page lists the command’s options with .NET SDK 10.0.402 and shows the two that
surprise people. Authoring a good package — metadata, layout, symbols, validation — is the subject of the
Publishing and Distributing Libraries group,
starting with
Creating Packages with dotnet pack.
Options
| Option | Effect |
|---|---|
|
Release by default since .NET 8 ( |
|
The folder for the packages (default |
|
Pack existing build output. |
|
Set the package version. |
|
Set |
|
Also create a symbol package ( |
|
Create a |
|
Set |
|
Do not display the startup banner or the copyright message. SDK 10.0.402 accepts |
|
As for |
Packing Ledgerline
dotnet pack src/Ledgerline -o pk
dotnet pack src/Ledgerline -o pk --no-build --version 1.1.0-beta.1
dotnet pack src/Ledgerline -o pk --no-build --version-suffix rc.1
dotnet pack src/Ledgerline -o pk --no-build --include-symbols -p:SymbolPackageFormat=snupkg
# 1. dotnet pack src/Ledgerline -o pk (the build lines before it omitted)
Successfully created package '~/ledgerline/pk/Ledgerline.1.0.0.nupkg'.
# 2. --no-build --version 1.1.0-beta.1
Successfully created package '~/ledgerline/pk/Ledgerline.1.1.0-beta.1.nupkg'.
# 3. --no-build --version-suffix rc.1 (printed nothing)
# 4. --no-build --include-symbols -p:SymbolPackageFormat=snupkg
Successfully created package '~/ledgerline/pk/Ledgerline.1.0.0.nupkg'.
Successfully created package '~/ledgerline/pk/Ledgerline.1.0.0.snupkg'.
The # lines mark which command printed what; they are not part of the output.
Two of the four results are not what the commands suggest:
-
--version-suffixdid nothing.Ledgerline.csprojsets<Version>1.0.0</Version>, andVersionSuffixonly takes part when the project setsVersionPrefixinstead (Versionis then$(VersionPrefix)-$(VersionSuffix)). The third command printed nothing at all: the version was still 1.0.0, so with-v dthe log showsSkipping target "GenerateNuspec" because all output files are up-to-date, and the existingLedgerline.1.0.0.nupkgwas left as it was. -
--versionwith--no-buildversions the package, not the assemblies.Ledgerline.1.1.0-beta.1.nupkghas<version>1.1.0-beta.1</version>in its.nuspec, but itslib/net10.0/Ledgerline.dllstill says1.0.0.0and informational version1.0.0+e33226ff…, because it was built before. Pass the version to the build (dotnet build -p:Version=1.1.0-beta.1, thendotnet pack --no-build -p:Version=1.1.0-beta.1), or letdotnet packbuild.
The .snupkg holds only the PDBs (lib/<tfm>/Ledgerline.pdb). --include-source instead created
Ledgerline.1.0.0.symbols.nupkg with the PDBs and src/Ledgerline/*.cs, the legacy format that nuget.org does not
accept as a symbol package
(Symbols, Source Link and Deterministic Packages).
-s added <serviceable>true</serviceable> to the .nuspec.
Versioning strategy is covered on Versioning and Prerelease Packages.
Source: dotnet pack: Examples.
Packing without a project
dotnet pack also accepts a .nuspec file — useful for content-only packages that have nothing to compile:
<?xml version="1.0" encoding="utf-8"?>
<package xmlns="http://schemas.microsoft.com/packaging/2013/05/nuspec.xsd">
<metadata>
<id>Ledgerline.Samples</id>
<version>1.0.0</version>
<authors>Ledgerline contributors</authors>
<description>Sample journal files for Ledgerline.</description>
<license type="expression">MIT</license>
</metadata>
<files>
<file src="content/*.csv" target="contentFiles/any/any/journals" />
</files>
</package>
dotnet pack Ledgerline.Samples.nuspec -o out
[NuGet Manager] The package Ledgerline.Samples.1.0.0 is missing a readme. Go to https://aka.ms/nuget/authoring-best-practices/readme to learn why package readmes are important.
[NuGet Manager] Successfully created package 'out/Ledgerline.Samples.1.0.0.nupkg'.
A file-based app (dotnet pack balance.cs) packs as a .NET tool, because PackAsTool is on by default for
file-based apps (Run and
File-Based Apps).
Deterministic packs
From SDK 10.0.400, -p:Deterministic=true -p:DeterministicTimestamp=<time> makes two packs of the same build output
byte-for-byte identical (ZIP entry times and the .psmdcp part). With SDK 10.0.402, exporting SOURCE_DATE_EPOCH
alone was not enough; passing it as DeterministicTimestamp was. The experiment is on
Reproducible and Deterministic Builds.
Common mistakes
-
--version-suffixon a project that setsVersion— ignored without a warning. -
--versionwith--no-build— package and assembly versions disagree. -
--include-sourcefor nuget.org symbols — use--include-symbols -p:SymbolPackageFormat=snupkg. -
Packing Debug by habit —
packdefaults to Release since .NET 8; do not override it.