Skip to content

Commit b11d755

Browse files
fix: split files
1 parent 9c98d5b commit b11d755

File tree

5 files changed

+255
-150
lines changed

5 files changed

+255
-150
lines changed

.github/workflows/scripts/update-pr-description.js

Lines changed: 28 additions & 150 deletions
Original file line numberDiff line numberDiff line change
@@ -1,161 +1,41 @@
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-
}
1+
const { compareTests } = require('./utils/test');
2+
const { generateTestChangesSummary } = require('./utils/format');
3+
const { generateBundleSizeSection, getBundleInfo } = require('./utils/bundle');
4+
const { readTestResults, getTestStatus } = require('./utils/results');
5+
6+
/**
7+
* Main function to update PR description with test results and bundle size information
8+
* @param {Object} github - GitHub API object
9+
* @param {Object} context - GitHub Actions context
10+
*/
11+
async function updatePRDescription(github, context) {
12+
// Read test results
13+
const currentResults = readTestResults('playwright-artifacts/test-results.json');
14+
const mainResults = readTestResults('gh-pages/main/test-results.json');
2315

24-
// Recursively process nested suites
25-
if (suite.suites) {
26-
suite.suites.forEach(nestedSuite => {
27-
tests.push(...extractTestsFromSuite(nestedSuite, fullSuiteTitle));
28-
});
29-
}
16+
// Compare tests
17+
const testComparison = compareTests(currentResults.tests, mainResults.tests);
3018

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-
19+
// Get test status and report URL
20+
const { status, statusColor } = getTestStatus(currentResults);
10721
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';
11622

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-
}
23+
// Get bundle size information
24+
const bundleInfo = getBundleInfo();
13825

