-
Notifications
You must be signed in to change notification settings - Fork 16
159 lines (136 loc) · 5.52 KB
/
benchmark.yml
File metadata and controls
159 lines (136 loc) · 5.52 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
name: benchmark
on:
pull_request:
branches:
- master
types: [opened, synchronize, reopened]
permissions:
pull-requests: write
issues: write
jobs:
benchmark:
runs-on: ubuntu-latest
steps:
# Step 1: Checkout the PR branch
- name: Checkout PR branch
uses: actions/checkout@v6
with:
fetch-depth: 0 # Fetch all history for comparison
# Step 2: Setup PHP
- name: Setup PHP
uses: shivammathur/setup-php@bf6b4fbd49ca58e4608c9c89fba0b8d90bd2a39f
with:
php-version: '8.5'
extensions: zip, curl, mbstring, xml
coverage: none
tools: composer:v2
# Step 2.1: Install PHPBench globally
- name: Install PHPBench
run: |
composer global require phpbench/phpbench:^1.6 --prefer-dist --no-progress --no-interaction
PHPBENCH_BIN="$(composer global config bin-dir --absolute)/phpbench"
echo "PHPBENCH_BIN=$PHPBENCH_BIN" >> "$GITHUB_ENV"
"$PHPBENCH_BIN" --version
# Step 3: Install dependencies for PR branch
- name: Install Composer dependencies
run: |
# Remove dependency artifacts that can leak across branch switches in CI
git clean -ffdx -- composer.lock vendor
composer install --prefer-dist --no-progress
# Step 4: Run benchmarks on PR branch
- name: Run benchmarks on PR branch
run: |
mkdir -p tests/Benchmark
"$PHPBENCH_BIN" run tests/Benchmark \
--report=default \
--tag=pr \
--retry-threshold=5 \
--iterations=10
# Step 5: Checkout base branch
- name: Checkout base branch
run: |
git fetch origin "$BASE_REF"
git checkout "origin/$BASE_REF"
env:
BASE_REF: ${{ github.base_ref }}
# Step 5.1: Diagnose Composer state on base branch
- name: Diagnose Composer state (base)
run: |
echo "Commit: $(git rev-parse --short HEAD)"
echo "Base ref: origin/$BASE_REF"
echo "phpunit/phpunit constraint in composer.json:"
grep -n '"phpunit/phpunit"' composer.json || true
if [ -f composer.lock ]; then
echo "composer.lock present before cleanup"
php -r '$lock = json_decode(file_get_contents("composer.lock"), true); $version = "not-found"; foreach (($lock["packages-dev"] ?? []) as $pkg) { if (($pkg["name"] ?? "") === "phpunit/phpunit") { $version = $pkg["version"] ?? "unknown"; break; } } echo "locked phpunit/phpunit: {$version}\n";'
else
echo "composer.lock missing before cleanup"
fi
echo "ignore status for composer.lock:"
git check-ignore -v composer.lock || true
echo "git status snapshot:"
git status --short -- composer.json composer.lock vendor || true
env:
BASE_REF: ${{ github.base_ref }}
# Step 6: Install dependencies for base branch
- name: Install Composer dependencies (base)
run: |
# Ensure install uses only files from the checked out base branch
git clean -ffdx -- composer.lock vendor
composer install --prefer-dist --no-progress
# Step 7: Run benchmarks on base branch
- name: Run benchmarks on base branch
run: |
mkdir -p tests/Benchmark
"$PHPBENCH_BIN" run tests/Benchmark \
--report=default \
--tag=base \
--retry-threshold=5 \
--iterations=10
# Step 8: Checkout PR branch again
- name: Checkout PR branch again
run: git checkout "$HEAD_REF"
env:
HEAD_REF: ${{ github.head_ref }}
# Step 8.1: Reinstall dependencies for PR branch
- name: Install Composer dependencies (PR, comparison)
run: |
# Prevent base branch dependency artifacts from affecting PR comparison run
git clean -ffdx -- composer.lock vendor
composer install --prefer-dist --no-progress
# Step 9: Compare benchmarks
- name: Compare benchmarks with baseline
id: compare
run: |
mkdir -p tests/Benchmark
"$PHPBENCH_BIN" run tests/Benchmark \
--report=aggregate \
--ref=base \
--retry-threshold=5 \
--iterations=10 \
--tag=pr \
--assert="mode(variant.time.avg) <= mode(baseline.time.avg) +/- 2%" \
| tee benchmark-comparison.txt
continue-on-error: true
# Step 10: Post results as PR comment
- name: Comment PR with benchmark results
if: ${{ github.actor != 'dependabot[bot]' }}
uses: actions/github-script@v9
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
script: |
const fs = require('fs');
const results = fs.readFileSync('benchmark-comparison.txt', 'utf8');
const body = `## 📊 Benchmark Results\n\n\`\`\`\n${results}\n\`\`\`\n\n**Note:** Benchmarks compare PR against \`${{ github.base_ref }}\` branch.\nPerformance regression threshold: ±2%`;
github.rest.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
body: body
});
# Step 11: Fail if performance degrades
- name: Check benchmark assertions
if: steps.compare.outcome == 'failure'
run: |
echo "::error::Performance regression detected! Benchmarks exceeded acceptable threshold."
exit 1