本文へ移動
cccskills
無料GitHub で公開

dotnet-cli-distribution

Chooses CLI output format. AOT vs framework-dependent, RID matrix, single-file, dotnet tool.

インストール方法を見る

含まれるファイル(1)

  • SKILL.md14.3 KB

SKILL.md(原文)

インストールする前に、エージェントに与えられる指示の中身を確認できます。

dotnet-cli-distribution

CLI distribution strategy for .NET tools: choosing between Native AOT single-file publish, framework-dependent deployment, and dotnet tool packaging. Runtime Identifier (RID) matrix planning for cross-platform targets (linux-x64, osx-arm64, win-x64, linux-arm64), single-file publish configuration, and binary size optimization techniques for CLI applications.

Version assumptions: .NET 8.0+ baseline. Native AOT for console apps is fully supported since .NET 8. Single-file publish has been mature since .NET 6.

Scope

  • Distribution strategy decision matrix (AOT, framework-dependent, self-contained, dotnet tool)
  • Runtime Identifier (RID) matrix planning for cross-platform targets
  • Single-file publish configuration
  • Binary size optimization for CLI tools
  • Publishing workflow (local and release artifacts)

Out of scope

  • Native AOT MSBuild configuration (PublishAot, ILLink descriptors) -- see [skill:dotnet-native-aot]
  • AOT-first application design patterns -- see [skill:dotnet-aot-architecture]
  • Multi-platform packaging formats (Homebrew, apt/deb, winget, Scoop) -- see [skill:dotnet-cli-packaging]
  • Release CI/CD pipeline -- see [skill:dotnet-cli-release-pipeline]
  • 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-native-aot] for AOT compilation pipeline, [skill:dotnet-aot-architecture] for AOT-safe design patterns, [skill:dotnet-cli-architecture] for CLI layered architecture, [skill:dotnet-cli-packaging] for platform-specific package formats, [skill:dotnet-cli-release-pipeline] for automated release workflows, [skill:dotnet-containers] for container-based distribution, [skill:dotnet-tool-management] for consumer-side tool installation and manifest management.


Distribution Strategy Decision Matrix

Choose the distribution model based on target audience and deployment constraints.

StrategyStartup TimeBinary SizeRuntime RequiredBest For
Native AOT single-file~10ms10-30 MBNonePerformance-critical CLI tools, broad distribution
Framework-dependent single-file~100ms1-5 MB.NET runtimeInternal tools where runtime is guaranteed
Self-contained single-file~120-200ms60-80 MBNoneSimple distribution without AOT complexity
dotnet tool (global/local)~200ms< 1 MB (NuGet).NET SDKDeveloper tools, .NET ecosystem users

Note: Startup timings are approximate for small console apps on modern hardware and vary by workload and environment. Self-contained single-file builds are often slightly slower to start than framework-dependent single-file builds due to larger artifacts and extraction overhead.

When to Choose Each Strategy

Native AOT single-file -- the gold standard for CLI distribution:

  • Zero dependencies on target machine (no .NET runtime needed)
  • Fastest startup (~10ms vs ~100ms+ for JIT)
  • Smallest binary when combined with trimming
  • Trade-off: longer build times, no reflection unless preserved
  • See [skill:dotnet-native-aot] for PublishAot MSBuild configuration

Framework-dependent deployment:

  • Smallest artifact size (only app code, no runtime)
  • Users must have .NET runtime installed
  • Best for internal/enterprise tools where runtime is managed
  • Can still use single-file publish for convenience

Self-contained (non-AOT):

  • Includes .NET runtime in the artifact
  • Larger binary than AOT but simpler build process
  • Full reflection and dynamic code support
  • Good compromise when AOT compat is difficult

dotnet tool packaging:

  • Distributed via NuGet -- simplest publishing workflow
  • Users install with dotnet tool install -g mytool
  • Requires .NET SDK on target (not just runtime)
  • Best for developer-facing tools in the .NET ecosystem
  • See [skill:dotnet-cli-packaging] for NuGet distribution details

Runtime Identifier (RID) Matrix

Standard CLI RID Targets

Target the four primary RIDs for broad coverage:

RIDPlatformNotes
linux-x64Linux x86_64Most Linux servers, CI runners, WSL
linux-arm64Linux ARM64AWS Graviton, Raspberry Pi 4+, Apple Silicon VMs
osx-arm64macOS Apple SiliconM1/M2/M3+ Macs (primary macOS target)
win-x64Windows x86_64Windows 10+, Windows Server

Optional Extended Targets

RIDWhen to Include
osx-x64Legacy Intel Mac support (declining market share)
linux-musl-x64Alpine Linux / Docker scratch images
linux-musl-arm64Alpine on ARM64
win-arm64Windows on ARM (Surface Pro X, Snapdragon laptops)

RID Configuration in .csproj


<!-- Set per publish, not in csproj (avoids accidental RID lock-in) -->
<!-- Use dotnet publish -r <rid> instead -->

<!-- If you must set a default for local development -->
<PropertyGroup Condition="'$(RuntimeIdentifier)' == ''">
  <RuntimeIdentifier>osx-arm64</RuntimeIdentifier>
