dotnet-artifacts-output

📁 novotnyllc/dotnet-artisan 📅 4 days ago
3
总安装量
3
周安装量
#61093
全站排名
安装命令
npx skills add https://github.com/novotnyllc/dotnet-artisan --skill dotnet-artifacts-output

Agent 安装分布

opencode 3
github-copilot 3
codex 3
kimi-cli 3
gemini-cli 3
cursor 3

Skill 文档

dotnet-artifacts-output

Reference guide for the .NET SDK artifacts output layout, which centralizes build outputs (bin/, obj/, publish/, package/) into a single artifacts/ directory at the repo root. Available since .NET 8 as an opt-in feature. Recommended for new projects; evaluate tradeoffs before migrating existing projects.

Prerequisites: Run [skill:dotnet-version-detection] first to confirm .NET 8+ SDK — artifacts output layout is not available in earlier SDK versions.

Scope

  • UseArtifactsOutput opt-in and ArtifactsPath configuration
  • Centralized build output layout (artifacts/bin/, artifacts/obj/, artifacts/publish/)
  • Impact on CI artifact upload paths and Docker builds
  • Migration tradeoffs for existing projects

Out of scope

  • Source tree organization (.sln, .csproj, src/, tests/) — see [skill:dotnet-project-structure]

Cross-references: [skill:dotnet-project-structure] for solution layout, [skill:dotnet-containers] for Dockerfile path adjustments, [skill:dotnet-gha-build-test] for CI artifact upload paths, [skill:dotnet-scaffold-project] for generating new projects with artifacts output enabled.


Why Use Artifacts Output

Traditional .NET build output scatters bin/ and obj/ directories throughout the source tree, one per project. The artifacts output layout consolidates all build outputs under a single artifacts/ directory next to Directory.Build.props.

Benefits:

  • Simpler .gitignore — one artifacts/ entry replaces per-project bin/ and obj/ entries
  • Easier clean builds — delete one directory instead of hunting for scattered bin//obj/ folders
  • Predictable output paths — tooling can anticipate where to find build outputs without traversing the source tree
  • Cleaner source tree — no build artifacts mixed into project directories

Tradeoffs:

  • Breaking path assumptions — existing CI pipelines, Dockerfiles, and tooling that reference bin/Debug/net10.0/ paths must be updated
  • IDE/tool compatibility — some older tools may not resolve the new output paths correctly
  • Migration effort — existing projects require updating all hardcoded output path references

Enabling Artifacts Output

Add UseArtifactsOutput to your Directory.Build.props at the repo root:

<Project>
  <PropertyGroup>
    <UseArtifactsOutput>true</UseArtifactsOutput>
  </PropertyGroup>
</Project>

Alternatively, generate a new Directory.Build.props with artifacts output pre-configured:

dotnet new buildprops --use-artifacts

This creates:

<Project>
  <PropertyGroup>
    <ArtifactsPath>$(MSBuildThisFileDirectory)artifacts</ArtifactsPath>
  </PropertyGroup>
</Project>

Setting ArtifactsPath directly is equivalent to UseArtifactsOutput=true and additionally lets you customize the root directory location.


Output Path Structure

All build outputs are organized under artifacts/ with three levels: output type, project name, and pivot (configuration/TFM/RID).

artifacts/
  bin/
    MyApp/
      debug/                          # Single-targeted project
      debug_net10.0/                  # Multi-targeted project
      release_linux-x64/              # RID-specific build
    MyApp.Core/
      debug/
  obj/
    MyApp/
      debug/
  publish/
    MyApp/
      release/                        # dotnet publish output
      release_linux-x64/              # RID-specific publish
  package/
    release/                          # NuGet .nupkg files (no project subfolder)

Output Type Directories

Directory Contents Traditional equivalent
artifacts/bin/ Compiled assemblies and dependencies <project>/bin/
artifacts/obj/ Intermediate build files, generated code <project>/obj/
artifacts/publish/ Published application output <project>/bin/<config>/<tfm>/publish/
artifacts/package/ NuGet packages (.nupkg, .snupkg) <project>/bin/<config>/

Pivot Naming

The pivot subfolder combines configuration, TFM, and RID joined by underscores. Components that are not present are omitted:

Scenario Pivot Full path example
Single-targeted, debug debug artifacts/bin/MyApp/debug/
Multi-targeted, debug debug_net10.0 artifacts/bin/MyApp/debug_net10.0/
Release, RID-specific release_linux-x64 artifacts/bin/MyApp/release_linux-x64/
Package output release artifacts/package/release/