26+
// Generate the CI section content
13927
const ciSection = `## CI Results
14028
14129
### Test Status: <span style="color: ${statusColor};">${status}</span>
14230
📊 [Full Report](${reportUrl})
14331
14432
| Total | Passed | Failed | Flaky | Skipped |
14533
|:-----:|:------:|:------:|:-----:|:-------:|
146-
| ${testResults.total} | ${testResults.passed} | ${testResults.failed} | ${testResults.flaky} | ${testResults.skipped} |
147-
148-
${testChangesSummary}
34+
| ${currentResults.total} | ${currentResults.passed} | ${currentResults.failed} | ${currentResults.flaky} | ${currentResults.skipped} |
14935
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}%`})
36+
${generateTestChangesSummary(testComparison)}
15337
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-
}
38+
${generateBundleSizeSection(bundleInfo)}
15939
16040
<details>
16141
<summary>ℹ️ CI Information</summary>
@@ -166,6 +46,7 @@ async function updatePRDescription(github, context) {
16646
- 🔺 indicates increase, 🔽 decrease, and ✅ no change in bundle size.
16747
</details>`;
16848

49+
// Update PR description
16950
const { data: pullRequest } = await github.rest.pulls.get({
17051
owner: context.repo.owner,
17152
repo: context.repo.repo,
@@ -175,12 +56,9 @@ async function updatePRDescription(github, context) {
17556
const currentBody = pullRequest.body || '';
17657
const ciSectionRegex = /## CI Results[\s\S]*?(?=\n## (?!CI Results)|$)/;
17758

178-
let newBody = currentBody;
179-
if (ciSectionRegex.test(newBody)) {
180-
newBody = newBody.replace(ciSectionRegex, ciSection);
181-
} else {
182-
newBody += '\n\n' + ciSection;
183-
}
59+
const newBody = ciSectionRegex.test(currentBody)
60+
? currentBody.replace(ciSectionRegex, ciSection)
61+
: currentBody + '\n\n' + ciSection;
18462

18563
await github.rest.pulls.update({
18664
owner: context.repo.owner,
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
const { formatSize } = require('./format');
2+
3+
/**
4+
* Generates the bundle size status section
5+
* @param {Object} bundleInfo - Bundle size information
6+
* @returns {string} Formatted bundle size section
7+
*/
8+
function generateBundleSizeSection({ currentSize, mainSize, diff, percent }) {
9+
const bundleStatus = percent === 'N/A' ? '⚠️' :
10+
parseFloat(percent) > 0 ? '🔺' :
11+
parseFloat(percent) < 0 ? '🔽' : '✅';
12+
13+
const sizeChangeMessage = percent === 'N/A' ? '⚠️ Unable to calculate change.' :
14+
parseFloat(percent) > 0 ? '⚠️ Bundle size increased. Please review.' :
15+
parseFloat(percent) < 0 ? '✅ Bundle size decreased.' : '✅ Bundle size unchanged.';
16+
17+
return `### Bundle Size: ${bundleStatus}
18+
Current: ${formatSize(currentSize)} | Main: ${formatSize(mainSize)}
19+
Diff: ${diff > 0 ? '+' : ''}${formatSize(Math.abs(diff))} (${percent === 'N/A' ? 'N/A' : `${percent}%`})
20+
21+
${sizeChangeMessage}`;
22+
}
23+
24+
/**
25+
* Gets bundle size information from environment variables
26+
* @returns {Object} Bundle size information
27+
*/
28+
function getBundleInfo() {
29+
return {
30+
currentSize: parseInt(process.env.CURRENT_SIZE || '0'),
31+
mainSize: parseInt(process.env.MAIN_SIZE || '0'),
32+
diff: parseInt(process.env.SIZE_DIFF || '0'),
33+
percent: process.env.SIZE_PERCENT || 'N/A'
34+
};
35+
}
36+
37+
module.exports = {
38+
generateBundleSizeSection,
39+
getBundleInfo
40+
};
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
/**
2+
* Formats a size in bytes to a human-readable string (KB or MB)
3+
* @param {number} sizeInBytes - Size in bytes to format
4+
* @returns {string} Formatted size string with units
5+
*/
6+
function formatSize(sizeInBytes) {
7+
const MB_THRESHOLD = 1024;
8+
if (sizeInBytes >= MB_THRESHOLD) {
9+
return `${(sizeInBytes / (1024 * 1024)).toFixed(2)} MB`;
10+
}
11+
return `${(sizeInBytes / 1024).toFixed(2)} KB`;
12+
}
13+
14+
/**
15+
* Generates a summary of test changes
16+
* @param {Object} comparison - Test comparison results
17+
* @returns {string} Formatted test changes summary
18+
*/
19+
function generateTestChangesSummary(comparison) {
20+
if (!comparison.new.length && !comparison.deleted.length && !comparison.skipped.length) {
21+
return '😟 No changes in tests. 😕';
22+
}
23+
24+
const summaryParts = [];
25+
const { new: newTests, skipped, deleted } = comparison;
26+
27+
if (newTests.length) {
28+
summaryParts.push(`#### ✨ New Tests (${newTests.length})
29+
${newTests.map((test, i) => `${i + 1}. ${test}`).join('\n')}\n`);
30+
}
31+
32+
if (skipped.length) {
33+
summaryParts.push(`#### ⏭️ Skipped Tests (${skipped.length})
34+
${skipped.map((test, i) => `${i + 1}. ${test}`).join('\n')}\n`);
35+
}
36+
37+
if (deleted.length) {
38+
summaryParts.push(`#### 🗑️ Deleted Tests (${deleted.length})
39+
${deleted.map((test, i) => `${i + 1}. ${test}`).join('\n')}`);
40+
}
41+
42+
return `
43+
<details>
44+
<summary>Test Changes Summary ${newTests.length ? `✨${newTests.length} ` : ''}${skipped.length ? `⏭️${skipped.length} ` : ''}${deleted.length ? `🗑️${deleted.length}` : ''}</summary>
45+
46+
${summaryParts.join('\n')}
47+
</details>`;
48+
}
49+
50+
module.exports = {
51+
formatSize,
52+
generateTestChangesSummary
53+
};
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
const fs = require('fs');
2+
const { extractTestsFromSuite } = require('./test');
3+
4+
/**
5+
* Reads and processes test results from a JSON file
6+
* @param {string} filePath - Path to the test results JSON file
7+
* @returns {Object} Processed test results
8+
*/
9+
function readTestResults(filePath) {
10+
if (!fs.existsSync(filePath)) {
11+
console.log(`Test results file not found: ${filePath}`);
12+
return { total: 0, passed: 0, failed: 0, flaky: 0, skipped: 0, tests: [] };
13+
}
14+
15+
const data = JSON.parse(fs.readFileSync(filePath));
16+
const allTests = data.suites.flatMap(suite => extractTestsFromSuite(suite));
17+
18+
return {
19+
total: data.stats.expected + data.stats.unexpected + data.stats.flaky + data.stats.skipped,
20+
passed: data.stats.expected,
21+
failed: data.stats.unexpected,
22+
flaky: data.stats.flaky,
23+
skipped: data.stats.skipped,
24+
tests: allTests
25+
};
26+
}
27+
28+
/**
29+
* Gets the test status information
30+
* @param {Object} results - Test results object
31+
* @returns {Object} Status information including color and label
32+
*/
33+
function getTestStatus(results) {
34+
const status = results.failed > 0 ? '❌ FAILED' :
35+
results.flaky > 0 ? '⚠️ FLAKY' :
36+
'✅ PASSED';
37+
38+
const statusColor = results.failed > 0 ? 'red' :
39+
results.flaky > 0 ? 'orange' :
40+
'green';
41+
42+
return { status, statusColor };
43+
}
44+
45+
module.exports = {
46+
readTestResults,
47+
getTestStatus
48+
};

0 commit comments

Comments
 (0)