用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
直接命令不会经过审查 Prompt;运行前请先检查来源。
npx skills add https://github.com/rudironsoni/Synaxis --skill dotnet-nuget-authoring命令会保持在同一行。复制前请横向滚动并检查完整内容。
想先保存到本地?可下载 SkillsMP 当前能够提供的文件。
正在显示 SKILL.md
Routes .NET/C# work to domain skills. Loads coding-standards for code paths.
基于 SOC 职业分类
| name | dotnet-nuget-authoring |
| category | developer-experience |
| subcategory | nuget |
| description | Creates NuGet packages. SDK-style csproj, source generators, multi-TFM, symbols, signing. |
| license | MIT |
| targets | ["*"] |
| tags | ["foundation","dotnet","skill"] |
| version | 0.0.1 |
| author | dotnet-agent-harness |
| invocable | true |
| claudecode | {"allowed-tools":["Read","Grep","Glob","Bash","Write","Edit"]} |
| codexcli | {"short-description":".NET skill guidance for foundation tasks"} |
| opencode | {"allowed-tools":["Read","Grep","Glob","Bash","Write","Edit"]} |
| copilot | {} |
| geminicli | {} |
| antigravity | {} |
NuGet package authoring for .NET library authors: SDK-style .csproj package properties (PackageId, PackageTags,
PackageReadmeFile, PackageLicenseExpression), source generator NuGet packaging with analyzers/dotnet/cs/ folder
layout and buildTransitive targets, multi-TFM packages, symbol packages (snupkg) with deterministic builds, package
signing (author signing with certificates, repository signing), package validation (EnablePackageValidation,
Microsoft.DotNet.ApiCompat.Task for API compatibility), and NuGet versioning strategies (SemVer 2.0, pre-release
suffixes, NBGV integration).
Version assumptions: .NET 8.0+ baseline. NuGet client bundled with .NET 8+ SDK. Microsoft.DotNet.ApiCompat.Task
8.0+ for API compatibility validation.
Cross-references: [skill:dotnet-project-structure] for CPM, SourceLink, nuget.config, [skill:dotnet-gha-publish] for CI NuGet push workflows, [skill:dotnet-ado-publish] for ADO NuGet push workflows, [skill:dotnet-cli-packaging] for CLI tool distribution formats, [skill:dotnet-csharp-source-generators] for Roslyn source generator authoring, [skill:dotnet-release-management] for release lifecycle and NBGV setup, [skill:dotnet-roslyn-analyzers] for Roslyn analyzer authoring.
Every NuGet package starts with MSBuild properties in the .csproj. SDK-style projects produce NuGet packages with
dotnet pack -- no .nuspec file required.
< =>
net8.0
MyCompany.Widgets
1.0.0
My Company
A library for managing widgets with fluent API support.
widgets;fluent;dotnet
MIT
https://github.com/mycompany/widgets
https://github.com/mycompany/widgets
git
README.md
icon.png
true
true
```markdown
### Property Reference
| Property | Purpose | Example |
|----------|---------|---------|
| `PackageId` | Unique package identifier on nuget.org | `MyCompany.Widgets` |
| `Version` | SemVer 2.0 version | `1.2.3-beta.1` |
| `Authors` | Comma-separated author names | `Jane Doe, My Company` |
| `Description` | Package description for nuget.org | `Fluent widget management library` |
| `PackageTags` | Semicolon-separated search tags | `widgets;fluent;dotnet` |
| `PackageLicenseExpression` | SPDX license identifier | `MIT`, `Apache-2.0` |
| `PackageLicenseFile` | License file (alternative to expression) | `LICENSE.txt` |
| `PackageReadmeFile` | Markdown readme displayed on nuget.org | `README.md` |
| `PackageIcon` | Package icon filename | `icon.png` |
| `PackageProjectUrl` | Project homepage URL | `https://github.com/mycompany/widgets` |
| `PackageReleaseNotes` | Release notes for this version | `Added widget caching support` |
| `Copyright` | Copyright statement | `Copyright 2024 My Company` |
| `RepositoryUrl` | Source repository URL | `https://github.com/mycompany/widgets` |
| `RepositoryType` | Repository type | `git` |
### Directory.Build.props for Shared Metadata
For multi-project repos, set common properties in `Directory.Build.props`:
```xml
My Company
MIT
https://github.com/mycompany/widgets
https://github.com/mycompany/widgets
git
Copyright 2024 My Company
```text
Individual `.csproj` files then only set package-specific properties (`PackageId`, `Description`, `PackageTags`).
---
## Source Generator NuGet Packaging
Source generators and analyzers require a specific NuGet package layout. The generator DLL must be placed in the `analyzers/dotnet/cs/` folder, not the `lib/` folder. For Roslyn source generator authoring (IIncrementalGenerator, syntax/semantic analysis), see [skill:dotnet-csharp-source-generators]. This section covers NuGet *packaging* of generators only.
### Project Setup for Source Generator Package
```xml
netstandard2.0
true
true
MyCompany.Generators
Source generators for widget auto-registration.
false
true
true
```text
### Adding Build Props/Targets
When a source generator needs to set MSBuild properties in consuming projects, use the `buildTransitive` folder:
```xml
true
```text
Include `buildTransitive` content in the package:
```xml
```text
### Multi-Target Analyzer Package (Analyzer + Library)
When shipping both an analyzer and a runtime library in the same package:
```xml
net8.0;netstandard2.0
MyCompany.Widgets
```text
### NuGet Package Folder Layout
```text
MyCompany.Generators.1.0.0.nupkg
analyzers/
dotnet/
cs/
MyCompany.Generators.dll <-- generator/analyzer assembly
buildTransitive/
MyCompany.Generators.props <-- auto-imported MSBuild props
MyCompany.Generators.targets <-- auto-imported MSBuild targets
lib/
netstandard2.0/
_._ <-- empty marker (no runtime lib)
```text
---
## Multi-TFM Packages
Multi-targeting produces a single NuGet package with assemblies for each target framework. Consumers automatically get the best-matching assembly.
### When to Multi-Target
| Scenario | Approach |
|----------|----------|
| Library works on net8.0 only | Single TFM: `net8.0` |
| Library needs netstandard2.0 + net8.0 APIs | Multi-TFM: `netstandard2.0;net8.0` |
| Library uses net9.0-specific APIs (e.g., `SearchValues`) | Multi-TFM with polyfills or conditional code |
| Library targets .NET Framework consumers | Include `net472` or `netstandard2.0` TFM |
### Multi-TFM Configuration
```xml
netstandard2.0;net8.0;net9.0
```json
### Conditional Compilation
```csharp
public static class StringExtensions
{
public static bool ContainsIgnoreCase(this string source, string value)
{
#if NET8_0_OR_GREATER
return source.Contains(value, StringComparison.OrdinalIgnoreCase);
#else
return source.IndexOf(value, StringComparison.OrdinalIgnoreCase) >= 0;
#endif
}
}
```text
### NuGet Package Folder Layout (Multi-TFM)
```text
MyCompany.Widgets.1.0.0.nupkg
lib/
netstandard2.0/
MyCompany.Widgets.dll
net8.0/
MyCompany.Widgets.dll
net9.0/
MyCompany.Widgets.dll
```text
---
## Symbol Packages and Deterministic Builds
Symbol packages (`.snupkg`) enable source-level debugging for package consumers via the NuGet symbol server.
### Enabling Symbol Packages
```xml
true
snupkg
true
true
true
```text
The `snupkg` is pushed alongside the `nupkg` automatically when using `dotnet nuget push`:
```bash
# Push both .nupkg and .snupkg to nuget.org
dotnet nuget push "bin/Release/*.nupkg" \
--source https://api.nuget.org/v3/index.json \
--api-key "$NUGET_API_KEY"
```json
**SourceLink integration:** For source-level debugging with links to the actual source repository, configure SourceLink in your project. See [skill:dotnet-project-structure] for SourceLink setup -- do not duplicate that configuration here.
### Embedded PDB Alternative
For packages where a separate symbol package is undesirable:
```xml
embedded
```xml
This embeds the PDB directly in the assembly DLL. The tradeoff is larger package size but simpler distribution.
---
## Package Signing
NuGet supports author signing (proving package origin) and repository signing (proving it came from a specific feed).
### Author Signing with a Certificate
```bash
# Sign a package with a PFX certificate
dotnet nuget sign "MyCompany.Widgets.1.0.0.nupkg" \
--certificate-path ./signing-cert.pfx \
--certificate-password "$CERT_PASSWORD" \
--timestamper http://timestamp.digicert.com
# Sign with a certificate from the certificate store (Windows)
dotnet nuget sign "MyCompany.Widgets.1.0.0.nupkg" \
--certificate-fingerprint "ABC123..." \
--timestamper http://timestamp.digicert.com
```text
### Certificate Requirements
| Requirement | Detail |
|-------------|--------|
| Key usage | Code signing (1.3.6.1.5.5.7.3.3) |
| Algorithm | RSA 2048-bit minimum |
| Timestamping | Required for long-term validity |
| Trusted CA | DigiCert, Sectigo, or other trusted CA for nuget.org |
| Self-signed | Accepted for private feeds; rejected by nuget.org |
### Repository Signing
Repository signing is applied by feed operators (e.g., nuget.org signs all packages). Package authors do not need to configure repository signing -- it is applied automatically by the feed infrastructure.
### Verifying Package Signatures
```bash
# Verify a signed package
dotnet nuget verify "MyCompany.Widgets.1.0.0.nupkg"
# Verify with verbose output
dotnet nuget verify "MyCompany.Widgets.1.0.0.nupkg" --verbosity detailed
```text
---
## Package Validation
Package validation catches API breaks, invalid package layouts, and compatibility issues before publishing.
### Built-in Pack Validation
```xml
true
```text
This validates:
- All TFMs have compatible API surface
- No accidental API removals between package versions
- Package layout follows NuGet conventions
### API Compatibility with Baseline Version
Compare the current package against a previously published baseline version to detect breaking changes:
```xml
true
1.0.0
```text
### Microsoft.DotNet.ApiCompat.Task
For advanced API compatibility checking across assemblies:
```xml
true
true
```text
### Suppressing Known Breaks
When intentional API changes are made, generate and commit a suppression file:
```bash
# Generate suppression file for known breaks
dotnet pack /p:GenerateCompatibilitySuppressionFile=true
```bash
This creates `CompatibilitySuppressions.xml`:
```xml
CP0002
M:MyCompany.Widgets.Widget.OldMethod
lib/net8.0/MyCompany.Widgets.dll
lib/net8.0/MyCompany.Widgets.dll
```text
Reference the suppression file:
```xml
```xml
---
## NuGet Versioning Strategies
### SemVer 2.0 for NuGet
NuGet follows Semantic Versioning 2.0:
| Version | Meaning |
|---------|---------|
| `1.0.0` | Stable release |
| `1.0.1` | Patch (bug fixes, no API changes) |
| `1.1.0` | Minor (new features, backward compatible) |
| `2.0.0` | Major (breaking changes) |
| `1.0.0-alpha.1` | Pre-release alpha |
| `1.0.0-beta.1` | Pre-release beta |
| `1.0.0-rc.1` | Release candidate |
### Pre-release Suffixes
```xml
1.2.3
1.2.3-beta.1
```text
### NBGV Integration
Nerdbank.GitVersioning (NBGV) calculates versions from git history. For NBGV setup and `version.json` configuration, see [skill:dotnet-release-management]. This skill covers how NBGV-generated versions interact with NuGet packaging:
```xml
```text
NBGV produces versions like `1.2.42-beta+abcdef` where:
- `1.2` comes from `version.json`
- `42` is git commit height
- `-beta` is the pre-release suffix from `version.json`
- `+abcdef` is the git commit hash (build metadata, ignored by NuGet resolution)
### Version Properties Reference
| Property | Purpose | Set By |
|----------|---------|--------|
| `Version` | Full SemVer version (drives PackageVersion) | Manual or NBGV |
| `PackageVersion` | NuGet package version (defaults to Version) | Manual or NBGV |
| `AssemblyVersion` | CLR assembly version | Manual or NBGV |
| `FileVersion` | Windows file version | Manual or NBGV |
| `InformationalVersion` | Full version string with metadata | Manual or NBGV |
---
## Packing and Local Testing
### Building the Package
```bash
# Pack in Release configuration
dotnet pack --configuration Release
# Pack with specific version override
dotnet pack --configuration Release /p:Version=1.2.3-beta.1
# Output to specific directory
dotnet pack --configuration Release --output ./artifacts
```text
### Local Feed Testing
Test a package locally before publishing:
```bash
# Create a local feed directory
mkdir -p ~/local-nuget-feed
# Add the package to the local feed
dotnet nuget push "bin/Release/MyCompany.Widgets.1.0.0.nupkg" \
--source ~/local-nuget-feed
# In the consuming project, add the local feed
dotnet nuget add source ~/local-nuget-feed --name LocalFeed
```text
### Package Content Inspection
```bash
# List package contents (nupkg is a zip file)
unzip -l MyCompany.Widgets.1.0.0.nupkg
# Verify analyzer placement
unzip -l MyCompany.Generators.1.0.0.nupkg | grep analyzers/
```text
---
## Agent Gotchas
1. **Do not set both `PackageLicenseExpression` and `PackageLicenseFile`** -- they are mutually exclusive. Use `PackageLicenseExpression` for standard SPDX identifiers, `PackageLicenseFile` for custom licenses only.
1. **Source generators MUST target `netstandard2.0`** -- the Roslyn host requires this. Do not multi-target generators themselves; multi-target the runtime library that references the generator project.
1. **Do not set `IncludeBuildOutput` to `false` on library projects** -- only on pure analyzer/generator projects that should not contribute runtime assemblies.
1. **`buildTransitive` vs `build` folder** -- use `buildTransitive` for props/targets that should flow through transitive `PackageReference` dependencies. The `build` folder only affects direct consumers.
1. **Package validation suppression uses `ApiCompatSuppressionFile` with `CompatibilitySuppressions.xml`** -- not a `PackageValidationSuppression` MSBuild item. Generate the file with `/p:GenerateCompatibilitySuppressionFile=true`.
1. **SDK-style projects auto-include all `*.cs` files** -- adding TFM-conditional `Compile Include` without a preceding `Compile Remove` causes NETSDK1022 duplicate items.
1. **Never hardcode API keys in CLI examples** -- always use environment variable placeholders (`$NUGET_API_KEY`) with a note about CI secret storage.
1. **`ContinuousIntegrationBuild` must be conditional on CI** -- setting it unconditionally breaks local debugging by making PDBs non-reproducible with local file paths.
Primary approach: Use Serena symbol operations for efficient code navigation:
serena_find_symbol instead of text searchserena_get_symbols_overview for file organizationserena_find_referencing_symbols for impact analysisserena_replace_symbol_body for clean modificationsWhen to use Serena vs traditional tools:
Example workflow:
# Instead of:
Read: src/Services/OrderService.cs
Grep: "public void ProcessOrder"
# Use:
serena_find_symbol: "OrderService/ProcessOrder"
serena_get_symbols_overview: "src/Services/OrderService.cs"