ci(cqrs): 新增手动 benchmark 工作流

- 新增仅支持 workflow_dispatch 的 Benchmark workflow,默认只验证 benchmark 项目 Release build
- 补充可选 benchmark_filter 输入与 BenchmarkDotNet 工件上传,支持按场景手动执行基准测试
- 更新 cqrs-rewrite 跟踪与 trace,记录手动 benchmark workflow 的用途与当前 startup benchmark 残留风险
This commit is contained in:
gewuyou 2026-05-06 11:48:15 +08:00
parent 2ac02c1a6f
commit f71791ae98
3 changed files with 82 additions and 3 deletions

69
.github/workflows/benchmark.yml vendored Normal file
View File

@ -0,0 +1,69 @@
# Copyright (c) 2025-2026 GeWuYou
# SPDX-License-Identifier: Apache-2.0
name: Benchmark
on:
workflow_dispatch:
inputs:
benchmark_filter:
description: '可选的 BenchmarkDotNet 过滤器;留空时仅执行 benchmark 项目 Release build'
required: false
default: ''
type: string
permissions:
contents: read
jobs:
benchmark:
name: Benchmark Build Or Run
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v6
with:
fetch-depth: 0
- name: Setup .NET 10
uses: actions/setup-dotnet@v5
with:
dotnet-version: 10.0.x
- name: Cache NuGet packages
uses: actions/cache@v5
with:
path: |
~/.nuget/packages
~/.local/share/NuGet
key: ${{ runner.os }}-nuget-benchmarks-${{ hashFiles('GFramework.Cqrs.Benchmarks/*.csproj', 'GFramework.Cqrs/*.csproj', 'GFramework.Cqrs.Abstractions/*.csproj', 'GFramework.Core/*.csproj', 'GFramework.Core.Abstractions/*.csproj', '**/nuget.config') }}
- name: Restore benchmark project
run: dotnet restore GFramework.Cqrs.Benchmarks/GFramework.Cqrs.Benchmarks.csproj
- name: Build benchmark project
run: dotnet build GFramework.Cqrs.Benchmarks/GFramework.Cqrs.Benchmarks.csproj -c Release --no-restore
- name: Report build-only mode
if: ${{ inputs.benchmark_filter == '' }}
run: |
echo "No benchmark filter provided."
echo "Workflow completed after validating the benchmark project build."
- name: Run filtered benchmarks
if: ${{ inputs.benchmark_filter != '' }}
run: |
set -euo pipefail
dotnet run --project GFramework.Cqrs.Benchmarks/GFramework.Cqrs.Benchmarks.csproj -c Release --no-build -- \
--filter "${{ inputs.benchmark_filter }}"
- name: Upload BenchmarkDotNet artifacts
if: ${{ always() && inputs.benchmark_filter != '' }}
uses: actions/upload-artifact@v7
with:
name: benchmark-artifacts
path: |
BenchmarkDotNet.Artifacts/**
GFramework.Cqrs.Benchmarks/bin/Release/net10.0/BenchmarkDotNet.Artifacts/**
if-no-files-found: ignore

View File

@ -32,6 +32,7 @@ CQRS 迁移与收敛。
- 当前分支对应 `PR #326`,状态为 `OPEN`
- latest-head review 仍以 `ai-plan` 恢复文档收敛为主要待闭环项;代码与测试侧的本地有效问题已收敛
- `RequestStartupBenchmarks` 已修复 baseline 分组冲突、MediatR 13 logging/license 构造失败与重复注册问题,但 `ColdStart_GFrameworkCqrs` 仍存在 `No CQRS request handler registered` 的运行级残留
- 已新增手动触发的 benchmark workflow默认只验证 benchmark 项目 Release build只有显式提供过滤器时才执行 BenchmarkDotNet 运行
- 远端 `CTRF` 最新汇总为 `2274/2274` passed
- `MegaLinter` 当前只暴露 `dotnet-format``Restore operation failed` 环境噪音,尚未提供本地仍成立的文件级格式诊断
@ -44,14 +45,17 @@ CQRS 迁移与收敛。
## 最近权威验证
- `dotnet build GFramework.Cqrs.Benchmarks/GFramework.Cqrs.Benchmarks.csproj -c Release`
- 结果:通过,`0 warning / 0 error`
- 备注:用于验证新增手动 benchmark workflow 依赖的 benchmark 项目入口仍可在 Release 下编译
- `python3 .agents/skills/gframework-pr-review/scripts/fetch_current_pr_review.py --format json --json-output <temporary-json-output>`
- 结果:通过
- 备注:确认当前分支对应 `PR #326`,本轮剩余 open AI feedback 主要集中在 benchmark 对照语义与 `ai-plan` 结构收敛
- `git diff --check`
- 结果:通过
- `python3 scripts/license-header.py --check`
- 结果:通过
- 备注:当前 WSL worktree 需要显式绑定 `GIT_DIR` / `GIT_WORK_TREE` 后运行
- `git diff --check`
- 结果:通过
- `dotnet build GFramework.SourceGenerators.Tests/GFramework.SourceGenerators.Tests.csproj -c Release`
- 结果:通过,`0 warning / 0 error`
- `dotnet test GFramework.SourceGenerators.Tests/GFramework.SourceGenerators.Tests.csproj -c Release --filter "FullyQualifiedName~CqrsHandlerRegistryGeneratorTests.Emits_Request_Invoker_Provider_Metadata_In_Stable_Order_For_Mixed_Direct_And_Reflected_Implementations|FullyQualifiedName~CqrsHandlerRegistryGeneratorTests.Emits_Stream_Invoker_Provider_Metadata_In_Stable_Order_For_Mixed_Direct_And_Reflected_Implementations"`
@ -116,7 +120,7 @@ CQRS 迁移与收敛。
1. 继续处理 `PR #326` 的剩余 review 收尾,优先保持 benchmark 对照语义与 `ai-plan` active 入口一致
2. 优先定位 `RequestStartupBenchmarks.ColdStart_GFrameworkCqrs` 在清空 dispatcher 缓存后的 request handler 绑定缺口,再决定是调整最小宿主注册方式还是补充专用 benchmark fixture
3. 若继续推进“吸收 Mediator 设计哲学”的切片,优先扩展 benchmark 场景矩阵到 registration / service lifetime、notification publish strategy 或更贴近 `Mediator` concrete runtime 的对照
3. 若需要在 CI 中手动复核 benchmark优先使用新增 workflow 的 `benchmark_filter` 输入按场景筛选,避免默认运行命中当前已知 startup 残留
## 活跃文档

View File

@ -466,3 +466,9 @@
- 结果:通过
- `dotnet run --project GFramework.Cqrs.Benchmarks/GFramework.Cqrs.Benchmarks.csproj -c Release -- --filter "*RequestStartupBenchmarks*" --job short --warmupCount 1 --iterationCount 1 --launchCount 1`
- 结果:部分通过;`MediatR` startup benchmark 已恢复真实测量,`ColdStart_GFrameworkCqrs` 仍因 `No CQRS request handler registered` 失败
### 阶段:手动 benchmark workflowCQRS-REWRITE-RP-089
- 新增 `.github/workflows/benchmark.yml`,提供仅 `workflow_dispatch` 触发的 benchmark 入口
- workflow 默认只执行 `GFramework.Cqrs.Benchmarks` 的 Release build避免在当前已知 `RequestStartupBenchmarks` 残留未清时默认运行失败
- 只有在手动输入 `benchmark_filter` 时才执行 BenchmarkDotNet并上传 `BenchmarkDotNet.Artifacts` 供后续比较