</PropertyGroup>

```text

Publish per RID from the command line:

```bash

# Publish for each target RID
dotnet publish -c Release -r linux-x64
dotnet publish -c Release -r linux-arm64
dotnet publish -c Release -r osx-arm64
dotnet publish -c Release -r win-x64

```text

---

## Single-File Publish

Single-file publish bundles the application and its dependencies into one executable.

### Configuration

```xml

<PropertyGroup>
  <PublishSingleFile>true</PublishSingleFile>
  <!-- Required for single-file -->
  <SelfContained>true</SelfContained>
  <!-- Embed PDB for stack traces (optional, adds ~2-5 MB) -->
  <DebugType>embedded</DebugType>
  <!-- Include native libraries in the single file -->
  <IncludeNativeLibrariesForSelfExtract>true</IncludeNativeLibrariesForSelfExtract>
</PropertyGroup>

```text

### Single-File with Native AOT

When combined with Native AOT, single-file is implicit -- AOT always produces a single native binary:

```xml

<PropertyGroup>
  <PublishAot>true</PublishAot>
  <!-- PublishSingleFile is not needed -- AOT output is inherently single-file -->
  <!-- SelfContained is implied by PublishAot -->
</PropertyGroup>

```text

See [skill:dotnet-native-aot] for the full AOT publish configuration including ILLink, type preservation, and analyzer
setup.

### Publish Command

```bash

# Framework-dependent single-file (requires .NET runtime on target)
dotnet publish -c Release -r linux-x64 /p:PublishSingleFile=true --self-contained false

# Self-contained single-file (includes runtime, no AOT)
dotnet publish -c Release -r linux-x64 /p:PublishSingleFile=true --self-contained true

# Native AOT (inherently single-file, smallest and fastest)
dotnet publish -c Release -r linux-x64
# (when PublishAot=true is in csproj)

```text

---

## Size Optimization for CLI Binaries

### Trimming (Non-AOT)

Trimming removes unused code from the published output. For self-contained non-AOT builds:

```xml

<PropertyGroup>
  <PublishTrimmed>true</PublishTrimmed>
  <TrimMode>link</TrimMode>
  <!-- Suppress known trim warnings for CLI scenarios -->
  <SuppressTrimAnalysisWarnings>false</SuppressTrimAnalysisWarnings>
</PropertyGroup>

```text

### AOT Size Optimization

For Native AOT builds, size is controlled by AOT-specific MSBuild properties. See [skill:dotnet-native-aot] for the full
configuration. Key CLI-relevant properties include `StripSymbols`, `OptimizationPreference`, `InvariantGlobalization`,
and `StackTraceSupport`.

### Size Comparison (Typical CLI Tool)

| Configuration                                   | Approximate Size |
| ----------------------------------------------- | ---------------- |
| Self-contained (no trim)                        | 60-80 MB         |
| Self-contained + trimmed                        | 15-30 MB         |
| Native AOT (default)                            | 15-25 MB         |
| Native AOT + size optimized                     | 8-15 MB          |
| Native AOT + invariant globalization + stripped | 5-10 MB          |
| Framework-dependent                             | 1-5 MB           |

### Practical Size Reduction Checklist

1. **Enable invariant globalization** if the tool does not need locale-specific formatting
   (`InvariantGlobalization=true`)
2. **Strip symbols** on Linux/macOS (`StripSymbols=true`) -- keep separate symbol files for crash analysis
3. **Optimize for size** (`OptimizationPreference=Size`) -- minimal runtime performance impact for I/O-bound CLI tools
4. **Disable reflection** where possible -- use source generators for JSON serialization
   ([skill:dotnet-aot-architecture])
5. **Audit NuGet dependencies** -- each dependency adds to the binary; remove unused packages

---

## Framework-Dependent vs Self-Contained Trade-offs

### Framework-Dependent

```bash

dotnet publish -c Release -r linux-x64 --self-contained false

```bash

**Advantages:**

- Smallest artifact (1-5 MB)
- Serviced by runtime updates (security patches applied by runtime, not app rebuild)
- Faster publish times

**Disadvantages:**

- Requires matching .NET runtime on target
- Runtime version mismatch causes startup failures
- Users must manage runtime installation

### Self-Contained

```bash

dotnet publish -c Release -r linux-x64 --self-contained true

```bash

**Advantages:**

- No runtime dependency on target
- App controls exact runtime version
- Side-by-side deployment (multiple apps, different runtimes)

**Disadvantages:**

- Larger artifact (60-80 MB without trimming)
- Must rebuild and redistribute for runtime security patches
- One artifact per target RID

---

## Publishing Workflow

### Local Development

```bash

# Quick local publish for testing
dotnet publish -c Release -r osx-arm64

# Verify the binary
./bin/Release/net8.0/osx-arm64/publish/mytool --version

```text

### Producing Release Artifacts

```bash

#!/bin/bash
# build-all.sh -- Produce artifacts for all target RIDs
set -euo pipefail

