ci(build): 添加CI/CD工作流并修复包依赖配置

- 配置CI工作流支持PR时执行代码质量检查、构建和测试
- 设置发布工作流支持标签推送时自动打包发布到NuGet和GitHub Packages
- 修复源代码生成器项目的包依赖配置,统一使用GFramework.SourceGenerators.Common命名
- 配置多版本.NET SDK支持及相应的缓存策略
- 实现并行测试执行和统一的测试报告生成机制
- 添加安全扫描和代码质量检查集成
This commit is contained in:
GeWuYou 2026-04-17 19:54:58 +08:00 committed by gewuyou
parent c721c5aed1
commit 6933d2799a
3 changed files with 78 additions and 39 deletions

View File

@ -117,7 +117,7 @@ jobs:
# 执行NuGet包恢复操作 # 执行NuGet包恢复操作
- name: Restore - name: Restore
run: dotnet restore run: dotnet restore GFramework.sln
# 恢复.NET本地工具 # 恢复.NET本地工具
- name: Restore .NET tools - name: Restore .NET tools
run: dotnet tool restore run: dotnet tool restore
@ -142,49 +142,46 @@ jobs:
# 构建项目使用Release配置且跳过恢复步骤 # 构建项目使用Release配置且跳过恢复步骤
- name: Build - name: Build
run: dotnet build -c Release --no-restore run: dotnet build GFramework.sln -c Release --no-restore
# 运行单元测试输出TRX格式结果到TestResults目录 # 运行单元测试输出TRX格式结果到TestResults目录
# 在同一个 step 中并发执行所有测试以加快速度 # 在同一个 step 中并发执行所有测试以加快速度
- name: Test All Projects - name: Test All Projects
run: | run: |
dotnet test GFramework.Core.Tests \ set -euo pipefail
-c Release \
--no-build \
--logger "trx;LogFileName=core-$RANDOM.trx" \
--results-directory TestResults &
dotnet test GFramework.Game.Tests \ test_projects=(
-c Release \ "GFramework.Core.Tests/GFramework.Core.Tests.csproj:core"
--no-build \ "GFramework.Game.Tests/GFramework.Game.Tests.csproj:game"
--logger "trx;LogFileName=game-$RANDOM.trx" \ "GFramework.SourceGenerators.Tests/GFramework.SourceGenerators.Tests.csproj:sg"
--results-directory TestResults & "GFramework.Cqrs.Tests/GFramework.Cqrs.Tests.csproj:cqrs"
"GFramework.Ecs.Arch.Tests/GFramework.Ecs.Arch.Tests.csproj:ecs-arch"
"GFramework.Godot.Tests/GFramework.Godot.Tests.csproj:godot"
"GFramework.Godot.SourceGenerators.Tests/GFramework.Godot.SourceGenerators.Tests.csproj:godot-sg"
)
dotnet test GFramework.SourceGenerators.Tests \ pids=()
-c Release \ for entry in "${test_projects[@]}"; do
--no-build \ project="${entry%%:*}"
--logger "trx;LogFileName=sg-$RANDOM.trx" \ name="${entry##*:}"
--results-directory TestResults &
dotnet test GFramework.Cqrs.Tests \ dotnet test "$project" \
-c Release \ -c Release \
--no-build \ --no-build \
--logger "trx;LogFileName=cqrs-$RANDOM.trx" \ --logger "trx;LogFileName=${name}-$RANDOM.trx" \
--results-directory TestResults & --results-directory TestResults &
dotnet test GFramework.Ecs.Arch.Tests \ pids+=("$!")
-c Release \ done
--no-build \
--logger "trx;LogFileName=ecs-arch-$RANDOM.trx" \
--results-directory TestResults &
dotnet test GFramework.Godot.Tests \ failed=0
-c Release \ for pid in "${pids[@]}"; do
--no-build \ if ! wait "$pid"; then
--logger "trx;LogFileName=godot-$RANDOM.trx" \ failed=1
--results-directory TestResults & fi
# 等待所有后台测试完成 done
wait
exit "$failed"
- name: Generate CTRF report - name: Generate CTRF report
run: | run: |

View File

