Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: move update pr script to actual script with tests #1684

Merged
merged 6 commits into from
Nov 25, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
102 changes: 13 additions & 89 deletions .github/workflows/quality.yml
Original file line number Diff line number Diff line change
Expand Up @@ -221,97 +221,21 @@ jobs:
name: playwright-artifacts
path: playwright-artifacts

- name: Fetch gh-pages branch
run: |
git fetch origin gh-pages:gh-pages
mkdir gh-pages
git --work-tree=gh-pages checkout gh-pages -- .

- name: Update PR description
uses: actions/github-script@v6
env:
CURRENT_SIZE: ${{ needs.bundle_size.outputs.current_size }}
MAIN_SIZE: ${{ needs.bundle_size.outputs.main_size }}
SIZE_DIFF: ${{ needs.bundle_size.outputs.diff }}
SIZE_PERCENT: ${{ needs.bundle_size.outputs.percent }}
with:
github-token: ${{secrets.GITHUB_TOKEN}}
script: |
const fs = require('fs');
const testResultsPath = 'playwright-artifacts/test-results.json';
let testResults;

if (fs.existsSync(testResultsPath)) {
const rawData = fs.readFileSync(testResultsPath);
const data = JSON.parse(rawData);
testResults = {
total: data.stats.expected + data.stats.unexpected + data.stats.flaky + data.stats.skipped,
passed: data.stats.expected,
failed: data.stats.unexpected,
flaky: data.stats.flaky,
skipped: data.stats.skipped
};
} else {
console.log('Test results file not found');
testResults = { total: 0, passed: 0, failed: 0, flaky: 0, skipped: 0 };
}

const reportUrl = `https://${context.repo.owner}.github.io/${context.repo.repo}/${context.issue.number}/`;
const status = testResults.failed > 0 ? '❌ FAILED' : (testResults.flaky > 0 ? '⚠️ FLAKY' : 'βœ… PASSED');
const statusColor = testResults.failed > 0 ? 'red' : (testResults.flaky > 0 ? 'orange' : 'green');

const currentSize = parseInt('${{ needs.bundle_size.outputs.current_size }}');
const mainSize = parseInt('${{ needs.bundle_size.outputs.main_size }}');
const diff = parseInt('${{ needs.bundle_size.outputs.diff }}');
const percent = '${{ needs.bundle_size.outputs.percent }}';

const formatSize = (size) => {
if (size >= 1024) {
return `${(size / (1024 * 1024)).toFixed(2)} MB`;
}
return `${(size / 1024).toFixed(2)} KB`;
};

const bundleStatus = percent === 'N/A' ? '⚠️' :
parseFloat(percent) > 0 ? 'πŸ”Ί' :
parseFloat(percent) < 0 ? 'πŸ”½' : 'βœ…';

const ciSection = `## CI Results

### Test Status: <span style="color: ${statusColor};">${status}</span>
πŸ“Š [Full Report](${reportUrl})

| Total | Passed | Failed | Flaky | Skipped |
|:-----:|:------:|:------:|:-----:|:-------:|
| ${testResults.total} | ${testResults.passed} | ${testResults.failed} | ${testResults.flaky} | ${testResults.skipped} |

### Bundle Size: ${bundleStatus}
Current: ${formatSize(currentSize)} | Main: ${formatSize(mainSize)}
Diff: ${diff > 0 ? '+' : ''}${formatSize(Math.abs(diff))} (${percent === 'N/A' ? 'N/A' : `${percent}%`})

${
percent === 'N/A' ? '⚠️ Unable to calculate change.' :
parseFloat(percent) > 0 ? '⚠️ Bundle size increased. Please review.' :
parseFloat(percent) < 0 ? 'βœ… Bundle size decreased.' : 'βœ… Bundle size unchanged.'
}

<details>
<summary>ℹ️ CI Information</summary>

- Test recordings for failed tests are available in the full report.
- Bundle size is measured for the entire 'dist' directory.
- πŸ“Š indicates links to detailed reports.
- πŸ”Ί indicates increase, πŸ”½ decrease, and βœ… no change in bundle size.
</details>`;

