Skip to content

Commit 87c1f93

Browse files
authored
chore: add sharding to e2e test run (#1485)
1 parent 4ba37e5 commit 87c1f93

File tree

1 file changed

+91
-25
lines changed

1 file changed

+91
-25
lines changed

.github/workflows/main.yml

Lines changed: 91 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -99,14 +99,18 @@ jobs:
9999
working-directory: ./smoke-tests/otel-collector
100100
run: bats .
101101
e2e-tests:
102-
name: End-to-End Tests
102+
name: E2E Tests - Shard ${{ matrix.shard }}
103103
runs-on: ubuntu-24.04
104104
timeout-minutes: 15
105105
container:
106106
image: mcr.microsoft.com/playwright:v1.57.0-jammy
107107
permissions:
108108
contents: read
109109
pull-requests: write
110+
strategy:
111+
fail-fast: false
112+
matrix:
113+
shard: [1, 2, 3, 4]
110114

111115
steps:
112116
- name: Checkout
@@ -128,60 +132,94 @@ jobs:
128132
- name: Run Playwright tests
129133
run: |
130134
cd packages/app
131-
yarn test:e2e
135+
yarn test:e2e --shard=${{ matrix.shard }}/4
132136
133137
- name: Upload Playwright report
134138
uses: actions/upload-artifact@v4
135139
if: always()
136140
with:
137-
name: playwright-report
141+
name: playwright-report-${{ matrix.shard }}
138142
path: packages/app/playwright-report/
139143
retention-days: 30
140144

141145
- name: Upload test results
142146
uses: actions/upload-artifact@v4
143147
if: always()
144148
with:
145-
name: test-results
149+
name: test-results-${{ matrix.shard }}
146150
path: packages/app/test-results/
147151
retention-days: 30
148152

149-
- name: Generate test results message
153+
e2e-report:
154+
name: End-to-End Tests
155+
if: always()
156+
needs: e2e-tests
157+
runs-on: ubuntu-24.04
158+
permissions:
159+
contents: read
160+
pull-requests: write
161+
162+
steps:
163+
- name: Download all test results
164+
uses: actions/download-artifact@v4
165+
with:
166+
pattern: test-results-*
167+
path: all-test-results
168+
169+
- name: Aggregate test results
150170
id: test-results
151-
if: always() && github.event_name == 'pull_request'
171+
if: github.event_name == 'pull_request'
152172
uses: actions/github-script@v7
153173
with:
154174
result-encoding: string
155175
script: |
156176
const fs = require('fs');
157177
const path = require('path');
158178
179+
let totalPassed = 0;
180+
let totalFailed = 0;
181+
let totalFlaky = 0;
182+
let totalSkipped = 0;
183+
let totalDuration = 0;
184+
let foundResults = false;
185+
159186
try {
160-
const resultsPath = path.join('packages/app/test-results/results.json');
161-
if (fs.existsSync(resultsPath)) {
162-
const results = JSON.parse(fs.readFileSync(resultsPath, 'utf8'));
163-
const { stats } = results;
164-
165-
const failed = stats.unexpected || 0;
166-
const passed = stats.expected || 0;
167-
const flaky = stats.flaky || 0;
168-
const skipped = stats.skipped || 0;
169-
const duration = Math.round((stats.duration || 0) / 1000);
170-
171-
const summary = failed > 0
172-
? `❌ **${failed} test${failed > 1 ? 's' : ''} failed**`
187+
const resultsDir = 'all-test-results';
188+
const shards = fs.readdirSync(resultsDir);
189+
190+
for (const shard of shards) {
191+
const resultsPath = path.join(resultsDir, shard, 'results.json');
192+
if (fs.existsSync(resultsPath)) {
193+
foundResults = true;
194+
const results = JSON.parse(fs.readFileSync(resultsPath, 'utf8'));
195+
const { stats } = results;
196+
197+
totalPassed += stats.expected || 0;
198+
totalFailed += stats.unexpected || 0;
199+
totalFlaky += stats.flaky || 0;
200+
totalSkipped += stats.skipped || 0;
201+
totalDuration += stats.duration || 0;
202+
}
203+
}
204+
205+
if (foundResults) {
206+
const duration = Math.round(totalDuration / 1000);
207+
const summary = totalFailed > 0
208+
? `❌ **${totalFailed} test${totalFailed > 1 ? 's' : ''} failed**`
173209
: `✅ **All tests passed**`;
174210
175211
return `## E2E Test Results
176212
177-
${summary} • ${passed} passed • ${skipped} skipped • ${duration}s
213+
${summary} • ${totalPassed} passed • ${totalSkipped} skipped • ${duration}s
178214
179215
| Status | Count |
180216
|--------|-------|
181-
| ✅ Passed | ${passed} |
182-
| ❌ Failed | ${failed} |
183-
| ⚠️ Flaky | ${flaky} |
184-
| ⏭️ Skipped | ${skipped} |
217+
| ✅ Passed | ${totalPassed} |
218+
| ❌ Failed | ${totalFailed} |
219+
| ⚠️ Flaky | ${totalFlaky} |
220+
| ⏭️ Skipped | ${totalSkipped} |
221+
222+
Tests ran across ${shards.length} shards in parallel.
185223
186224
[View full report →](https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }})`;
187225
} else {
@@ -195,7 +233,7 @@ jobs:
195233
console.log('Could not parse test results:', error.message);
196234
return `## E2E Test Results
197235
198-
❌ **Error reading test results**
236+
❌ **Error reading test results**: ${error.message}
199237
200238
[View full report →](https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }})`;
201239
}
@@ -206,3 +244,31 @@ jobs:
206244
with:
207245
message: ${{ steps.test-results.outputs.result }}
208246
message-id: e2e-test-results
247+
248+
- name: Check test results
249+
uses: actions/github-script@v7
250+
with:
251+
script: |
252+
const fs = require('fs');
253+
const path = require('path');
254+
255+
let totalFailed = 0;
256+
257+
try {
258+
const resultsDir = 'all-test-results';
259+
const shards = fs.readdirSync(resultsDir);
260+
261+
for (const shard of shards) {
262+
const resultsPath = path.join(resultsDir, shard, 'results.json');
263+
if (fs.existsSync(resultsPath)) {
264+
const results = JSON.parse(fs.readFileSync(resultsPath, 'utf8'));
265+
totalFailed += results.stats.unexpected || 0;
266+
}
267+
}
268+
269+
if (totalFailed > 0) {
270+
core.setFailed(`${totalFailed} test(s) failed`);
271+
}
272+
} catch (error) {
273+
core.setFailed(`Failed to read test results: ${error.message}`);
274+
}

0 commit comments

Comments
 (0)