VERSION="${1:?Usage: build-all.sh <version>}"
PROJECT="src/MyCli/MyCli.csproj"
OUTPUT_DIR="artifacts"

RIDS=("linux-x64" "linux-arm64" "osx-arm64" "win-x64")
# Note: Native AOT cross-compilation for ARM64 on x64 requires platform toolchain
# See [skill:dotnet-cli-release-pipeline] for CI-based cross-compilation setup

for rid in "${RIDS[@]}"; do
  echo "Publishing for $rid..."
  dotnet publish "$PROJECT" \
    -c Release \
    -r "$rid" \
    -o "$OUTPUT_DIR/$rid" \
    /p:Version="$VERSION"
done

# Create archives
for rid in "${RIDS[@]}"; do
  if [[ "$rid" == win-* ]]; then
    (cd "$OUTPUT_DIR/$rid" && zip -q "../mytool-$VERSION-$rid.zip" *)
  else
    tar -czf "$OUTPUT_DIR/mytool-$VERSION-$rid.tar.gz" -C "$OUTPUT_DIR/$rid" .
  fi
done

echo "Artifacts in $OUTPUT_DIR/"

```text

### Checksum Generation

Always produce checksums for release artifacts:

```bash

# Generate SHA-256 checksums
cd artifacts
shasum -a 256 *.tar.gz *.zip > checksums-sha256.txt

```bash

See [skill:dotnet-cli-release-pipeline] for automating this in GitHub Actions.

---

## Agent Gotchas

1. **Do not set RuntimeIdentifier in the .csproj for multi-platform CLI tools.** Hardcoding a RID in the project file
   prevents building for other platforms. Pass `-r <rid>` at publish time instead.
2. **Do not use PublishSingleFile with PublishAot.** Native AOT output is inherently single-file. Setting both is
   redundant and may cause confusing build warnings.
3. **Do not skip InvariantGlobalization for size-sensitive CLI tools.** Globalization data adds ~25 MB to AOT binaries.
   Most CLI tools that do not format locale-specific dates/currencies should enable `InvariantGlobalization=true`.
4. **Do not distribute self-contained non-trimmed binaries.** A 60-80 MB CLI tool is unacceptable for end users. Either
   trim (PublishTrimmed), use AOT, or distribute as framework-dependent.
5. **Do not forget to produce checksums for release artifacts.** Users and package managers need SHA-256 checksums to
   verify download integrity. See [skill:dotnet-cli-release-pipeline] for automated checksum generation.
6. **Do not hardcode secrets in publish scripts.** Use environment variable placeholders (`${SIGNING_KEY}`) with a
   comment about CI secret storage for any signing or upload credentials.

---



## 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: "public void ProcessOrder"

# Use:
serena_find_symbol: "OrderService/ProcessOrder"
serena_get_symbols_overview: "src/Services/OrderService.cs"
```
## References

- [.NET application publishing overview](https://learn.microsoft.com/en-us/dotnet/core/deploying/)
- [Single-file deployment](https://learn.microsoft.com/en-us/dotnet/core/deploying/single-file/overview)
- [Native AOT deployment](https://learn.microsoft.com/en-us/dotnet/core/deploying/native-aot/)
- [Runtime Identifier (RID) catalog](https://learn.microsoft.com/en-us/dotnet/core/rid-catalog)
- [Trimming options](https://learn.microsoft.com/en-us/dotnet/core/deploying/trimming/trimming-options)

レビュー

まだレビューはありません。使ってみた感想をお寄せください。

同じリポジトリのスキル

概要と使いどころ

Patterns and techniques for evaluating and improving AI agent outputs.

日本語の概要は準備中です。原文の説明を表示しています。

rudironsoni/Synaxis22026年3月17日 更新

Comprehensive AI prompt engineering safety review and improvement prompt. Analyzes prompts for safety, bias, security vulnerabilities, and effectiveness while providing detailed improvement recommendations.

日本語の概要は準備中です。原文の説明を表示しています。

rudironsoni/Synaxis22026年3月17日 更新

Use when user requests research requiring multiple sources, comprehensive analysis, or synthesis across topics - technical research, domain knowledge gathering, market analysis, or learning about complex subjects

日本語の概要は準備中です。原文の説明を表示しています。

rudironsoni/Synaxis22026年3月17日 更新

deep-wiki

無料

AI-powered wiki generation for code repositories with commands, agents, and skills

日本語の概要は準備中です。原文の説明を表示しています。

rudironsoni/Synaxis22026年3月17日 更新

Use when building .NET 10 or C# 14 applications; when using minimal APIs, modular monolith patterns, or feature folders; when implementing HTTP resilience, Options pattern, Channels, or validation; when seeing outdated patterns like old extension method syntax

日本語の概要は準備中です。原文の説明を表示しています。

rudironsoni/Synaxis22026年3月17日 更新

Implements accessible .NET UI. SemanticProperties, ARIA, AutomationPeer, testing per platform.

日本語の概要は準備中です。原文の説明を表示しています。

rudironsoni/Synaxis22026年3月17日 更新

rudironsoni のスキルをすべて見る

このスキルの問題を報告する