bun run ci defers the browser suites and the desktop boot check to Forgejo CI when the 1-minute load is above 2x the cores (deferBrowser in tools/ci-plan.ts, said at the start and in the summary); CI=full forces them, Forgejo runs CI=full
This commit is contained in:
parent
918146d4a6
commit
49a73c90e4
3 changed files with 28 additions and 6 deletions
|
|
@ -1,5 +1,14 @@
|
|||
import { describe, expect, test } from 'bun:test';
|
||||
import { balance, depsOf, GLOBAL, HEAVY, junitTimes, listTests, mergeTimings, relatedTests, rustNeeded, shardCount } from '../tools/ci-plan';
|
||||
import { balance, deferBrowser, depsOf, GLOBAL, HEAVY, junitTimes, listTests, mergeTimings, relatedTests, rustNeeded, shardCount } from '../tools/ci-plan';
|
||||
|
||||
describe('tools/ci-plan: browser suites deferred on a busy machine', () => {
|
||||
test('deferred only when the 1-minute load is above 2x the cores, never with CI=full', () => {
|
||||
expect(deferBrowser({}, 21, 10)).toBe(true);
|
||||
expect(deferBrowser({}, 20, 10)).toBe(false);
|
||||
expect(deferBrowser({ CI: 'full' }, 500, 10)).toBe(false);
|
||||
expect(deferBrowser({ CI: 'true' }, 500, 10)).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
describe('tools/ci-plan: test shards', () => {
|
||||
test('shard count: cores - 1, between 1 and 8, env override', () => {
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
// touches (ci:quick) and whether the desktop Rust host needs to run. Pure functions plus small file / git reads;
|
||||
// tests/ci-plan.test.ts covers them.
|
||||
import { mkdirSync, readdirSync, readFileSync, statSync, writeFileSync } from 'node:fs';
|
||||
import { cpus } from 'node:os';
|
||||
import { cpus, loadavg } from 'node:os';
|
||||
import { dirname, join, normalize, relative } from 'node:path';
|
||||
|
||||
export const ROOT = join(import.meta.dir, '..');
|
||||
|
|
@ -28,6 +28,15 @@ export function browserShardCount(env = process.env): number {
|
|||
return Number.isInteger(n) && n > 0 ? n : 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* The local pre-push gate on a busy shared machine: with the 1-minute load average above 2x the cores, the browser
|
||||
* suites (HEAVY) and the desktop boot check (real Chrome) are deferred to the Forgejo CI on the VDS, which always runs
|
||||
* them (CI=full; a red Forgejo CI on main stops releases). CI=full forces them locally.
|
||||
*/
|
||||
export function deferBrowser(env = process.env, load1 = loadavg()[0] ?? 0, cores = cpus().length): boolean {
|
||||
return env.CI !== 'full' && load1 > 2 * cores;
|
||||
}
|
||||
|
||||
/** Changes that can affect every test: run the whole suite. */
|
||||
export const GLOBAL = /^(package\.json|bun\.lock|bunfig\.toml|tsconfig\.json|tests\/helpers\/preload\.ts)$/;
|
||||
|
||||
|
|
|
|||
12
tools/ci.ts
12
tools/ci.ts
|
|
@ -18,11 +18,11 @@
|
|||
// apps/desktop/src-tauri or the sidecar build changed against origin/main, or always with CI=full;
|
||||
// STOREBOUND_CI_RUST=0 skips it on a machine without Rust.
|
||||
import { existsSync, mkdtempSync, readFileSync, rmSync } from 'node:fs';
|
||||
import { homedir, tmpdir } from 'node:os';
|
||||
import { cpus, homedir, loadavg, tmpdir } from 'node:os';
|
||||
import { join } from 'node:path';
|
||||
import { hostTarget, OUT_DIR, outName } from './build-sidecars';
|
||||
import { loadFactor, loadNote, RETRY_MARK, scaled } from '../tests/helpers/load';
|
||||
import { BROWSER_CONCURRENCY, changedFiles, HEAVY, junitTimes, listTests, mergeTimings, planShards, readTimings, relatedTests, ROOT, rustNeeded, writeTimings } from './ci-plan';
|
||||
import { BROWSER_CONCURRENCY, changedFiles, deferBrowser, HEAVY, junitTimes, listTests, mergeTimings, planShards, readTimings, relatedTests, ROOT, rustNeeded, writeTimings } from './ci-plan';
|
||||
|
||||
interface Task { name: string; cmd: string[]; cwd?: string; env?: Record<string, string>; after?: string[]; junit?: string }
|
||||
|
||||
|
|
@ -30,7 +30,10 @@ const quick = process.argv.includes('--quick');
|
|||
const tauri = join(ROOT, 'apps/desktop/src-tauri');
|
||||
const cache = join(ROOT, 'node_modules/.cache/storebound-ci');
|
||||
const changed = changedFiles();
|
||||
const tests = listTests();
|
||||
const deferred = deferBrowser();
|
||||
const allTests = listTests();
|
||||
const tests = deferred ? allTests.filter(f => !HEAVY.includes(f)) : allTests;
|
||||
if (deferred) console.log(`ci: browser suites deferred to Forgejo CI (load ${loadavg()[0]!.toFixed(0)} > 2 x ${cpus().length} cores): ${allTests.filter(f => HEAVY.includes(f)).join(' ')} and the desktop boot check. CI=full runs them here.`);
|
||||
const touches = (re: RegExp) => changed === null || changed.some(f => re.test(f));
|
||||
const tasks: Task[] = [];
|
||||
const add = (t: Task) => tasks.push(t);
|
||||
|
|
@ -99,7 +102,7 @@ if (quick) {
|
|||
add({ name: 'desktop bundle check', cmd: ['bun', 'test', './apps/desktop/tests/webview.test.ts'], after: ['desktop build'] });
|
||||
// the built window boots (release CSP, Tauri's frozen Object.prototype, mocked host + real sidecar) on an empty, a
|
||||
// D1 (folders gone) and a full D3 saved state, through every screen: no uncaught error, never an empty window
|
||||
add({ name: 'desktop boot check', cmd: ['bun', 'tools/desktop-boot-check.ts'], after: ['desktop build'] });
|
||||
if (!deferred) add({ name: 'desktop boot check', cmd: ['bun', 'tools/desktop-boot-check.ts'], after: ['desktop build'] });
|
||||
// the CLI compiled into the desktop sidecar (bun build --compile, scanned for this machine's paths): rebuilt when
|
||||
// its inputs changed, with CI=full, or when missing; tauri's build script needs it for cargo test / clippy
|
||||
const hostBin = join(OUT_DIR, outName(hostTarget()));
|
||||
|
|
@ -196,5 +199,6 @@ for (const r of [...runs.values()].sort((a, b) => a.start - b.start)) {
|
|||
}
|
||||
for (const t of pending) console.log(` ${t.name.padEnd(width)} - not started`);
|
||||
if (retried.length) console.log(`\nretried under load (${retried.length}; each timed out once while load ÷ cores was above 2, then ran again):\n${retried.map(r => ` ${r}`).join('\n')}`);
|
||||
if (deferred) console.log(`\nci: browser suites deferred to Forgejo CI (load ${loadavg()[0]!.toFixed(0)}); check its run on main`);
|
||||
if (failed) { console.error(`\nci: ${failed} failed`); process.exit(1); }
|
||||
console.log(`\n${quick ? 'ci:quick' : 'ci'}: all green`);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue