chore: Use git to read old timings

This commit is contained in:
Sidharth Vinod
2025-04-09 12:19:13 +05:30
parent 7a5f999f42
commit 97e35fd30a
2 changed files with 37 additions and 15 deletions

View File

@@ -31,9 +31,6 @@ jobs:
with: with:
runTests: false runTests: false
- name: Copy previous timings
run: cp cypress/timings.json cypress/timings-old.json
- name: Cypress run - name: Cypress run
uses: cypress-io/github-action@18a6541367f4580a515371905f499a27a44e8dbe # v6.7.12 uses: cypress-io/github-action@18a6541367f4580a515371905f499a27a44e8dbe # v6.7.12
id: cypress id: cypress

View File

@@ -1,5 +1,22 @@
/**
* Compares new E2E test timings with previous timings and determines whether to keep the new timings.
*
* The script will:
* 1. Read old timings from git HEAD
* 2. Read new timings from the current file
* 3. Compare the timings and specs
* 4. Keep new timings if:
* - Specs were added/removed
* - Any timing changed by 20% or more
* 5. Revert to old timings if:
* - No significant timing changes
*
* This helps prevent unnecessary timing updates when test performance hasn't changed significantly.
*/
import fs from 'node:fs'; import fs from 'node:fs';
import path from 'node:path'; import path from 'node:path';
import { execSync } from 'node:child_process';
interface Timing { interface Timing {
spec: string; spec: string;
@@ -10,37 +27,45 @@ interface TimingsFile {
durations: Timing[]; durations: Timing[];
} }
const TIMINGS_PATH = path.join(process.cwd(), 'cypress', 'timings.json'); interface CleanupOptions {
const TIMINGS_OLD_PATH = path.join(process.cwd(), 'cypress', 'timings-old.json'); keepNew: boolean;
reason: string;
}
const TIMINGS_FILE = 'cypress/timings.json';
const TIMINGS_PATH = path.join(process.cwd(), TIMINGS_FILE);
function log(message: string): void { function log(message: string): void {
// eslint-disable-next-line no-console // eslint-disable-next-line no-console
console.log(message); console.log(message);
} }
function readTimings(filePath: string): TimingsFile { function readOldTimings(): TimingsFile {
return JSON.parse(fs.readFileSync(filePath, 'utf8')); try {
const oldContent = execSync(`git show HEAD:${TIMINGS_FILE}`, { encoding: 'utf8' });
return JSON.parse(oldContent);
} catch {
log('Error getting old timings, using empty file');
return { durations: [] };
}
} }
interface CleanupOptions { function readNewTimings(): TimingsFile {
keepNew: boolean; return JSON.parse(fs.readFileSync(TIMINGS_PATH, 'utf8'));
reason: string;
} }
function cleanupFiles({ keepNew, reason }: CleanupOptions): void { function cleanupFiles({ keepNew, reason }: CleanupOptions): void {
if (keepNew) { if (keepNew) {
log(`Keeping new timings: ${reason}`); log(`Keeping new timings: ${reason}`);
fs.unlinkSync(TIMINGS_OLD_PATH);
} else { } else {
log(`Reverting to old timings: ${reason}`); log(`Reverting to old timings: ${reason}`);
fs.unlinkSync(TIMINGS_PATH); execSync(`git checkout HEAD -- ${TIMINGS_FILE}`);
fs.renameSync(TIMINGS_OLD_PATH, TIMINGS_PATH);
} }
} }
function compareTimings(): void { function compareTimings(): void {
const oldTimings = readTimings(TIMINGS_OLD_PATH); const oldTimings = readOldTimings();
const newTimings = readTimings(TIMINGS_PATH); const newTimings = readNewTimings();
const oldSpecs = new Set(oldTimings.durations.map((d) => d.spec)); const oldSpecs = new Set(oldTimings.durations.map((d) => d.spec));
const newSpecs = new Set(newTimings.durations.map((d) => d.spec)); const newSpecs = new Set(newTimings.durations.map((d) => d.spec));