dotnet-project-structure by aaronontheweb/dotnet-skills
npx skills add https://github.com/aaronontheweb/dotnet-skills --skill dotnet-project-structure在以下情况下使用此技能:
dotnet-local-tools - 使用 dotnet-tools.json 管理本地 .NET 工具microsoft-extensions-configuration - 配置验证模式.slnx 格式是 .NET 9 中引入的现代基于 XML 的解决方案文件格式。它取代了传统的 .sln 格式。
| 方面 | .sln (旧版) | .slnx (现代) |
|---|
广告位招租
在这里展示您的产品或服务
触达数万 AI 开发者,精准高效
| 格式 | 自定义文本格式 | 标准 XML |
| 可读性 | GUID,晦涩的语法 | 清晰,人类可读 |
| 版本控制 | 难以差异比较/合并 | 易于差异比较/合并 |
| 编辑 | 需要 IDE | 任何文本编辑器 |
| 工具 | 最低版本 |
|---|---|
| .NET SDK | 9.0.200 |
| Visual Studio | 17.13 |
| MSBuild | Visual Studio Build Tools 17.13 |
注意: 从 .NET 10 开始,dotnet new sln 默认创建 .slnx 文件。在 .NET 9 中,您必须显式迁移或指定格式。
<Solution>
<Folder Name="/build/">
<File Path="Directory.Build.props" />
<File Path="Directory.Packages.props" />
<File Path="global.json" />
<File Path="NuGet.Config" />
<File Path="README.md" />
</Folder>
<Folder Name="/src/">
<Project Path="src/MyApp/MyApp.csproj" />
<Project Path="src/MyApp.Core/MyApp.Core.csproj" />
</Folder>
<Folder Name="/tests/">
<Project Path="tests/MyApp.Tests/MyApp.Tests.csproj" />
</Folder>
</Solution>
使用 dotnet sln migrate 命令转换现有解决方案:
# 迁移特定的解决方案文件
dotnet sln MySolution.sln migrate
# 或者,如果目录中只有一个 .sln 文件,只需运行:
dotnet sln migrate
重要: 不要在同一仓库中同时保留 .sln 和 .slnx 文件。这会导致自动解决方案检测出现问题,并可能导致同步问题。迁移后,请删除旧的 .sln 文件。
您也可以在 Visual Studio 中迁移:
# .NET 10+:默认创建 .slnx
dotnet new sln --name MySolution
# .NET 9:显式指定格式
dotnet new sln --name MySolution --format slnx
# 添加项目(两种格式的操作相同)
dotnet sln add src/MyApp/MyApp.csproj
如果您使用的是 .NET 9.0.200 或更高版本,请将您的解决方案迁移到 .slnx。 优势显著:
.csproj 格式保持一致Directory.Build.props 提供集中式构建配置,适用于目录树中的所有项目。将其放在解决方案根目录。
<Project>
<!-- 元数据 -->
<PropertyGroup>
<Authors>您的团队</Authors>
<Company>您的公司</Company>
<!-- 动态版权年份 - 自动更新 -->
<Copyright>Copyright © 2020-$([System.DateTime]::Now.Year) Your Company</Copyright>
<Product>您的产品</Product>
<PackageProjectUrl>https://github.com/yourorg/yourrepo</PackageProjectUrl>
<RepositoryUrl>https://github.com/yourorg/yourrepo</RepositoryUrl>
<PackageLicenseExpression>Apache-2.0</PackageLicenseExpression>
<PackageTags>your;tags;here</PackageTags>
</PropertyGroup>
<!-- C# 语言设置 -->
<PropertyGroup>
<LangVersion>latest</LangVersion>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
<NoWarn>$(NoWarn);CS1591</NoWarn> <!-- 缺少 XML 注释 -->
</PropertyGroup>
<!-- 版本管理 -->
<PropertyGroup>
<VersionPrefix>1.0.0</VersionPrefix>
<PackageReleaseNotes>参见 RELEASE_NOTES.md</PackageReleaseNotes>
</PropertyGroup>
<!-- 目标框架定义(可重用属性) -->
<PropertyGroup>
<NetStandardLibVersion>netstandard2.0</NetStandardLibVersion>
<NetLibVersion>net8.0</NetLibVersion>
<NetTestVersion>net9.0</NetTestVersion>
</PropertyGroup>
<!-- SourceLink 配置 -->
<PropertyGroup>
<PublishRepositoryUrl>true</PublishRepositoryUrl>
<EmbedUntrackedSources>true</EmbedUntrackedSources>
<IncludeSymbols>true</IncludeSymbols>
<SymbolPackageFormat>snupkg</SymbolPackageFormat>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.SourceLink.GitHub" PrivateAssets="All" />
</ItemGroup>
<!-- NuGet 包资源 -->
<ItemGroup>
<None Include="$(MSBuildThisFileDirectory)logo.png" Pack="true" PackagePath="\" />
<None Include="$(MSBuildThisFileDirectory)README.md" Pack="true" PackagePath="\" />
</ItemGroup>
<PropertyGroup>
<PackageIcon>logo.png</PackageIcon>
<PackageReadmeFile>README.md</PackageReadmeFile>
</PropertyGroup>
<!-- 全局 Using 语句 -->
<ItemGroup>
<Using Include="System.Collections.Immutable" />
</ItemGroup>
</Project>
<Copyright>Copyright © 2020-$([System.DateTime]::Now.Year) Your Company</Copyright>
使用 MSBuild 属性函数在构建时插入当前年份。无需手动更新。
定义一次目标框架,随处引用:
<!-- 在 Directory.Build.props 中 -->
<PropertyGroup>
<NetLibVersion>net8.0</NetLibVersion>
<NetTestVersion>net9.0</NetTestVersion>
</PropertyGroup>
<!-- 在 MyApp.csproj 中 -->
<PropertyGroup>
<TargetFramework>$(NetLibVersion)</TargetFramework>
</PropertyGroup>
<!-- 在 MyApp.Tests.csproj 中 -->
<PropertyGroup>
<TargetFramework>$(NetTestVersion)</TargetFramework>
</PropertyGroup>
SourceLink 支持对 NuGet 包进行逐步调试:
<PropertyGroup>
<PublishRepositoryUrl>true</PublishRepositoryUrl>
<EmbedUntrackedSources>true</EmbedUntrackedSources>
<IncludeSymbols>true</IncludeSymbols>
<SymbolPackageFormat>snupkg</SymbolPackageFormat>
</PropertyGroup>
<ItemGroup>
<!-- 为您的源代码控制选择正确的提供程序 -->
<PackageReference Include="Microsoft.SourceLink.GitHub" PrivateAssets="All" />
<!-- 或者:Microsoft.SourceLink.AzureRepos.Git -->
<!-- 或者:Microsoft.SourceLink.GitLab -->
<!-- 或者:Microsoft.SourceLink.Bitbucket.Git -->
</ItemGroup>
集中式包管理 (CPM) 为所有 NuGet 包版本提供单一事实来源。
<Project>
<PropertyGroup>
<ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>
</PropertyGroup>
<!-- 为相关包定义版本变量 -->
<PropertyGroup>
<AkkaVersion>1.5.35</AkkaVersion>
<AspireVersion>9.1.0</AspireVersion>
</PropertyGroup>
<!-- 应用程序依赖项 -->
<ItemGroup Label="App Dependencies">
<PackageVersion Include="Akka" Version="$(AkkaVersion)" />
<PackageVersion Include="Akka.Cluster" Version="$(AkkaVersion)" />
<PackageVersion Include="Akka.Persistence" Version="$(AkkaVersion)" />
<PackageVersion Include="Microsoft.Extensions.Hosting" Version="9.0.0" />
</ItemGroup>
<!-- 构建/工具依赖项 -->
<ItemGroup Label="Build Dependencies">
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="8.0.0" />
</ItemGroup>
<!-- 测试依赖项 -->
<ItemGroup Label="Test Dependencies">
<PackageVersion Include="xunit" Version="2.9.3" />
<PackageVersion Include="xunit.runner.visualstudio" Version="3.0.1" />
<PackageVersion Include="FluentAssertions" Version="7.0.0" />
<PackageVersion Include="Microsoft.NET.Test.Sdk" Version="17.12.0" />
<PackageVersion Include="coverlet.collector" Version="6.0.3" />
</ItemGroup>
</Project>
<!-- 在 MyApp.csproj 中 -->
<ItemGroup>
<PackageReference Include="Akka" />
<PackageReference Include="Akka.Cluster" />
<PackageReference Include="Microsoft.Extensions.Hosting" />
</ItemGroup>
<!-- 在 MyApp.Tests.csproj 中 -->
<ItemGroup>
<PackageReference Include="xunit" />
<PackageReference Include="FluentAssertions" />
<PackageReference Include="Microsoft.NET.Test.Sdk" />
</ItemGroup>
固定 .NET SDK 版本,以便在所有环境中实现一致的构建。
{
"sdk": {
"version": "9.0.200",
"rollForward": "latestFeature"
}
}
| 策略 | 行为 |
|---|---|
disable | 需要精确版本 |
patch | 相同主版本.次版本,最新补丁 |
feature | 相同主版本,最新次版本.补丁 |
latestFeature | 相同主版本,最新功能带 |
minor | 相同主版本,最新次版本 |
latestMinor | 相同主版本,最新次版本 |
major | 最新 SDK(不推荐) |
推荐: latestFeature - 允许在同一功能带内进行补丁更新。
#### 1.2.0 2025年1月15日 ####
- 添加了新功能 X
- 修复了 Y 中的错误
- 改进了 Z 的性能
#### 1.1.0 2024年12月10日 ####
- 具有功能 A、B、C 的初始版本
function Get-ReleaseNotes {
param (
[Parameter(Mandatory=$true)]
[string]$MarkdownFile
)
$content = Get-Content -Path $MarkdownFile -Raw
$sections = $content -split "####"
$result = [PSCustomObject]@{
Version = $null
Date = $null
ReleaseNotes = $null
}
if ($sections.Count -ge 3) {
$header = $sections[1].Trim()
$releaseNotes = $sections[2].Trim()
$headerParts = $header -split " ", 2
if ($headerParts.Count -eq 2) {
$result.Version = $headerParts[0]
$result.Date = $headerParts[1]
}
$result.ReleaseNotes = $releaseNotes
}
return $result
}
function UpdateVersionAndReleaseNotes {
param (
[Parameter(Mandatory=$true)]
[PSCustomObject]$ReleaseNotesResult,
[Parameter(Mandatory=$true)]
[string]$XmlFilePath
)
$xmlContent = New-Object XML
$xmlContent.Load($XmlFilePath)
# 更新 VersionPrefix
$versionElement = $xmlContent.SelectSingleNode("//VersionPrefix")
$versionElement.InnerText = $ReleaseNotesResult.Version
# 更新 PackageReleaseNotes
$notesElement = $xmlContent.SelectSingleNode("//PackageReleaseNotes")
$notesElement.InnerText = $ReleaseNotesResult.ReleaseNotes
$xmlContent.Save($XmlFilePath)
}
# 加载辅助脚本
. "$PSScriptRoot\scripts\getReleaseNotes.ps1"
. "$PSScriptRoot\scripts\bumpVersion.ps1"
# 解析发布说明并更新 Directory.Build.props
$releaseNotes = Get-ReleaseNotes -MarkdownFile (Join-Path -Path $PSScriptRoot -ChildPath "RELEASE_NOTES.md")
UpdateVersionAndReleaseNotes -ReleaseNotesResult $releaseNotes -XmlFilePath (Join-Path -Path $PSScriptRoot -ChildPath "Directory.Build.props")
Write-Output "已更新到版本 $($releaseNotes.Version)"
# GitHub Actions 示例
- name: 从发布说明更新版本
shell: pwsh
run: ./build.ps1
- name: 构建
run: dotnet build -c Release
- name: 使用标签版本打包
run: dotnet pack -c Release /p:PackageVersion=${{ github.ref_name }}
- name: 推送到 NuGet
run: dotnet nuget push **/*.nupkg --api-key ${{ secrets.NUGET_API_KEY }} --source https://api.nuget.org/v3/index.json
配置 NuGet 源和行为:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<solution>
<add key="disableSourceControlIntegration" value="true" />
</solution>
<packageSources>
<clear />
<add key="nuget.org" value="https://api.nuget.org/v3/index.json" />
<!-- 如果需要,添加私有源 -->
<!-- <add key="MyCompany" value="https://pkgs.dev.azure.com/myorg/_packaging/myfeed/nuget/v3/index.json" /> -->
</packageSources>
</configuration>
关键设置:
<clear /> - 移除继承的/默认源,以实现可重现的构建disableSourceControlIntegration - 防止 TFS/Git 集成问题MySolution/
├── .config/
│ └── dotnet-tools.json # 本地 .NET 工具
├── .github/
│ └── workflows/
│ ├── pr-validation.yml # PR 检查
│ └── release.yml # NuGet 发布
├── scripts/
│ ├── getReleaseNotes.ps1 # 解析 RELEASE_NOTES.md
│ └── bumpVersion.ps1 # 更新 Directory.Build.props
├── src/
│ ├── MyApp/
│ │ └── MyApp.csproj
│ └── MyApp.Core/
│ └── MyApp.Core.csproj
├── tests/
│ └── MyApp.Tests/
│ └── MyApp.Tests.csproj
├── Directory.Build.props # 集中式构建配置
├── Directory.Packages.props # 集中式包版本
├── MySolution.slnx # 现代解决方案文件
├── global.json # SDK 版本固定
├── NuGet.Config # 包源配置
├── build.ps1 # 构建编排
├── RELEASE_NOTES.md # 版本历史
├── README.md # 项目文档
└── logo.png # 包图标
| 文件 | 用途 |
|---|---|
MySolution.slnx | 现代 XML 解决方案文件 |
Directory.Build.props | 集中式构建属性 |
Directory.Packages.props | 集中式包版本管理 |
global.json | SDK 版本固定 |
NuGet.Config | 包源配置 |
RELEASE_NOTES.md | 版本历史(由构建解析) |
build.ps1 | 构建编排脚本 |
.config/dotnet-tools.json | 本地 .NET 工具 |
每周安装次数
120
仓库
GitHub 星标数
495
首次出现
2026年1月28日
安全审计
安装于
claude-code87
codex80
github-copilot77
opencode77
gemini-cli74
kimi-cli71
Use this skill when:
dotnet-local-tools - Managing local .NET tools with dotnet-tools.jsonmicrosoft-extensions-configuration - Configuration validation patternsThe .slnx format is the modern XML-based solution file format introduced in .NET 9. It replaces the traditional .sln format.
| Aspect | .sln (Legacy) | .slnx (Modern) |
|---|---|---|
| Format | Custom text format | Standard XML |
| Readability | GUIDs, cryptic syntax | Clean, human-readable |
| Version control | Hard to diff/merge | Easy to diff/merge |
| Editing | IDE required | Any text editor |
| Tool | Minimum Version |
|---|---|
| .NET SDK | 9.0.200 |
| Visual Studio | 17.13 |
| MSBuild | Visual Studio Build Tools 17.13 |
Note: Starting with .NET 10, dotnet new sln creates .slnx files by default. In .NET 9, you must explicitly migrate or specify the format.
<Solution>
<Folder Name="/build/">
<File Path="Directory.Build.props" />
<File Path="Directory.Packages.props" />
<File Path="global.json" />
<File Path="NuGet.Config" />
<File Path="README.md" />
</Folder>
<Folder Name="/src/">
<Project Path="src/MyApp/MyApp.csproj" />
<Project Path="src/MyApp.Core/MyApp.Core.csproj" />
</Folder>
<Folder Name="/tests/">
<Project Path="tests/MyApp.Tests/MyApp.Tests.csproj" />
</Folder>
</Solution>
Use the dotnet sln migrate command to convert existing solutions:
# Migrate a specific solution file
dotnet sln MySolution.sln migrate
# Or if only one .sln exists in the directory, just run:
dotnet sln migrate
Important: Do not keep both .sln and .slnx files in the same repository. This causes issues with automatic solution detection and can lead to sync problems. After migration, delete the old .sln file.
You can also migrate in Visual Studio:
# .NET 10+: Creates .slnx by default
dotnet new sln --name MySolution
# .NET 9: Specify the format explicitly
dotnet new sln --name MySolution --format slnx
# Add projects (works the same for both formats)
dotnet sln add src/MyApp/MyApp.csproj
If you're using .NET 9.0.200 or later, migrate your solutions to .slnx. The benefits are significant:
.csproj formatDirectory.Build.props provides centralized build configuration that applies to all projects in a directory tree. Place it at the solution root.
<Project>
<!-- Metadata -->
<PropertyGroup>
<Authors>Your Team</Authors>
<Company>Your Company</Company>
<!-- Dynamic copyright year - updates automatically -->
<Copyright>Copyright © 2020-$([System.DateTime]::Now.Year) Your Company</Copyright>
<Product>Your Product</Product>
<PackageProjectUrl>https://github.com/yourorg/yourrepo</PackageProjectUrl>
<RepositoryUrl>https://github.com/yourorg/yourrepo</RepositoryUrl>
<PackageLicenseExpression>Apache-2.0</PackageLicenseExpression>
<PackageTags>your;tags;here</PackageTags>
</PropertyGroup>
<!-- C# Language Settings -->
<PropertyGroup>
<LangVersion>latest</LangVersion>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
<NoWarn>$(NoWarn);CS1591</NoWarn> <!-- Missing XML comments -->
</PropertyGroup>
<!-- Version Management -->
<PropertyGroup>
<VersionPrefix>1.0.0</VersionPrefix>
<PackageReleaseNotes>See RELEASE_NOTES.md</PackageReleaseNotes>
</PropertyGroup>
<!-- Target Framework Definitions (reusable properties) -->
<PropertyGroup>
<NetStandardLibVersion>netstandard2.0</NetStandardLibVersion>
<NetLibVersion>net8.0</NetLibVersion>
<NetTestVersion>net9.0</NetTestVersion>
</PropertyGroup>
<!-- SourceLink Configuration -->
<PropertyGroup>
<PublishRepositoryUrl>true</PublishRepositoryUrl>
<EmbedUntrackedSources>true</EmbedUntrackedSources>
<IncludeSymbols>true</IncludeSymbols>
<SymbolPackageFormat>snupkg</SymbolPackageFormat>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.SourceLink.GitHub" PrivateAssets="All" />
</ItemGroup>
<!-- NuGet Package Assets -->
<ItemGroup>
<None Include="$(MSBuildThisFileDirectory)logo.png" Pack="true" PackagePath="\" />
<None Include="$(MSBuildThisFileDirectory)README.md" Pack="true" PackagePath="\" />
</ItemGroup>
<PropertyGroup>
<PackageIcon>logo.png</PackageIcon>
<PackageReadmeFile>README.md</PackageReadmeFile>
</PropertyGroup>
<!-- Global Using Statements -->
<ItemGroup>
<Using Include="System.Collections.Immutable" />
</ItemGroup>
</Project>
<Copyright>Copyright © 2020-$([System.DateTime]::Now.Year) Your Company</Copyright>
Uses MSBuild property functions to insert current year at build time. No manual updates needed.
Define target frameworks once, reference everywhere:
<!-- In Directory.Build.props -->
<PropertyGroup>
<NetLibVersion>net8.0</NetLibVersion>
<NetTestVersion>net9.0</NetTestVersion>
</PropertyGroup>
<!-- In MyApp.csproj -->
<PropertyGroup>
<TargetFramework>$(NetLibVersion)</TargetFramework>
</PropertyGroup>
<!-- In MyApp.Tests.csproj -->
<PropertyGroup>
<TargetFramework>$(NetTestVersion)</TargetFramework>
</PropertyGroup>
SourceLink enables step-through debugging of NuGet packages:
<PropertyGroup>
<PublishRepositoryUrl>true</PublishRepositoryUrl>
<EmbedUntrackedSources>true</EmbedUntrackedSources>
<IncludeSymbols>true</IncludeSymbols>
<SymbolPackageFormat>snupkg</SymbolPackageFormat>
</PropertyGroup>
<ItemGroup>
<!-- Choose the right provider for your source control -->
<PackageReference Include="Microsoft.SourceLink.GitHub" PrivateAssets="All" />
<!-- Or: Microsoft.SourceLink.AzureRepos.Git -->
<!-- Or: Microsoft.SourceLink.GitLab -->
<!-- Or: Microsoft.SourceLink.Bitbucket.Git -->
</ItemGroup>
Central Package Management (CPM) provides a single source of truth for all NuGet package versions.
<Project>
<PropertyGroup>
<ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>
</PropertyGroup>
<!-- Define version variables for related packages -->
<PropertyGroup>
<AkkaVersion>1.5.35</AkkaVersion>
<AspireVersion>9.1.0</AspireVersion>
</PropertyGroup>
<!-- Application Dependencies -->
<ItemGroup Label="App Dependencies">
<PackageVersion Include="Akka" Version="$(AkkaVersion)" />
<PackageVersion Include="Akka.Cluster" Version="$(AkkaVersion)" />
<PackageVersion Include="Akka.Persistence" Version="$(AkkaVersion)" />
<PackageVersion Include="Microsoft.Extensions.Hosting" Version="9.0.0" />
</ItemGroup>
<!-- Build/Tooling Dependencies -->
<ItemGroup Label="Build Dependencies">
<PackageVersion Include="Microsoft.SourceLink.GitHub" Version="8.0.0" />
</ItemGroup>
<!-- Test Dependencies -->
<ItemGroup Label="Test Dependencies">
<PackageVersion Include="xunit" Version="2.9.3" />
<PackageVersion Include="xunit.runner.visualstudio" Version="3.0.1" />
<PackageVersion Include="FluentAssertions" Version="7.0.0" />
<PackageVersion Include="Microsoft.NET.Test.Sdk" Version="17.12.0" />
<PackageVersion Include="coverlet.collector" Version="6.0.3" />
</ItemGroup>
</Project>
<!-- In MyApp.csproj -->
<ItemGroup>
<PackageReference Include="Akka" />
<PackageReference Include="Akka.Cluster" />
<PackageReference Include="Microsoft.Extensions.Hosting" />
</ItemGroup>
<!-- In MyApp.Tests.csproj -->
<ItemGroup>
<PackageReference Include="xunit" />
<PackageReference Include="FluentAssertions" />
<PackageReference Include="Microsoft.NET.Test.Sdk" />
</ItemGroup>
Pin the .NET SDK version for consistent builds across all environments.
{
"sdk": {
"version": "9.0.200",
"rollForward": "latestFeature"
}
}
| Policy | Behavior |
|---|---|
disable | Exact version required |
patch | Same major.minor, latest patch |
feature | Same major, latest minor.patch |
latestFeature | Same major, latest feature band |
minor | Same major, latest minor |
latestMinor | Same major, latest minor |
Recommended: latestFeature - Allows patch updates within the same feature band.
#### 1.2.0 January 15th 2025 ####
- Added new feature X
- Fixed bug in Y
- Improved performance of Z
#### 1.1.0 December 10th 2024 ####
- Initial release with features A, B, C
function Get-ReleaseNotes {
param (
[Parameter(Mandatory=$true)]
[string]$MarkdownFile
)
$content = Get-Content -Path $MarkdownFile -Raw
$sections = $content -split "####"
$result = [PSCustomObject]@{
Version = $null
Date = $null
ReleaseNotes = $null
}
if ($sections.Count -ge 3) {
$header = $sections[1].Trim()
$releaseNotes = $sections[2].Trim()
$headerParts = $header -split " ", 2
if ($headerParts.Count -eq 2) {
$result.Version = $headerParts[0]
$result.Date = $headerParts[1]
}
$result.ReleaseNotes = $releaseNotes
}
return $result
}
function UpdateVersionAndReleaseNotes {
param (
[Parameter(Mandatory=$true)]
[PSCustomObject]$ReleaseNotesResult,
[Parameter(Mandatory=$true)]
[string]$XmlFilePath
)
$xmlContent = New-Object XML
$xmlContent.Load($XmlFilePath)
# Update VersionPrefix
$versionElement = $xmlContent.SelectSingleNode("//VersionPrefix")
$versionElement.InnerText = $ReleaseNotesResult.Version
# Update PackageReleaseNotes
$notesElement = $xmlContent.SelectSingleNode("//PackageReleaseNotes")
$notesElement.InnerText = $ReleaseNotesResult.ReleaseNotes
$xmlContent.Save($XmlFilePath)
}
# Load helper scripts
. "$PSScriptRoot\scripts\getReleaseNotes.ps1"
. "$PSScriptRoot\scripts\bumpVersion.ps1"
# Parse release notes and update Directory.Build.props
$releaseNotes = Get-ReleaseNotes -MarkdownFile (Join-Path -Path $PSScriptRoot -ChildPath "RELEASE_NOTES.md")
UpdateVersionAndReleaseNotes -ReleaseNotesResult $releaseNotes -XmlFilePath (Join-Path -Path $PSScriptRoot -ChildPath "Directory.Build.props")
Write-Output "Updated to version $($releaseNotes.Version)"
# GitHub Actions example
- name: Update version from release notes
shell: pwsh
run: ./build.ps1
- name: Build
run: dotnet build -c Release
- name: Pack with tag version
run: dotnet pack -c Release /p:PackageVersion=${{ github.ref_name }}
- name: Push to NuGet
run: dotnet nuget push **/*.nupkg --api-key ${{ secrets.NUGET_API_KEY }} --source https://api.nuget.org/v3/index.json
Configure NuGet sources and behavior:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<solution>
<add key="disableSourceControlIntegration" value="true" />
</solution>
<packageSources>
<clear />
<add key="nuget.org" value="https://api.nuget.org/v3/index.json" />
<!-- Add private feeds if needed -->
<!-- <add key="MyCompany" value="https://pkgs.dev.azure.com/myorg/_packaging/myfeed/nuget/v3/index.json" /> -->
</packageSources>
</configuration>
Key Settings:
<clear /> - Remove inherited/default sources for reproducible buildsdisableSourceControlIntegration - Prevents TFS/Git integration issuesMySolution/
├── .config/
│ └── dotnet-tools.json # Local .NET tools
├── .github/
│ └── workflows/
│ ├── pr-validation.yml # PR checks
│ └── release.yml # NuGet publishing
├── scripts/
│ ├── getReleaseNotes.ps1 # Parse RELEASE_NOTES.md
│ └── bumpVersion.ps1 # Update Directory.Build.props
├── src/
│ ├── MyApp/
│ │ └── MyApp.csproj
│ └── MyApp.Core/
│ └── MyApp.Core.csproj
├── tests/
│ └── MyApp.Tests/
│ └── MyApp.Tests.csproj
├── Directory.Build.props # Centralized build config
├── Directory.Packages.props # Central package versions
├── MySolution.slnx # Modern solution file
├── global.json # SDK version pinning
├── NuGet.Config # Package source config
├── build.ps1 # Build orchestration
├── RELEASE_NOTES.md # Version history
├── README.md # Project documentation
└── logo.png # Package icon
| File | Purpose |
|---|---|
MySolution.slnx | Modern XML solution file |
Directory.Build.props | Centralized build properties |
Directory.Packages.props | Central package version management |
global.json | SDK version pinning |
NuGet.Config | Package source configuration |
RELEASE_NOTES.md |
Weekly Installs
120
Repository
GitHub Stars
495
First Seen
Jan 28, 2026
Security Audits
Gen Agent Trust HubPassSocketPassSnykPass
Installed on
claude-code87
codex80
github-copilot77
opencode77
gemini-cli74
kimi-cli71
Angular编译器CLI (ngtsc) 架构详解:Ivy编译、模板类型检查与AOT
402 周安装
major | Latest SDK (not recommended) |
| Version history (parsed by build) |
build.ps1 | Build orchestration script |
.config/dotnet-tools.json | Local .NET tools |