Note: artifacts/package/ omits the project name subfolder. The pivot includes only the configuration.


Customizing the Artifacts Path

Custom Root Directory

Set ArtifactsPath to change the root location:

<PropertyGroup>
  <ArtifactsPath>$(MSBuildThisFileDirectory).output</ArtifactsPath>
</PropertyGroup>

This places all build outputs under .output/ instead of artifacts/.

Custom Pivot

Customize the pivot subfolder naming with ArtifactsPivots:

<PropertyGroup>
  <ArtifactsPivots>$(ArtifactsPivots)_MyCustomPivot</ArtifactsPivots>
</PropertyGroup>

Impact on .gitignore

With artifacts output enabled, simplify .gitignore:

# Artifacts output layout (replaces per-project bin/ and obj/ entries)
artifacts/

This single entry replaces the traditional pattern:

# Traditional layout (no longer needed with artifacts output)
[Bb]in/
[Oo]bj/

If using a custom ArtifactsPath, update the .gitignore entry to match.


Impact on Dockerfiles

Multi-stage Dockerfiles that copy build output must reference the new path structure. See [skill:dotnet-containers] for full Dockerfile patterns.

Traditional paths:

COPY --from=build /app/src/MyApp/bin/Release/net10.0/publish/ .

Artifacts output paths:

COPY --from=build /app/artifacts/publish/MyApp/release/ .

Key differences in Dockerfile paths:

  • Output is under artifacts/publish/ not bin/Release/<tfm>/publish/
  • Project name becomes a subdirectory under the output type
  • Configuration pivot is lowercase (release not Release)
  • TFM is omitted from single-targeted project pivots

Impact on CI Pipelines

CI workflows that upload build artifacts or reference output paths must be updated. See [skill:dotnet-gha-build-test] for full CI workflow patterns.

GitHub Actions — upload build output:

- name: Publish
  run: dotnet publish src/MyApp/MyApp.csproj -c Release

- name: Upload artifact
  uses: actions/upload-artifact@v4
  with:
    name: app
    path: artifacts/publish/MyApp/release/

GitHub Actions — upload NuGet packages:

- name: Pack
  run: dotnet pack -c Release

- name: Upload packages
  uses: actions/upload-artifact@v4
  with:
    name: packages
    path: artifacts/package/release/*.nupkg

Azure DevOps — publish artifacts:

- script: dotnet publish src/MyApp/MyApp.csproj -c Release
  displayName: 'Publish'

- task: PublishPipelineArtifact@1
  inputs:
    targetPath: 'artifacts/publish/MyApp/release/'
    artifact: 'app'

Migration Checklist

When enabling artifacts output on an existing project:

  1. Add UseArtifactsOutput to Directory.Build.props
  2. Update .gitignore — replace [Bb]in/ and [Oo]bj/ with artifacts/
  3. Update Dockerfiles — change all COPY --from=build paths to use artifacts/ structure
  4. Update CI pipelines — fix artifact upload paths, test result paths, and publish paths
  5. Update local scripts — fix any shell scripts that reference bin/ or obj/ paths
  6. Clean old output — delete existing bin/ and obj/ directories from all projects
  7. Verify builds — run dotnet build and dotnet publish to confirm output appears under artifacts/
  8. Verify tests — run dotnet test to confirm test execution with new paths

Agent Gotchas

  1. Do not hardcode TFM in artifacts output paths for single-targeted projects. The pivot for single-targeted projects is just the configuration (e.g., debug), not debug_net10.0. Multi-targeted projects include the TFM in the pivot.
  2. Do not use capitalized configuration names in artifacts paths. The artifacts layout uses lowercase pivots (debug, release), not the traditional capitalized names (Debug, Release).
  3. Do not assume artifacts/package/ has a project name subfolder. Unlike bin/, obj/, and publish/, the package/ output type omits the project name level. Packages appear directly under artifacts/package/<config>/.
  4. Do not enable artifacts output without updating Dockerfiles and CI pipelines first. Path changes will break COPY --from=build directives and artifact upload steps that reference traditional bin/ paths.
  5. Do not present artifacts output as the default .NET layout. It is opt-in since .NET 8 and remains opt-in. Recommend it for new projects; for existing projects, evaluate the migration effort against the benefits.

References