const { data: pullRequest } = await github.rest.pulls.get({
owner: context.repo.owner,
repo: context.repo.repo,
pull_number: context.issue.number,
});

const currentBody = pullRequest.body || '';
const ciSectionRegex = /## CI Results[\s\S]*?(?=\n## (?!CI Results)|$)/;

let newBody = currentBody;
if (ciSectionRegex.test(newBody)) {
newBody = newBody.replace(ciSectionRegex, ciSection);
} else {
newBody += '\n\n' + ciSection;
}

await github.rest.pulls.update({
owner: context.repo.owner,
repo: context.repo.repo,
pull_number: context.issue.number,
body: newBody,
});
const updatePRDescription = require('./.github/workflows/scripts/update-pr-description.js');
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

moved script from yml to scripts

await updatePRDescription(github, context);
108 changes: 108 additions & 0 deletions .github/workflows/scripts/__tests__/bundle.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
import {generateBundleSizeSection, getBundleInfo} from '../utils/bundle';

describe('bundle utils', () => {
describe('generateBundleSizeSection', () => {
it('should generate section for increased bundle size', () => {
const bundleInfo = {
currentSize: 1024 * 1024 * 2, // 2MB
mainSize: 1024 * 1024, // 1MB
diff: 1024 * 1024, // 1MB increase
percent: '100',
};

const result = generateBundleSizeSection(bundleInfo);
expect(result).toContain('Bundle Size: πŸ”Ί');
expect(result).toContain('Current: 2.00 MB | Main: 1.00 MB');
expect(result).toContain('Diff: +1.00 MB (100%)');
expect(result).toContain('⚠️ Bundle size increased. Please review.');
});

it('should generate section for decreased bundle size', () => {
const bundleInfo = {
currentSize: 1024 * 1024, // 1MB
mainSize: 1024 * 1024 * 2, // 2MB
diff: -1024 * 1024, // 1MB decrease
percent: '-50',
};

const result = generateBundleSizeSection(bundleInfo);
expect(result).toContain('Bundle Size: πŸ”½');
expect(result).toContain('Current: 1.00 MB | Main: 2.00 MB');
expect(result).toContain('Diff: 1.00 MB (-50%)');
expect(result).toContain('βœ… Bundle size decreased.');
});

it('should generate section for unchanged bundle size', () => {
const bundleInfo = {
currentSize: 1024 * 1024, // 1MB
mainSize: 1024 * 1024, // 1MB
diff: 0,
percent: '0',
};

const result = generateBundleSizeSection(bundleInfo);
expect(result).toContain('Bundle Size: βœ…');
expect(result).toContain('Current: 1.00 MB | Main: 1.00 MB');
expect(result).toContain('Diff: 0.00 KB (0%)');
expect(result).toContain('βœ… Bundle size unchanged.');
});

it('should handle N/A percent', () => {
const bundleInfo = {
currentSize: 1024 * 1024, // 1MB
mainSize: 0,
diff: 1024 * 1024,
percent: 'N/A',
};

const result = generateBundleSizeSection(bundleInfo);
expect(result).toContain('Bundle Size: ⚠️');
expect(result).toContain('Current: 1.00 MB | Main: 0.00 KB');
expect(result).toContain('Diff: +1.00 MB (N/A)');
expect(result).toContain('⚠️ Unable to calculate change.');
});
});

describe('getBundleInfo', () => {
const originalEnv = process.env;

beforeEach(() => {
jest.resetModules();
process.env = {...originalEnv};
});

afterAll(() => {
process.env = originalEnv;
});

it('should get bundle info from environment variables', () => {
process.env.CURRENT_SIZE = '2097152'; // 2MB
process.env.MAIN_SIZE = '1048576'; // 1MB
process.env.SIZE_DIFF = '1048576'; // 1MB
process.env.SIZE_PERCENT = '100';

const result = getBundleInfo();
expect(result).toEqual({
currentSize: 2097152,
mainSize: 1048576,
diff: 1048576,
percent: '100',
});
});

it('should handle missing environment variables', () => {
process.env.CURRENT_SIZE = undefined;
process.env.MAIN_SIZE = undefined;
process.env.SIZE_DIFF = undefined;
process.env.SIZE_PERCENT = undefined;

const result = getBundleInfo();
expect(result).toEqual({
currentSize: 0,
mainSize: 0,
diff: 0,
percent: 'N/A',
});
});
});
});
98 changes: 98 additions & 0 deletions .github/workflows/scripts/__tests__/format.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
import {formatSize, generateTestChangesSummary} from '../utils/format';

