Installer avec Codex ou Claude Copiez ce prompt, collez-le dans Codex, Claude ou un autre assistant, puis laissez-le vérifier la page du skill et l'installer pour vous.
Une commande directe contourne le prompt de vérification. Examinez la source avant de l'exécuter.
Multi-platform packaging for .NET CLI tools: Homebrew formula authoring (binary tap and cask), apt/deb packaging with
dpkg-deb, winget manifest YAML schema and PR submission to winget-pkgs, Scoop manifest JSON, Chocolatey package
creation, dotnet tool global/local packaging, and NuGet distribution.
Version assumptions: .NET 8.0+ baseline. Package manager formats are stable across .NET versions.
Scope
Homebrew formula authoring (binary tap and cask)
apt/deb packaging with dpkg-deb
winget manifest YAML schema and PR submission
Scoop manifest JSON for Windows
Chocolatey package creation
dotnet tool global/local packaging and NuGet distribution
Out of scope
CLI distribution strategy (AOT vs framework-dependent decision) -- see [skill:dotnet-cli-distribution]
Release CI/CD pipeline that automates packaging -- see [skill:dotnet-cli-release-pipeline]
Native AOT compilation -- see [skill:dotnet-native-aot]
Container-based distribution -- see [skill:dotnet-containers]
General CI/CD patterns -- see [skill:dotnet-gha-patterns] and [skill:dotnet-ado-patterns]
Cross-references: [skill:dotnet-cli-distribution] for distribution strategy and RID matrix,
[skill:dotnet-cli-release-pipeline] for automated package publishing, [skill:dotnet-native-aot] for AOT binary
production, [skill:dotnet-containers] for container-based distribution, [skill:dotnet-tool-management] for consumer-side
tool installation and manifest management.
Homebrew (macOS / Linux)
Homebrew is the primary package manager for macOS and widely used on Linux. Two distribution formats exist for CLI
tools.
Binary Tap (Formula)
A formula downloads pre-built binaries per platform. This is the recommended approach for Native AOT CLI tools.
# Formula/mytool.rbclassMytool < Formula
desc "A CLI tool for managing widgets"
homepage "https://github.com/myorg/mytool"
version "1.2.3"
license "MIT"
on_macos do
on_arm do
url "https://github.com/myorg/mytool/releases/download/v1.2.3/mytool-1.2.3-osx-arm64.tar.gz"
sha256
on_intel
url
sha256
on_linux
on_arm
url
sha256
on_intel
url
sha256
bin.install
test
assert_match version.to_s, shell_output()
homebrew-taptext
myorg/homebrew-tap/
/
mytool.rb
bash
brew tap myorg/tap
brew install mytool
ruby
cask
version
sha256
url
name
homepage
binary
text
mytool_1..3_amd64/
/
control
usr/
bin/
mytool
text
: mytool
: .
: utils
: optional
: amd64
: <dev.com>
: A tool managing widgets
provides fast widget management from the command line.
with . zero-dependency execution.
: //usr/binartifacts/linux-x64/mytool/usr/bin/mytool/usr/bin/mytool//control: }.debversion.descriptionA tool managing widgetshomepage/1./mytool-.-win-x64.ziphashabc123...arm64url/1./mytool-.-win-arm64.ziphashdef456...binmytool.execheckvergithub//mytool--win-x64.ziparm64url//mytool--win-arm64.ziputf-///nuspecexpression- - ..)...../../.md/ void /src//.cs
"abc123..."
end
# Optional: remove on_intel block if not targeting Intel Macs
"
}
Install-ChocolateyZipPackage @packageArgs
```bash
### Building and Publishing
```powershell
# Pack the .nupkg
choco pack mytool.nuspec
# Test locally
choco install mytool --source="
" --force
# Push to Chocolatey Community Repository
choco push mytool.1.2.3.nupkg --source https://push.chocolatey.org/ --api-key $env:CHOCO_API_KEY
```text
---
## dotnet tool (Global and Local)
`dotnet tool` is the simplest distribution for .NET developers. Tools are distributed as NuGet packages.
### Project Configuration for Tool Packaging
```xml
<Project Sdk="
" />
</ItemGroup>
</Project>
```markdown
### Building and Publishing
```bash
# Pack the tool
dotnet pack -c Release
# Publish to NuGet.org
dotnet nuget push bin/Release/MyOrg.MyTool.1.2.3.nupkg \
--source https://api.nuget.org/v3/index.json \
--api-key "
$NUGET_API_KEY
"
```json
### Installing dotnet Tools
```bash
# Global tool (available system-wide)
dotnet tool install -g MyOrg.MyTool
# Local tool (per-project, tracked in .config/dotnet-tools.json)
dotnet new tool-manifest # first time only
dotnet tool install MyOrg.MyTool
# Update
dotnet tool update -g MyOrg.MyTool
# Run local tool
dotnet tool run mytool
# or just:
dotnet mytool
```text
### Global vs Local Tools
| Aspect | Global Tool | Local Tool |
| ------------------ | --------------------------- | ---------------------------------- |
| Scope | System-wide (per user) | Per-project directory |
| Install location | `~/.dotnet/tools` | `.config/dotnet-tools.json` |
| Version management | Manual update | Tracked in source control |
| CI/CD | Must install before use | `dotnet tool restore` restores all |
| Best for | Personal productivity tools | Project-specific build tools |
---
## NuGet Distribution
For tools distributed as NuGet packages (either as `dotnet tool` or standalone):
### Package Metadata
```xml
<PropertyGroup>
<PackageId>MyOrg.MyTool</PackageId>
<Version>1.2.3</Version>
<Description>A CLI tool for managing widgets</Description>
<Authors>My Org</Authors>
<PackageLicenseExpression>MIT</PackageLicenseExpression>
<PackageProjectUrl>https://github.com/myorg/mytool</PackageProjectUrl>
<PackageReadmeFile>README.md</PackageReadmeFile>
<PackageTags>cli;tools;widgets</PackageTags>
<RepositoryUrl>https://github.com/myorg/mytool</RepositoryUrl>
<RepositoryType>git</RepositoryType>
</PropertyGroup>
```text
### Publishing to NuGet.org
```bash
# Pack
dotnet pack -c Release -o ./nupkgs
# Push (use env var for API key -- never hardcode)
dotnet nuget push ./nupkgs/MyOrg.MyTool.1.2.3.nupkg \
--source https://api.nuget.org/v3/index.json \
--api-key "
$NUGET_API_KEY
"
```json
### Private Feed Distribution
```bash
# Push to a private feed (Azure Artifacts, GitHub Packages, etc.)
dotnet nuget push ./nupkgs/MyOrg.MyTool.1.2.3.nupkg \
--source https://pkgs.dev.azure.com/myorg/_packaging/myfeed/nuget/v3/index.json \
--api-key "
$AZURE_ARTIFACTS_PAT
"
```json
---
## Package Format Comparison
| Format | Platform | Requires .NET | Auto-Update | Difficulty |
| ---------------- | -------------- | --------------- | -------------------- | ---------- |
| Homebrew formula | macOS, Linux | No (binary tap) | `brew upgrade` | Medium |
| apt/deb | Debian/Ubuntu | No (AOT binary) | Via apt repo | Medium |
| winget | Windows 10+ | No (portable) | `winget upgrade` | Medium |
| Scoop | Windows | No (portable) | `scoop update` | Low |
| Chocolatey | Windows | No | `choco upgrade` | Medium |
| dotnet tool | Cross-platform | Yes (SDK) | `dotnet tool update` | Low |
| NuGet (library) | Cross-platform | Yes (SDK) | NuGet restore | Low |
---
## Agent Gotchas
1. **Do not hardcode SHA-256 hashes in package manifests.** Generate checksums from actual release artifacts, not
placeholder values. All package managers validate checksums against downloaded files.
2. **Do not use `InstallerType: exe` for portable CLI tools in winget.** Use `InstallerType: zip` with
`NestedInstallerType: portable` for standalone executables. The `exe` type implies an installer with silent flags.
3. **Do not forget `PackAsTool` for dotnet tool projects.** Without `<PackAsTool>true</PackAsTool>`, `dotnet pack`
produces a library package, not an installable tool.
4. **Do not hardcode API keys in packaging scripts.** Use environment variable references (`$NUGET_API_KEY`,
`$env:CHOCO_API_KEY`) with a comment noting CI secret configuration.
5. **Do not mix Homebrew formula and cask for the same CLI tool.** Pure CLI tools should use formulae. Casks are for GUI
applications with macOS app bundles.
6. **Do not skip the `test` block in Homebrew formulae.** Homebrew CI runs formula tests. A missing test block causes
review rejection. At minimum, test `--version` output.
---
## Code Navigation (Serena MCP)
**Primary approach:** Use Serena symbol operations for efficient code navigation:
1. **Find definitions**: `serena_find_symbol` instead of text search
2. **Understand structure**: `serena_get_symbols_overview` for file organization
3. **Track references**: `serena_find_referencing_symbols` for impact analysis
4. **Precise edits**: `serena_replace_symbol_body` for clean modifications
**When to use Serena vs traditional tools:**
- ✅ **Use Serena**: Navigation, refactoring, dependency analysis, precise edits
- ✅ **Use Read/Grep**: Reading full files, pattern matching, simple text operations
- ✅ **Fallback**: If Serena unavailable, traditional tools work fine
**Example workflow:**
```text
# Instead of:
Read: src/Services/OrderService.cs
Grep: "