Managing local .NET tools with dotnet-tools.json for consistent tooling across development environments and CI/CD pipelines.
67%
Does it follow best practices?
Run evals on this skill
Adds up to 20 points to the overall score
Passed
No findings from the security scan
Fix and improve this skill with Tessl
tessl review fix ./skills/local-tools/SKILL.mdUse this skill when:
Local tools are .NET CLI tools that are installed and versioned per-repository rather than globally. They're defined in .config/dotnet-tools.json and restored with dotnet tool restore.
| Aspect | Global Tools | Local Tools |
|---|---|---|
| Installation | dotnet tool install -g | dotnet tool restore |
| Scope | Machine-wide | Per-repository |
| Version control | Manual | In .config/dotnet-tools.json |
| CI/CD | Must install each tool | Single restore command |
| Conflicts | Can have version conflicts | Isolated per project |
# Create .config/dotnet-tools.json
dotnet new tool-manifestThis creates:
.config/
└── dotnet-tools.json# Install a tool locally
dotnet tool install docfx
# Install specific version
dotnet tool install docfx --version 2.78.3
# Install from a specific source
dotnet tool install MyTool --add-source https://mycompany.pkgs.visualstudio.com/_packaging/feed/nuget/v3/index.json# Restore all tools from manifest
dotnet tool restore{
"version": 1,
"isRoot": true,
"tools": {
"docfx": {
"version": "2.78.3",
"commands": [
"docfx"
],
"rollForward": false
},
"dotnet-ef": {
"version": "9.0.0",
"commands": [
"dotnet-ef"
],
"rollForward": false
},
"incrementalist.cmd": {
"version": "1.2.0",
"commands": [
"incrementalist"
],
"rollForward": false
},
"dotnet-reportgenerator-globaltool": {
"version": "5.4.1",
"commands": [
"reportgenerator"
],
"rollForward": false
}
}
}| Field | Description |
|---|---|
version | Manifest schema version (always 1) |
isRoot | Marks this as the root manifest (prevents searching parent directories) |
tools | Dictionary of tool configurations |
tools.<name>.version | Exact version to install |
tools.<name>.commands | CLI commands the tool provides |
tools.<name>.rollForward | Allow newer versions (usually false for reproducibility) |
# DocFX - API documentation generator
dotnet tool install docfx"docfx": {
"version": "2.78.3",
"commands": ["docfx"],
"rollForward": false
}Usage:
dotnet docfx docfx.json
dotnet docfx serve _site# EF Core CLI for migrations
dotnet tool install dotnet-ef"dotnet-ef": {
"version": "9.0.0",
"commands": ["dotnet-ef"],
"rollForward": false
}Usage:
dotnet ef migrations add InitialCreate
dotnet ef database update# ReportGenerator for coverage reports
dotnet tool install dotnet-reportgenerator-globaltool"dotnet-reportgenerator-globaltool": {
"version": "5.4.1",
"commands": ["reportgenerator"],
"rollForward": false
}Usage:
dotnet reportgenerator -reports:coverage.cobertura.xml -targetdir:coveragereport -reporttypes:Html# Incrementalist - build only changed projects
dotnet tool install incrementalist.cmd"incrementalist.cmd": {
"version": "1.2.0",
"commands": ["incrementalist"],
"rollForward": false
}Usage:
# Get projects affected by changes since main branch
incrementalist --branch main# CSharpier - opinionated C# formatter
dotnet tool install csharpier"csharpier": {
"version": "0.30.3",
"commands": ["dotnet-csharpier"],
"rollForward": false
}Usage:
dotnet csharpier .
dotnet csharpier --check . # CI mode - fails if changes needed# JB dotnet-inspect (requires license)
dotnet tool install jb"jb": {
"version": "2024.3.4",
"commands": ["jb"],
"rollForward": false
}jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup .NET
uses: actions/setup-dotnet@v4
with:
global-json-file: global.json
- name: Restore tools
run: dotnet tool restore
- name: Build
run: dotnet build
- name: Test with coverage
run: dotnet test --collect:"XPlat Code Coverage"
- name: Generate coverage report
run: dotnet reportgenerator -reports:**/coverage.cobertura.xml -targetdir:coveragereport
- name: Build documentation
run: dotnet docfx docs/docfx.jsonsteps:
- task: UseDotNet@2
inputs:
useGlobalJson: true
- script: dotnet tool restore
displayName: 'Restore .NET tools'
- script: dotnet build -c Release
displayName: 'Build'
- script: dotnet test -c Release --collect:"XPlat Code Coverage"
displayName: 'Test'
- script: dotnet reportgenerator -reports:**/coverage.cobertura.xml -targetdir:$(Build.ArtifactStagingDirectory)/coverage
displayName: 'Generate coverage report'# Update to latest version
dotnet tool update docfx
# Update to specific version
dotnet tool update docfx --version 2.79.0# List local tools
dotnet tool list
# List with outdated check
dotnet tool list --outdateddotnet tool uninstall docfxisRoot: truePrevents MSBuild from searching parent directories for tool manifests:
{
"version": 1,
"isRoot": true,
...
}Use "rollForward": false for reproducible builds:
"docfx": {
"version": "2.78.3",
"rollForward": false
}Always run dotnet tool restore before using any local tool:
- run: dotnet tool restore
- run: dotnet docfx docs/docfx.jsonAdd a comment or section in README:
## Development Setup
1. Restore tools: `dotnet tool restore`
2. Build: `dotnet build`
3. Test: `dotnet test`# .github/dependabot.yml
version: 2
updates:
- package-ecosystem: "nuget"
directory: "/"
schedule:
interval: "weekly"
# Includes local tools in .config/dotnet-tools.jsonEnsure you're running from the repository root:
# Wrong - running from subdirectory
cd src/MyApp
dotnet docfx # Error: tool not found
# Correct - run from solution root
cd ../..
dotnet docfx docs/docfx.jsonIf you see version conflicts, check for:
dotnet tool list -g.config/dotnet-tools.json in parent directories# Clear NuGet tool cache
dotnet nuget locals all --clear
# Re-restore tools
dotnet tool restore{
"version": 1,
"isRoot": true,
"tools": {
"docfx": {
"version": "2.78.3",
"commands": ["docfx"],
"rollForward": false
},
"dotnet-ef": {
"version": "9.0.0",
"commands": ["dotnet-ef"],
"rollForward": false
},
"dotnet-reportgenerator-globaltool": {
"version": "5.4.1",
"commands": ["reportgenerator"],
"rollForward": false
},
"csharpier": {
"version": "0.30.3",
"commands": ["dotnet-csharpier"],
"rollForward": false
},
"incrementalist.cmd": {
"version": "1.2.0",
"commands": ["incrementalist"],
"rollForward": false
}
}
}Development workflow:
# Initial setup
dotnet tool restore
# Format code before commit
dotnet csharpier .
# Run tests with coverage
dotnet test --collect:"XPlat Code Coverage"
dotnet reportgenerator -reports:**/coverage.cobertura.xml -targetdir:coverage
# Build documentation
dotnet docfx docs/docfx.json
# Check which projects changed (for large repos)
incrementalist --branch mainAaronontheweb/dotnet-skills
5ca5db8
If you maintain this skill, you can claim it as your own. Once claimed, you can manage eval scenarios, bundle related skills, attach documentation or rules, and ensure cross-agent compatibility.