# Publish .NET packages

`kanject packages` is the release control plane for NuGet and SDK repositories. It turns the evaluated MSBuild graph into a reviewed public/private policy, proves versions are immutable, stages candidates to a real feed, builds clean consumers, and journals the approved publication.

**You'll learn**

- Choose a split or all-private repository policy and classify every packable project
- Gate closure, package metadata, version floors, and already-claimed identities before release
- Stage unique `-rc.N` candidates and build consumers from the actual candidate feed
- Promote only after approval, using a trusted publisher and a resumable operation journal

> **Learn it through Bean & Bark:** Prefer a situation over a checklist? [Release the Pricing SDK](https://www.kanject.com/docs/cli-bean-bark-packages/) follows the package from Friday's duplicated pricing bug to an RC Tunde can install and an approved, journaled release.

## Use the right shipping family

Use `kanject packages` when the repository's product is one or more NuGet packages. Use `kanject aws distribute` when the product is a downloadable application routed by edition and runtime identifier. A legacy `kind: "library"` distribution cell still works for a deliberately product-coupled artifact, but it is not the normal authority for an SDK surface.

## Start with policy, not a push command

`init --split` scaffolds a public/private policy and human-review list; `--all-private` creates the BaaS-style shape with no public destination. The policy names feed environment variables rather than embedding credentials. `plan --write` maintains the reviewable public list; `verify` is the blocking local and CI gate.

```bash
# Pin the CLI in the repository
dotnet new tool-manifest
dotnet tool install Kanject.Cli

# Pick the repository shape
dotnet kanject packages init --split
# or: dotnet kanject packages init --all-private

# Make the intended package surface reviewable
dotnet kanject packages plan --write
dotnet kanject packages verify --advisories
```

- **Closure:** a public package cannot depend on a private first-party package.
- **Classification:** every packable project resolves to one deliberate tier.
- **Contract:** effective dependency floors cannot exceed the sibling versions being built.
- **Content:** configured public metadata, license, symbol, and SourceLink rules are enforced.
- **Fail loud:** an unreadable project graph or unknown policy member is a failure, never a skipped check.

## Audit versions before anyone waits for approval

A package identity is permanently claimed by its version and contract. `versions --packed-dir` compares the packed payload plus normalized dependency contract with the destination feed. If the bytes or dependency contract moved, the project needs a new `VersionPrefix`; the CLI names it but never guesses whether the bump is patch, minor, or major.

```bash
# Pack the exact release inputs
dotnet pack Acme.Sdk.slnx -c Release -o packed

# Refuse versions already claimed by different package contracts
dotnet kanject packages versions   --packed-dir packed   --strict

# Preserve the evaluated dependency graph as release evidence
dotnet kanject packages graph --out package-graph.json
```

## Evidence first, candidate second

The normal pipeline compiles once and packs twice: stable identities travel in the protected artifact, while the same assemblies are packed with a feed-derived `-rc.N` suffix for testing. The hostile build role has no release secret and can write only to the candidate repository.

```bash
# Build-stage evidence — no package is pushed
dotnet kanject packages publish   --profile release-evidence   --packed-dir packed

# Candidate stage — writes only to the configured rc feed
dotnet kanject packages publish   --profile candidate   --packed-dir packed-rc   --ci

# Prove clean consumers restore and build from the real candidate feed
dotnet kanject packages smoke feed   --plan release-plan-rc.json   --build
```

`smoke feed --build` installs each planned candidate into a clean consumer and builds it with analyzer failures elevated. Packages that need a runtime companion or literal source activation keep their isolated smoke and add a composite fixture; `packages smoke fixture init` scaffolds that proof fail-loud rather than inventing a green no-op fixture.

## Approve the bytes that were tested

After a person validates the RC, the publish stage recomputes routing from deployment-owned inputs, byte-verifies any existing identity, pushes dependency-first, and records every operation. It installs the infrastructure-pinned released CLI—not the repository's candidate tool—and its buildspec is controlled by the release stack.

```bash
# Trusted publish stage, after manual approval
PUBLISH_PUBLIC=true dotnet kanject packages publish   --profile approved-release   --packed-dir packed   --ci

# A partial publication resumes from its durable journal
PUBLISH_PUBLIC=true dotnet kanject packages publish   --profile approved-release   --packed-dir packed   --resume release-journal.json   --ci
```

## The three receipts

- **Release plan** — The exact package identities, routes, hashes, and policy fingerprint the release intends to execute.
- **Preflight verdicts** — As-if-armed destination evidence created before mutation: absent, equivalent, or conflicting identity.
- **Publication journal** — A durable per-operation record that makes partial releases observable and safely resumable.

> **A green build is not permission to overwrite:** `--skip-duplicate` is not a versioning strategy. If a destination already holds the same identity with a different contract, publication stops. Bump the package version, rebuild, and stage a new candidate.

**Recap**

- `packages init → plan → verify` turns the real project graph into a deliberate, reviewable package surface.
- `versions --packed-dir --strict` catches claimed identities before candidate staging.
- Candidates live in a separate rc feed and must restore/build from that feed before approval.
- The trusted publisher ships the approved stable packages dependency-first and persists plan, preflight, and journal evidence.

---
_Source: https://www.kanject.com/docs/packages/ · Kanject Docs_
