Skip to content

Commit 9c98d5b

Browse files
fix: move to script
1 parent b23e205 commit 9c98d5b

File tree

2 files changed

+200
-187
lines changed

2 files changed

+200
-187
lines changed

.github/workflows/quality.yml

Lines changed: 7 additions & 187 deletions
Original file line numberDiff line numberDiff line change
@@ -229,193 +229,13 @@ jobs:
229229
230230
- name: Update PR description
231231
uses: actions/github-script@v6
232+
env:
233+
CURRENT_SIZE: ${{ needs.bundle_size.outputs.current_size }}
234+
MAIN_SIZE: ${{ needs.bundle_size.outputs.main_size }}
235+
SIZE_DIFF: ${{ needs.bundle_size.outputs.diff }}
236+
SIZE_PERCENT: ${{ needs.bundle_size.outputs.percent }}
232237
with:
233238
github-token: ${{secrets.GITHUB_TOKEN}}
234239
script: |
235-
const fs = require('fs');
236-
const testResultsPath = 'playwright-artifacts/test-results.json';
237-
const mainTestResultsPath = 'gh-pages/main/test-results.json';
238-
let testResults;
239-
let mainTestResults;
240-
let testComparison = {
241-
new: [],
242-
skipped: [],
243-
deleted: []
244-
};
245-
246-
// Helper function to extract all tests from a suite recursively
247-
function extractTestsFromSuite(suite, parentTitle = '') {
248-
let tests = [];
249-
const fullSuiteTitle = parentTitle ? `${parentTitle} > ${suite.title}` : suite.title;
250-
251-
if (suite.specs) {
252-
tests.push(...suite.specs.map(spec => {
253-
const isSkipped = spec.tests && spec.tests[0] &&
254-
(spec.tests[0].annotations?.some(a => a.type === 'skip') ||
255-
spec.tests[0].status === 'skipped');
256-
257-
return {
258-
title: spec.title,
259-
fullTitle: `${fullSuiteTitle} > ${spec.title}`,
260-
status: isSkipped ? 'skipped' : (spec.ok ? 'passed' : 'failed'),
261-
file: suite.file,
262-
skipped: isSkipped
263-
};
264-
}));
265-
}
266-
267-
// Recursively process nested suites
268-
if (suite.suites) {
269-
suite.suites.forEach(nestedSuite => {
270-
tests.push(...extractTestsFromSuite(nestedSuite, fullSuiteTitle));
271-
});
272-
}
273-
274-
return tests;
275-
}
276-
277-
// Read current PR test results
278-
if (fs.existsSync(testResultsPath)) {
279-
const rawData = fs.readFileSync(testResultsPath);
280-
const data = JSON.parse(rawData);
281-
const allTests = data.suites.flatMap(suite => extractTestsFromSuite(suite));
282-
283-
testResults = {
284-
total: data.stats.expected + data.stats.unexpected + data.stats.flaky + data.stats.skipped,
285-
passed: data.stats.expected,
286-
failed: data.stats.unexpected,
287-
flaky: data.stats.flaky,
288-
skipped: data.stats.skipped,
289-
tests: allTests
290-
};
291-
} else {
292-
console.log('Test results file not found');
293-
testResults = { total: 0, passed: 0, failed: 0, flaky: 0, skipped: 0, tests: [] };
294-
}
295-
296-
// Read main branch test results
297-
if (fs.existsSync(mainTestResultsPath)) {
298-
const rawData = fs.readFileSync(mainTestResultsPath);
299-
const data = JSON.parse(rawData);
300-
const allTests = data.suites.flatMap(suite => extractTestsFromSuite(suite));
301-
mainTestResults = { tests: allTests };
302-
303-
// Compare tests
304-
const currentTests = new Map(testResults.tests.map(t => [t.fullTitle, t]));
305-
const mainTests = new Map(mainTestResults.tests.map(t => [t.fullTitle, t]));
306-
307-
// Find new tests
308-
for (const [fullTitle, test] of currentTests) {
309-
if (!mainTests.has(fullTitle)) {
310-
testComparison.new.push(`${test.title} (${test.file})`);
311-
}
312-
}
313-
314-
// Find deleted tests
315-
for (const [fullTitle, test] of mainTests) {
316-
if (!currentTests.has(fullTitle)) {
317-
testComparison.deleted.push(`${test.title} (${test.file})`);
318-
}
319-
}
320-
321-
// Find skipped tests (both newly skipped and already skipped)
322-
testComparison.skipped = testResults.tests
323-
.filter(t => t.skipped)
324-
.map(test => `${test.title} (${test.file})`);
325-
326-
testComparison.skipped = Array.from(new Set(testComparison.skipped));
327-
} else {
328-
console.log('Main branch test results file not found');
329-
mainTestResults = { tests: [] };
330-
}
331-
332-
const reportUrl = `https://${context.repo.owner}.github.io/${context.repo.repo}/${context.issue.number}/`;
333-
const status = testResults.failed > 0 ? '❌ FAILED' : (testResults.flaky > 0 ? '⚠️ FLAKY' : '✅ PASSED');
334-
const statusColor = testResults.failed > 0 ? 'red' : (testResults.flaky > 0 ? 'orange' : 'green');
335-
336-
const currentSize = parseInt('${{ needs.bundle_size.outputs.current_size }}');
337-
const mainSize = parseInt('${{ needs.bundle_size.outputs.main_size }}');
338-
const diff = parseInt('${{ needs.bundle_size.outputs.diff }}');
339-
const percent = '${{ needs.bundle_size.outputs.percent }}';
340-
341-
const formatSize = (size) => {
342-
if (size >= 1024) {
343-
return `${(size / (1024 * 1024)).toFixed(2)} MB`;
344-
}
345-
return `${(size / 1024).toFixed(2)} KB`;
346-
};
347-
348-
const bundleStatus = percent === 'N/A' ? '⚠️' :
349-
parseFloat(percent) > 0 ? '🔺' :
350-
parseFloat(percent) < 0 ? '🔽' : '✅';
351-
352-
// Generate test changes summary based on actual changes
353-
let testChangesSummary = '😟 No changes in tests. 😕';
354-
if (testComparison.new.length > 0 || testComparison.deleted.length > 0 || testComparison.skipped.length > 0) {
355-
testChangesSummary = `
356-
<details>
357-
<summary>Test Changes Summary ${testComparison.new.length > 0 ? `✨${testComparison.new.length} ` : ''}${testComparison.skipped.length > 0 ? `⏭️${testComparison.skipped.length} ` : ''}${testComparison.deleted.length > 0 ? `🗑️${testComparison.deleted.length}` : ''}</summary>
358-
359-
${testComparison.new.length > 0 ? `#### ✨ New Tests (${testComparison.new.length})
360-
${testComparison.new.map((test, i) => `${i + 1}. ${test}`).join('\n')}
361-
362-
` : ''}${testComparison.skipped.length > 0 ? `#### ⏭️ Skipped Tests (${testComparison.skipped.length})
363-
${testComparison.skipped.map((test, i) => `${i + 1}. ${test}`).join('\n')}
364-
365-
` : ''}${testComparison.deleted.length > 0 ? `#### 🗑️ Deleted Tests (${testComparison.deleted.length})
366-
${testComparison.deleted.map((test, i) => `${i + 1}. ${test}`).join('\n')}` : ''}
367-
</details>`;
368-
}
369-
370-
const ciSection = `## CI Results
371-
372-
### Test Status: <span style="color: ${statusColor};">${status}</span>
373-
📊 [Full Report](${reportUrl})
374-
375-
| Total | Passed | Failed | Flaky | Skipped |
376-
|:-----:|:------:|:------:|:-----:|:-------:|
377-
| ${testResults.total} | ${testResults.passed} | ${testResults.failed} | ${testResults.flaky} | ${testResults.skipped} |
378-
379-
${testChangesSummary}
380-
381-
### Bundle Size: ${bundleStatus}
382-
Current: ${formatSize(currentSize)} | Main: ${formatSize(mainSize)}
383-
Diff: ${diff > 0 ? '+' : ''}${formatSize(Math.abs(diff))} (${percent === 'N/A' ? 'N/A' : `${percent}%`})
384-
385-
${
386-
percent === 'N/A' ? '⚠️ Unable to calculate change.' :
387-
parseFloat(percent) > 0 ? '⚠️ Bundle size increased. Please review.' :
388-
parseFloat(percent) < 0 ? '✅ Bundle size decreased.' : '✅ Bundle size unchanged.'
389-
}
390-
391-
<details>
392-
<summary>ℹ️ CI Information</summary>
393-
394-
- Test recordings for failed tests are available in the full report.
395-
- Bundle size is measured for the entire 'dist' directory.
396-
- 📊 indicates links to detailed reports.
397-
- 🔺 indicates increase, 🔽 decrease, and ✅ no change in bundle size.
398-
</details>`;
399-
400-
const { data: pullRequest } = await github.rest.pulls.get({
401-
owner: context.repo.owner,
402-
repo: context.repo.repo,
403-
pull_number: context.issue.number,
404-
});
405-
406-
const currentBody = pullRequest.body || '';
407-
const ciSectionRegex = /## CI Results[\s\S]*?(?=\n## (?!CI Results)|$)/;
408-
409-
let newBody = currentBody;
410-
if (ciSectionRegex.test(newBody)) {
411-
newBody = newBody.replace(ciSectionRegex, ciSection);
412-
} else {
413-
newBody += '\n\n' + ciSection;
414-
}
415-
416-
await github.rest.pulls.update({
417-
owner: context.repo.owner,
418-
repo: context.repo.repo,
419-
pull_number: context.issue.number,
420-
body: newBody,
421-
});
240+
const updatePRDescription = require('./.github/workflows/scripts/update-pr-description.js');
241+
await updatePRDescription(github, context);
Lines changed: 193 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,193 @@
1+
const fs = require('fs');
2+
3+
// Helper function to extract all tests from a suite recursively
4+
function extractTestsFromSuite(suite, parentTitle = '') {
5+
let tests = [];
6+
const fullSuiteTitle = parentTitle ? `${parentTitle} > ${suite.title}` : suite.title;
7+
8+
if (suite.specs) {
9+
tests.push(...suite.specs.map(spec => {
10+
const isSkipped = spec.tests && spec.tests[0] &&
11+
(spec.tests[0].annotations?.some(a => a.type === 'skip') ||
12+
spec.tests[0].status === 'skipped');
13+
14+
return {
15+
title: spec.title,
16+
fullTitle: `${fullSuiteTitle} > ${spec.title}`,
17+
status: isSkipped ? 'skipped' : (spec.ok ? 'passed' : 'failed'),
18+
file: suite.file,
19+
skipped: isSkipped
20+
};
21+
}));
22+
}
23+
24+
// Recursively process nested suites
25+
if (suite.suites) {
26+
suite.suites.forEach(nestedSuite => {
27+
tests.push(...extractTestsFromSuite(nestedSuite, fullSuiteTitle));
28+
});
29+
}
30+
31+
return tests;
32+
}
33+
34+
function formatSize(size) {
35+
if (size >= 1024) {
36+
return `${(size / (1024 * 1024)).toFixed(2)} MB`;
37+
}
38+
return `${(size / 1024).toFixed(2)} KB`;
39+
}
40+
41+
async function updatePRDescription(github, context) {
42+
const testResultsPath = 'playwright-artifacts/test-results.json';
43+
const mainTestResultsPath = 'gh-pages/main/test-results.json';
44+
let testResults;
45+
let mainTestResults;
46+
let testComparison = {
47+
new: [],
48+
skipped: [],
49+
deleted: []
50+
};
51+
52+
// Read current PR test results
53+
if (fs.existsSync(testResultsPath)) {
54+
const rawData = fs.readFileSync(testResultsPath);
55+
const data = JSON.parse(rawData);
56+
const allTests = data.suites.flatMap(suite => extractTestsFromSuite(suite));
57+
58+
testResults = {
59+
total: data.stats.expected + data.stats.unexpected + data.stats.flaky + data.stats.skipped,
60+
passed: data.stats.expected,
61+
failed: data.stats.unexpected,
62+
flaky: data.stats.flaky,
63+
skipped: data.stats.skipped,
64+
tests: allTests
65+
};
66+
} else {
67+
console.log('Test results file not found');
68+
testResults = { total: 0, passed: 0, failed: 0, flaky: 0, skipped: 0, tests: [] };
69+
}
70+
71+
// Read main branch test results
72+
if (fs.existsSync(mainTestResultsPath)) {
73+
const rawData = fs.readFileSync(mainTestResultsPath);
74+
const data = JSON.parse(rawData);
75+
const allTests = data.suites.flatMap(suite => extractTestsFromSuite(suite));
76+
mainTestResults = { tests: allTests };
77+
78+
// Compare tests
79+
const currentTests = new Map(testResults.tests.map(t => [t.fullTitle, t]));
80+
const mainTests = new Map(mainTestResults.tests.map(t => [t.fullTitle, t]));
81+
82+
// Find new tests
83+
for (const [fullTitle, test] of currentTests) {
84+
if (!mainTests.has(fullTitle)) {
85+
testComparison.new.push(`${test.title} (${test.file})`);
86+
}
87+
}
88+
89+
// Find deleted tests
90+
for (const [fullTitle, test] of mainTests) {
91+
if (!currentTests.has(fullTitle)) {
92+
testComparison.deleted.push(`${test.title} (${test.file})`);
93+
}
94+
}
95+
96+
// Find skipped tests (both newly skipped and already skipped)
97+
testComparison.skipped = testResults.tests
98+
.filter(t => t.skipped)
99+
.map(test => `${test.title} (${test.file})`);
100+
101+
testComparison.skipped = Array.from(new Set(testComparison.skipped));
102+
} else {
103+
console.log('Main branch test results file not found');
104+
mainTestResults = { tests: [] };
105+
}
106+
107+
const reportUrl = `https://${context.repo.owner}.github.io/${context.repo.repo}/${context.issue.number}/`;
108+
const status = testResults.failed > 0 ? '❌ FAILED' : (testResults.flaky > 0 ? '⚠️ FLAKY' : '✅ PASSED');
109+
const statusColor = testResults.failed > 0 ? 'red' : (testResults.flaky > 0 ? 'orange' : 'green');
110+
111+
// Get bundle size information from environment variables
112+
const currentSize = parseInt(process.env.CURRENT_SIZE || '0');
113+
const mainSize = parseInt(process.env.MAIN_SIZE || '0');
114+
const diff = parseInt(process.env.SIZE_DIFF || '0');
115+
const percent = process.env.SIZE_PERCENT || 'N/A';
116+
117+
const bundleStatus = percent === 'N/A' ? '⚠️' :
118+
parseFloat(percent) > 0 ? '🔺' :
119+
parseFloat(percent) < 0 ? '🔽' : '✅';
120+
121+
// Generate test changes summary based on actual changes
122+
let testChangesSummary = '😟 No changes in tests. 😕';
123+
if (testComparison.new.length > 0 || testComparison.deleted.length > 0 || testComparison.skipped.length > 0) {
124+
testChangesSummary = `
125+
<details>
126+
<summary>Test Changes Summary ${testComparison.new.length > 0 ? `✨${testComparison.new.length} ` : ''}${testComparison.skipped.length > 0 ? `⏭️${testComparison.skipped.length} ` : ''}${testComparison.deleted.length > 0 ? `🗑️${testComparison.deleted.length}` : ''}</summary>
127+
128+
${testComparison.new.length > 0 ? `#### ✨ New Tests (${testComparison.new.length})
129+
${testComparison.new.map((test, i) => `${i + 1}. ${test}`).join('\n')}
130+
131+
` : ''}${testComparison.skipped.length > 0 ? `#### ⏭️ Skipped Tests (${testComparison.skipped.length})
132+
${testComparison.skipped.map((test, i) => `${i + 1}. ${test}`).join('\n')}
133+
134+
` : ''}${testComparison.deleted.length > 0 ? `#### 🗑️ Deleted Tests (${testComparison.deleted.length})
135+
${testComparison.deleted.map((test, i) => `${i + 1}. ${test}`).join('\n')}` : ''}
136+
</details>`;
137+
}
138+
139+
const ciSection = `## CI Results
140+
141+
### Test Status: <span style="color: ${statusColor};">${status}</span>
142+
📊 [Full Report](${reportUrl})
143+
144+
| Total | Passed | Failed | Flaky | Skipped |
145+
|:-----:|:------:|:------:|:-----:|:-------:|
146+
| ${testResults.total} | ${testResults.passed} | ${testResults.failed} | ${testResults.flaky} | ${testResults.skipped} |
147+
148+
${testChangesSummary}
149+
150+
### Bundle Size: ${bundleStatus}
151+
Current: ${formatSize(currentSize)} | Main: ${formatSize(mainSize)}
152+
Diff: ${diff > 0 ? '+' : ''}${formatSize(Math.abs(diff))} (${percent === 'N/A' ? 'N/A' : `${percent}%`})
153+
154+
${
155+
percent === 'N/A' ? '⚠️ Unable to calculate change.' :
156+
parseFloat(percent) > 0 ? '⚠️ Bundle size increased. Please review.' :
157+
parseFloat(percent) < 0 ? '✅ Bundle size decreased.' : '✅ Bundle size unchanged.'
158+
}
159+
160+
<details>
161+
<summary>ℹ️ CI Information</summary>
162+
163+
- Test recordings for failed tests are available in the full report.
164+
- Bundle size is measured for the entire 'dist' directory.
165+
- 📊 indicates links to detailed reports.
166+
- 🔺 indicates increase, 🔽 decrease, and ✅ no change in bundle size.
167+
</details>`;
168+
169+
const { data: pullRequest } = await github.rest.pulls.get({
170+
owner: context.repo.owner,
171+
repo: context.repo.repo,
172+
pull_number: context.issue.number,
173+
});
174+
175+
const currentBody = pullRequest.body || '';
176+
const ciSectionRegex = /## CI Results[\s\S]*?(?=\n## (?!CI Results)|$)/;
177+
178+
let newBody = currentBody;
179+
if (ciSectionRegex.test(newBody)) {
180+
newBody = newBody.replace(ciSectionRegex, ciSection);
181+
} else {
182+
newBody += '\n\n' + ciSection;
183+
}
184+
185+
await github.rest.pulls.update({
186+
owner: context.repo.owner,
187+
repo: context.repo.repo,
188+
pull_number: context.issue.number,
189+
body: newBody,
190+
});
191+
}
192+
193+
module.exports = updatePRDescription;

0 commit comments

Comments
 (0)