-
Notifications
You must be signed in to change notification settings - Fork 0
216 lines (190 loc) · 8.17 KB
/
Copy pathbenchmark.yml
File metadata and controls
216 lines (190 loc) · 8.17 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
name: Benchmarks
on:
# Auto-triggered when a GitHub Release is published
release:
types: [published]
# Manual trigger — restricted to 'Developpement' environment (AriusII approval)
workflow_dispatch:
inputs:
category:
description: 'Benchmark category to run'
required: false
default: 'all'
type: choice
options:
- all
- in-memory
- tvp
- sql-server
- collections
- cache
- auto-contracts
# Minimal default permissions
permissions:
contents: write # needed to commit results back to repo
concurrency:
group: benchmark
cancel-in-progress: false
env:
DOTNET_SKIP_FIRST_TIME_EXPERIENCE: true
DOTNET_CLI_TELEMETRY_OPTOUT: true
DOTNET_NOLOGO: true
FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: 'true'
SA_PASSWORD: 'BenchmarkP@ss2026!'
jobs:
benchmark:
name: Run Benchmarks (${{ github.event.inputs.category || 'all' }})
runs-on: ubuntu-latest
# Developpement environment for manual dispatch; no gate needed for automated release trigger.
environment: ${{ github.event_name == 'workflow_dispatch' && 'Developpement' || '' }}
# SQL Server 2022 service container for SQL benchmarks
services:
sqlserver:
image: mcr.microsoft.com/mssql/server:2022-latest
env:
SA_PASSWORD: ${{ env.SA_PASSWORD }}
ACCEPT_EULA: 'Y'
MSSQL_PID: Developer
ports:
- 1433:1433
options: >-
--health-cmd "/bin/bash -c 'echo > /dev/tcp/127.0.0.1/1433'"
--health-interval 5s
--health-timeout 3s
--health-retries 24
--health-start-period 20s
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0
token: ${{ secrets.GITHUB_TOKEN }}
- name: Setup .NET from global.json
uses: actions/setup-dotnet@v4
with:
global-json-file: global.json
- name: Display .NET SDK info
run: dotnet --info
- name: Cache NuGet packages
uses: actions/cache@v6
with:
path: ~/.nuget/packages
key: nuget-bench-${{ runner.os }}-${{ hashFiles('global.json', '**/*.csproj', '**/*.slnx') }}
restore-keys: nuget-bench-${{ runner.os }}-
- name: Restore dependencies
run: dotnet restore CaeriusNet.slnx
- name: Build (Release)
run: |
dotnet build Benchmark/CaeriusNet.Benchmark.csproj \
--configuration Release \
--no-restore
- name: Wait for SQL Server to be ready
run: |
# The service container health check (TCP /dev/tcp) guarantees port 1433 is
# open before steps begin. This step adds explicit diagnostic output.
echo "⏳ Verifying SQL Server port 1433 is reachable on localhost..."
for i in $(seq 1 12); do
if bash -c '(echo > /dev/tcp/localhost/1433) 2>/dev/null'; then
echo "✅ SQL Server port 1433 is open (attempt $i)."
exit 0
fi
echo " Attempt $i/12 — port not open yet, retrying in 5s..."
sleep 5
done
echo "❌ SQL Server port 1433 did not open after 12 attempts. Aborting."
exit 1
- name: Run Benchmarks
env:
BENCHMARK_SQL_CONNECTION: "Server=localhost,1433;Database=master;User Id=sa;Password=${{ env.SA_PASSWORD }};TrustServerCertificate=True"
# Explicit artifact path — read by BenchmarkConfig.cs via env var.
# InProcessEmitToolchain guarantees files are written here (no child process CWD ambiguity).
BENCHMARK_ARTIFACTS_PATH: ${{ github.workspace }}/BenchmarkDotNet.Artifacts
CI: 'true'
run: |
CATEGORY="${{ github.event.inputs.category || 'all' }}"
echo "🚀 Running benchmarks: category=${CATEGORY}"
cd Benchmark && dotnet run \
--project CaeriusNet.Benchmark.csproj \
--configuration Release \
--no-build \
-- "${CATEGORY}"
- name: Verify artifact output
if: always()
run: |
ARTIFACTS="${{ github.workspace }}/BenchmarkDotNet.Artifacts/results"
echo "=== Configured artifact path ==="
echo "$ARTIFACTS"
echo "=== Directory listing ==="
ls -la "$ARTIFACTS" 2>/dev/null || echo "⚠️ Directory not found: $ARTIFACTS"
echo "=== GitHub-flavoured Markdown reports (*-report-github.md) ==="
find "$ARTIFACTS" -name "*-report-github.md" 2>/dev/null || echo " (none found)"
echo "=== JSON reports (*-report-full.json) ==="
find "$ARTIFACTS" -name "*-report-full.json" 2>/dev/null || echo " (none found)"
- name: Extract results into documentation
if: always()
run: |
ARTIFACTS="${{ github.workspace }}/BenchmarkDotNet.Artifacts/results"
DOCS_DIR="Documentations/docs/benchmarks/results"
mkdir -p "$DOCS_DIR"
if [ ! -d "$ARTIFACTS" ] || [ -z "$(ls -A "$ARTIFACTS" 2>/dev/null)" ]; then
echo "⚠️ No artifacts at $ARTIFACTS — skipping extraction."
exit 0
fi
echo "📂 Artifact files:"
ls -la "$ARTIFACTS"
# Copy full JSON reports for data analysis
cp "$ARTIFACTS"/*.json "$DOCS_DIR/" 2>/dev/null && echo "✅ JSON files copied." || echo "ℹ️ No JSON files."
# MarkdownExporter.GitHub produces *-report-github.md files.
# Extract only table rows (lines starting with '|') to strip BDN environment headers.
extracted=0
skipped=0
for md_file in "$ARTIFACTS"/*-report-github.md; do
[ -f "$md_file" ] || continue
# Strip namespace prefix, keep ClassName only:
# e.g. "CaeriusNet.Benchmark.Workshops.Benchs.Mapping.DtoMappingBench-report-github.md"
# → "DtoMappingBench"
classname=$(basename "$md_file" "-report-github.md" | rev | cut -d'.' -f1 | rev)
out_file="$DOCS_DIR/${classname}.md"
awk '/^\|/' "$md_file" > "$out_file"
line_count=$(wc -l < "$out_file")
if [ "$line_count" -lt 3 ]; then
echo " ⚠️ ${classname}.md has only ${line_count} line(s) — skipping (expected header + separator + ≥1 data row)."
rm -f "$out_file"
skipped=$((skipped + 1))
else
echo " ✅ ${classname}.md (${line_count} lines)"
extracted=$((extracted + 1))
fi
done
echo "📊 Extraction summary: ${extracted} file(s) written, ${skipped} skipped."
echo "📋 Documentation results directory:"
ls -la "$DOCS_DIR"
- name: Commit benchmark results to documentation
# Only auto-commit on GitHub Release events — never on manual workflow_dispatch
if: always() && github.event_name == 'release'
run: |
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
git add Documentations/docs/benchmarks/results/ || true
if git diff --staged --quiet; then
echo "ℹ️ No benchmark result changes to commit."
else
CATEGORY="${{ github.event.inputs.category || 'all' }}"
VERSION=$(grep -oP '(?<=<Version>)\d+\.\d+\.\d+(?=</Version>)' Src/CaeriusNet.csproj || echo "unknown")
COMMIT_SHA="${{ github.sha }}"
SHORT_SHA="${COMMIT_SHA:0:7}"
git commit -m "chore(bench): update benchmark results v${VERSION} [category:${CATEGORY}] [run:${SHORT_SHA}] [skip ci]"
git push
echo "✅ Benchmark results committed."
fi
- name: Upload benchmark artifacts
if: always()
uses: actions/upload-artifact@v5
with:
name: "benchmark-reports-${{ github.run_number }}"
path: |
${{ github.workspace }}/BenchmarkDotNet.Artifacts/results/*-report-github.md
${{ github.workspace }}/BenchmarkDotNet.Artifacts/results/*-report-full.json
Documentations/docs/benchmarks/results/
retention-days: 90
if-no-files-found: warn