关于 dotnet-artifacts-output
dotnet-artifacts-output 是关于 .NET SDK 构建产物集中布局的参考技能,说明如何将输出归入统一的 artifacts 目录。它帮助 .NET 开发者启用这一可选布局,并处理路径、Dockerfile 和 CI 流水线的相应调整。
主要功能
- 01集中式构建输出布局
- 02可自定义产物根目录与分区
- 03.gitignore 更新指引
- 04Dockerfile 输出路径调整
- 05CI 流水线迁移清单
适用场景
- 01在新 .NET 项目启用产物布局
- 02迁移 Docker 构建路径
- 03更新 CI 产物上传位置
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ wshaddix/ dotnet-skills --skill dotnet-artifacts-output安装后在 Claude Code 中输入/dotnet-artifacts-output确认已加载。
详细介绍
dotnet-artifacts-output
.NET SDK artifacts 输出布局参考指南,该布局会将构建输出(bin/、obj/、publish/、package/)集中到仓库根目录下的单个 artifacts/ 目录中。此可选功能自 .NET 8 起提供。建议新项目使用;迁移现有项目前请评估取舍。
先决条件: 先运行 [skill:dotnet-version-detection],确认 SDK 版本为 .NET 8+;较早的 SDK 版本不支持 artifacts 输出布局。
范围界定: [skill:dotnet-project-structure] 涵盖源代码树组织(.sln、.csproj、src/、tests/)。本技能涵盖构建输出组织(artifacts/bin/、artifacts/obj/、artifacts/publish/)。源代码树与输出树。
交叉引用:[skill:dotnet-project-structure] 介绍解决方案布局,[skill:dotnet-containers] 介绍 Dockerfile 路径调整,[skill:dotnet-gha-build-test] 介绍 CI artifacts 上传路径,[skill:dotnet-scaffold-project] 介绍如何生成启用了 artifacts 输出的新项目。
为什么使用 Artifacts 输出
传统的 .NET 构建输出会将 bin/ 和 obj/ 目录散布在源代码树中,每个项目各有一份。artifacts 输出布局会将所有构建输出集中到 Directory.Build.props 旁边的单个 artifacts/ 目录下。
优点:
- 简化
.gitignore—— 一个artifacts/条目即可替代每个项目的bin/和obj/条目 - 更轻松地执行干净构建 —— 删除一个目录即可,无需四处查找散布的
bin//obj/文件夹 - 输出路径可预测 —— 工具无需遍历源代码树即可预知构建输出的位置
- 源代码树更整洁 —— 项目目录中不会混入构建产物
取舍:
- 路径假设失效 —— 现有 CI 流水线、Dockerfile 和工具中引用
bin/Debug/net10.0/等路径的内容都必须更新 - IDE/工具兼容性 —— 某些较旧的工具可能无法正确解析新的输出路径
- 迁移工作量 —— 现有项目需要更新所有硬编码的输出路径引用
启用 Artifacts 输出
在仓库根目录的 Directory.Build.props 中添加 UseArtifactsOutput:
<Project>
<PropertyGroup>
<UseArtifactsOutput>true</UseArtifactsOutput>
</PropertyGroup>
</Project>
或者,生成一个预先配置好 artifacts 输出的 Directory.Build.props:
dotnet new buildprops --use-artifacts
这会创建:
<Project>
<PropertyGroup>
<ArtifactsPath>$(MSBuildThisFileDirectory)artifacts</ArtifactsPath>
</PropertyGroup>
</Project>
直接设置 ArtifactsPath 等同于 UseArtifactsOutput=true,此外还可以自定义根目录位置。
输出路径结构
所有构建输出都按三个层级组织在 artifacts/ 下:输出类型、项目名称和 pivot(配置/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)
输出类型目录
| 目录 | 内容 | 传统对应位置 |
|---|---|---|
artifacts/bin/ | 已编译的程序集及其依赖项 | <project>/bin/ |
artifacts/obj/ | 中间构建文件、生成的代码 | <project>/obj/ |
artifacts/publish/ | 已发布的应用程序输出 | <project>/bin/<config>/<tfm>/publish/ |
artifacts/package/ | NuGet 包(.nupkg、.snupkg) | <project>/bin/<config>/ |
Pivot 命名
pivot 子文件夹会将配置、TFM 和 RID 用下划线连接起来。不存在的组成部分会省略:
| 场景 | Pivot | 完整路径示例 |
|---|---|---|
| 单目标、调试 | debug | artifacts/bin/MyApp/debug/ |
| 多目标、调试 | debug_net10.0 | artifacts/bin/MyApp/debug_net10.0/ |
| 发布、特定 RID | release_linux-x64 | artifacts/bin/MyApp/release_linux-x64/ |
| 包输出 | release | artifacts/package/release/ |
注意:artifacts/package/ 不包含项目名称子文件夹。pivot 仅包含配置。
自定义 Artifacts 路径
自定义根目录
设置 ArtifactsPath 以更改根目录位置:
<PropertyGroup>
<ArtifactsPath>$(MSBuildThisFileDirectory).output</ArtifactsPath>
</PropertyGroup>
这会将所有构建输出放在 .output/ 下,而不是 artifacts/ 下。
自定义 Pivot
使用 ArtifactsPivots 自定义 pivot 子文件夹名称:
<PropertyGroup>
<ArtifactsPivots>$(ArtifactsPivots)_MyCustomPivot</ArtifactsPivots>
</PropertyGroup>
对 .gitignore 的影响
启用 artifacts 输出后,可简化 .gitignore:
# Artifacts output layout (replaces per-project bin/ and obj/ entries)
artifacts/
这条目可替代传统模式:
# Traditional layout (no longer needed with artifacts output)
[Bb]in/
[Oo]bj/
如果使用自定义 ArtifactsPath,请更新 .gitignore 条目,使其与之匹配。
对 Dockerfile 的影响
复制构建输出的多阶段 Dockerfile 必须引用新的路径结构。完整的 Dockerfile 模式请参阅 [skill:dotnet-containers]。
传统路径:
COPY --from=build /app/src/MyApp/bin/Release/net10.0/publish/ .
Artifacts 输出路径:
COPY --from=build /app/artifacts/publish/MyApp/release/ .
Dockerfile 路径的主要区别:
- 输出位于
artifacts/publish/下,而非bin/Release/<tfm>/publish/ - 项目名称成为输出类型下的子目录
- 配置 pivot 使用小写形式(
release,而非Release) - 单目标项目的 pivot 中省略 TFM
对 CI 流水线的影响
上传构建 artifacts 或引用输出路径的 CI 工作流必须更新。完整的 CI 工作流模式请参阅 [skill:dotnet-gha-build-test]。
GitHub Actions -- 上传构建输出:
- 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 -- 上传 NuGet 包:
- 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 -- 发布 artifacts:
- script: dotnet publish src/MyApp/MyApp.csproj -c Release
displayName: 'Publish'
- task: PublishPipelineArtifact@1
inputs:
targetPath: 'artifacts/publish/MyApp/release/'
artifact: 'app'
迁移检查清单
在现有项目中启用 artifacts 输出时:
- 将
UseArtifactsOutput添加到Directory.Build.props - 更新
.gitignore—— 将[Bb]in/和[Oo]bj/替换为artifacts/ - 更新 Dockerfile —— 将所有
COPY --from=build路径改为使用artifacts/结构 - 更新 CI 流水线 —— 修正 artifact 上传路径、测试结果路径和发布路径
- 更新本地脚本 —— 修正所有引用
bin/或obj/路径的 shell 脚本 - 清理旧输出 —— 删除所有项目中现有的
bin/和obj/目录 - 验证构建 —— 运行
dotnet build和dotnet publish,确认输出位于artifacts/下 - 验证测试 —— 运行
dotnet test,确认测试能使用新路径执行
Agent 注意事项
- 单目标项目的 artifacts 输出路径不要硬编码 TFM。 单目标项目的 pivot 仅包含配置(例如
debug),而不是debug_net10.0。多目标项目的 pivot 则包含 TFM。 - artifacts 路径中的配置名称不要使用大写字母。 artifacts 布局使用小写 pivot(
debug、release),而非传统的大写名称(Debug、Release)。 - 不要假设
artifacts/package/下有项目名称子文件夹。 与bin/、obj/和publish/不同,package/输出类型会省略项目名称这一层。包会直接位于artifacts/package/<config>/下。 - 启用 artifacts 输出前,务必先更新 Dockerfile 和 CI 流水线。 路径变更会导致引用传统
bin/路径的COPY --from=build指令和 artifact 上传步骤失效。 - 不要将 artifacts 输出描述为默认的 .NET 布局。 从 .NET 8 起,它一直是可选项。建议新项目使用;对于现有项目,应权衡迁移工作量与收益。