describe('format utils', () => {
describe('formatSize', () => {
it('should format size in KB when less than 1024 bytes', () => {
const size = 512; // 512 bytes
expect(formatSize(size)).toBe('0.50 KB');
});

it('should format size in MB when greater than or equal to 1024 bytes', () => {
const size = 2.5 * 1024; // 2.5 KB -> will be shown in MB
expect(formatSize(size)).toBe('2.50 KB');
});

it('should handle small sizes', () => {
const size = 100; // 100 bytes
expect(formatSize(size)).toBe('0.10 KB');
});

it('should handle zero', () => {
expect(formatSize(0)).toBe('0.00 KB');
});
});

describe('generateTestChangesSummary', () => {
it('should generate summary for new tests only', () => {
const comparison = {
new: ['Test 1 (file1.ts)', 'Test 2 (file2.ts)'],
skipped: [],
deleted: [],
};

const summary = generateTestChangesSummary(comparison);
expect(summary).toContain('✨ New Tests (2)');
expect(summary).toContain('1. Test 1 (file1.ts)');
expect(summary).toContain('2. Test 2 (file2.ts)');
expect(summary).not.toContain('⏭️ Skipped Tests');
expect(summary).not.toContain('πŸ—‘οΈ Deleted Tests');
});

it('should generate summary for skipped tests only', () => {
const comparison = {
new: [],
skipped: ['Test 1 (file1.ts)', 'Test 2 (file2.ts)'],
deleted: [],
};

const summary = generateTestChangesSummary(comparison);
expect(summary).toContain('⏭️ Skipped Tests (2)');
expect(summary).toContain('1. Test 1 (file1.ts)');
expect(summary).toContain('2. Test 2 (file2.ts)');
expect(summary).not.toContain('✨ New Tests');
expect(summary).not.toContain('πŸ—‘οΈ Deleted Tests');
});

it('should generate summary for deleted tests only', () => {
const comparison = {
new: [],
skipped: [],
deleted: ['Test 1 (file1.ts)', 'Test 2 (file2.ts)'],
};

const summary = generateTestChangesSummary(comparison);
expect(summary).toContain('πŸ—‘οΈ Deleted Tests (2)');
expect(summary).toContain('1. Test 1 (file1.ts)');
expect(summary).toContain('2. Test 2 (file2.ts)');
expect(summary).not.toContain('✨ New Tests');
expect(summary).not.toContain('⏭️ Skipped Tests');
});

it('should generate summary for all types of changes', () => {
const comparison = {
new: ['New Test (file1.ts)'],
skipped: ['Skipped Test (file2.ts)'],
deleted: ['Deleted Test (file3.ts)'],
};

const summary = generateTestChangesSummary(comparison);
expect(summary).toContain('✨ New Tests (1)');
expect(summary).toContain('⏭️ Skipped Tests (1)');
expect(summary).toContain('πŸ—‘οΈ Deleted Tests (1)');
expect(summary).toContain('New Test (file1.ts)');
expect(summary).toContain('Skipped Test (file2.ts)');
expect(summary).toContain('Deleted Test (file3.ts)');
});

it('should handle no changes', () => {
const comparison = {
new: [],
skipped: [],
deleted: [],
};

const summary = generateTestChangesSummary(comparison);
expect(summary).toBe('😟 No changes in tests. πŸ˜•');
});
});
});
Loading
Loading