@ -52,7 +52,7 @@ jobs:
key: ${{ runner.os }}-nuget-${{ hashFiles('**/*.csproj') }} key: ${{ runner.os }}-nuget-${{ hashFiles('**/*.csproj') }}
- name: Restore dependencies - name: Restore dependencies
run: dotnet restore run: dotnet restore GFramework.sln
# 从 GitHub 引用中提取标签版本。 # 从 GitHub 引用中提取标签版本。
# 提取逻辑:去除 refs/tags/ 前缀,然后去除 v/V 前缀。 # 提取逻辑:去除 refs/tags/ 前缀,然后去除 v/V 前缀。
@ -71,7 +71,49 @@ jobs:
run: | run: |
set -e set -e
echo "Packing with version=${{ steps.tag_version.outputs.version }}" echo "Packing with version=${{ steps.tag_version.outputs.version }}"
dotnet pack -c Release -o ./packages -p:PackageVersion=${{ steps.tag_version.outputs.version }} -p:IncludeSymbols=false dotnet pack GFramework.sln \
-c Release \
--no-restore \
-o ./packages \
-p:PackageVersion=${{ steps.tag_version.outputs.version }} \
-p:IncludeSymbols=false
- name: Validate packed modules
run: |
set -euo pipefail
expected_packages=(
"GeWuYou.GFramework"
"GeWuYou.GFramework.Core"
"GeWuYou.GFramework.Core.Abstractions"
"GeWuYou.GFramework.Core.SourceGenerators"
"GeWuYou.GFramework.Cqrs"
"GeWuYou.GFramework.Cqrs.Abstractions"
"GeWuYou.GFramework.Cqrs.SourceGenerators"
"GeWuYou.GFramework.Ecs.Arch"
"GeWuYou.GFramework.Ecs.Arch.Abstractions"
"GeWuYou.GFramework.Game"
"GeWuYou.GFramework.Game.Abstractions"
"GeWuYou.GFramework.Game.SourceGenerators"
"GeWuYou.GFramework.Godot"
"GeWuYou.GFramework.Godot.SourceGenerators"
)
mapfile -t actual_packages < <(
find ./packages -maxdepth 1 -type f -name '*.nupkg' -printf '%f\n' \
| sed -E 's/\.[0-9][0-9A-Za-z.-]*\.nupkg$//' \
| sort -u
)
printf '%s\n' "${expected_packages[@]}" | sort > expected-packages.txt
printf '%s\n' "${actual_packages[@]}" | sort > actual-packages.txt
echo "Expected packages:"
cat expected-packages.txt
echo "Actual packages:"
cat actual-packages.txt
diff -u expected-packages.txt actual-packages.txt
- name: Show packages - name: Show packages
run: ls -la ./packages || true run: ls -la ./packages || true

View File

@ -52,7 +52,7 @@
PackagePath="analyzers/dotnet/cs" PackagePath="analyzers/dotnet/cs"
Visible="false"/> Visible="false"/>
<!-- ★ Generator 运行期依赖 --> <!-- ★ Generator 运行期依赖 -->
<None Include="$(OutputPath)\$(AssemblyName).Common.dll" <None Include="$(OutputPath)\GFramework.SourceGenerators.Common.dll"
Pack="true" Pack="true"
PackagePath="analyzers/dotnet/cs" PackagePath="analyzers/dotnet/cs"
Visible="false"/> Visible="false"/>
@ -61,8 +61,8 @@
<ItemGroup> <ItemGroup>
<None Include="$(OutputPath)\$(AssemblyName).Abstractions.dll" Pack="true" PackagePath="lib\netstandard2.0" Visible="true"/> <None Include="$(OutputPath)\$(AssemblyName).Abstractions.dll" Pack="true" PackagePath="lib\netstandard2.0" Visible="true"/>
<None Include="$(OutputPath)\$(AssemblyName).Abstractions.xml" Pack="true" PackagePath="lib\netstandard2.0" Visible="true"/> <None Include="$(OutputPath)\$(AssemblyName).Abstractions.xml" Pack="true" PackagePath="lib\netstandard2.0" Visible="true"/>
<None Include="$(OutputPath)\$(AssemblyName).Common.dll" Pack="true" PackagePath="lib\netstandard2.0" Visible="true"/> <None Include="$(OutputPath)\GFramework.SourceGenerators.Common.dll" Pack="true" PackagePath="lib\netstandard2.0" Visible="true"/>
<None Include="$(OutputPath)\$(AssemblyName).Common.xml" Pack="true" PackagePath="lib\netstandard2.0" Visible="true"/> <None Include="$(OutputPath)\GFramework.SourceGenerators.Common.xml" Pack="true" PackagePath="lib\netstandard2.0" Visible="true"/>
<None Include="GeWuYou.GFramework.Core.SourceGenerators.targets" Pack="true" PackagePath="build" Visible="false"/> <None Include="GeWuYou.GFramework.Core.SourceGenerators.targets" Pack="true" PackagePath="build" Visible="false"/>
</ItemGroup> </ItemGroup>
</Project> </Project>