Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
37dead9
ci: gate heavy jobs on a disk floor and persist pressure samples
yiliang114 Aug 28, 2026
7da0eb7
ci: single-quote the failure() condition to satisfy yamllint quoted-s…
yiliang114 Aug 28, 2026
d8ff4f2
ci: keep TMPDIR routing block byte-identical across test legs
yiliang114 Aug 28, 2026
1186e50
fix(ci): validate disk floor overrides
yiliang114 Aug 29, 2026
c17ce29
fix(ci): reject oversized disk floor overrides
yiliang114 Aug 29, 2026
44344d4
test(ci): pin the disk-floor overflow guard boundaries
yiliang114 Aug 29, 2026
6eae982
Merge origin/main into fix/ci-disk-floor-gate-10035
yiliang114 Aug 29, 2026
0c7fe0a
refactor(ci): simplify disk floor validation and sampling
yiliang114 Aug 29, 2026
5c8456d
fix(ci): preserve the TMPDIR sampler sentinel
yiliang114 Aug 29, 2026
fa9bfb0
fix(ci): retain disk samples from dependency install
yiliang114 Aug 29, 2026
26654c5
refactor(ci): reuse the workflow parser in disk tests
yiliang114 Aug 29, 2026
9ac726f
Merge origin/main into fix/ci-preinstall-disk-sampling-10035
yiliang114 Aug 30, 2026
1a4fd1b
chore(ci): trigger checks after retargeting to main
yiliang114 Aug 30, 2026
8a0f5dd
test(ci): pin disk-pressure workflow contract
yiliang114 Aug 30, 2026
8a386ab
Merge branch 'main' into fix/ci-preinstall-disk-sampling-10035
yiliang114 Aug 30, 2026
cbf28ac
fix(ci): harden install disk sampling
yiliang114 Aug 30, 2026
3aac615
Merge branch 'main' into fix/ci-preinstall-disk-sampling-10035
yiliang114 Aug 30, 2026
c0da45d
ci: record ci.yml growth in the size baseline
yiliang114 Aug 30, 2026
9964047
Merge branch 'main' into fix/ci-preinstall-disk-sampling-10035
yiliang114 Aug 31, 2026
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
117 changes: 117 additions & 0 deletions .github/scripts/ci-disk-pressure.test.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
import assert from 'node:assert/strict';
import { spawnSync } from 'node:child_process';
import {
chmodSync,
mkdtempSync,
readFileSync,
rmSync,
writeFileSync,
} from 'node:fs';
import { tmpdir } from 'node:os';
import { dirname, join } from 'node:path';
import { describe, it } from 'node:test';
import { fileURLToPath } from 'node:url';
import { parse } from 'yaml';

const workflowPath = join(
dirname(fileURLToPath(import.meta.url)),
'..',
'workflows',
'ci.yml',
);
const testSteps = parse(readFileSync(workflowPath, 'utf8')).jobs.test.steps;

function step(name) {
const value = testSteps.find((candidate) => candidate.name === name);
assert.ok(value, `missing ${name} step`);
return value;
}

describe('ci.yml disk-pressure evidence', () => {
it('starts sampling before npm ci and preserves those samples for upload', () => {
const install = step('Install dependencies').run;
const npmCi = install.indexOf('npm ci');

assert.match(
install,
/DISK_SAMPLES="\$\{RUNNER_TEMP\}\/disk-pressure-samples\.log"/,
);
assert.ok(npmCi > install.indexOf('DFSAMPLE '));
assert.match(install, /\( while sleep 10; do sample_disk; done \) &/);
assert.ok(npmCi > install.indexOf('( while sleep 10'));
assert.match(install, /trap .*SAMPLER_PID.* EXIT/);

const tests = step('Run tests and generate reports').run;
assert.match(
tests,
/DISK_SAMPLES="\$\{RUNNER_TEMP\}\/disk-pressure-samples\.log"\nif \[ ! -s "\$DISK_SAMPLES" \]; then\n {2}echo "DISKCONTEXT .*" > "\$DISK_SAMPLES" 2>\/dev\/null \|\| true\nfi/,
);
assert.ok(tests.indexOf('export TMPDIR=') > tests.indexOf('DISK_SAMPLES='));

const sampleFormat = (script) => {
const match = script.match(
/sample="DFSAMPLE .*\/proc\/meminfo 2>\/dev\/null(?: \|\| true)?\)\]"/,
);
assert.ok(match);
return match[0]
.replaceAll('${RUNNER_TEMP:-/tmp}', '${TMPDIR}')
.replace(
' /proc/meminfo 2>/dev/null || true)]',
' /proc/meminfo 2>/dev/null)]',
);
};
const headerLine = (script) =>
script
.split('\n')
.find((line) => line.trimStart().startsWith('echo "DISKCONTEXT '))
?.trim();
assert.equal(headerLine(install), headerLine(tests));
assert.equal(sampleFormat(install), sampleFormat(tests));

const upload = step('Upload disk-pressure samples');
assert.equal(upload.if, '${{ failure() }}');
assert.equal(upload.with['if-no-files-found'], 'ignore');
Comment thread
yiliang114 marked this conversation as resolved.
Resolved
assert.equal(
upload.with.path,
'${{ runner.temp }}/disk-pressure-samples.log',
);
});

it('keeps install failure status while writing the pre-install sample', () => {
const root = mkdtempSync(join(tmpdir(), 'ci-disk-pressure-'));
const npm = join(root, 'npm');
writeFileSync(npm, '#!/usr/bin/env bash\nexit 42\n');
chmodSync(npm, 0o755);

try {
const result = spawnSync(
'bash',
['-e', '-o', 'pipefail', '-c', step('Install dependencies').run],
Comment thread
yiliang114 marked this conversation as resolved.
Resolved
{
encoding: 'utf8',
timeout: 30_000,
env: {
...process.env,
PATH: `${root}:${process.env.PATH}`,
RUNNER_TEMP: root,
},
},
);

assert.equal(result.error, undefined);
assert.equal(
result.status,
42,
`signal: ${result.signal}\nerror: ${result.error}\nstdout: ${result.stdout}\nstderr: ${result.stderr}`,
);
const samples = readFileSync(
join(root, 'disk-pressure-samples.log'),
'utf8',
);
assert.match(samples, /^DISKCONTEXT /m);
assert.match(samples, /^DFSAMPLE /m);
} finally {
rmSync(root, { recursive: true, force: true });
}
});
});
2 changes: 1 addition & 1 deletion .github/workflows/.size-baseline
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
9256 build-and-publish-image.yml
49610 cd-cua-driver.yml
2076 cd-mobile-mcp.yml
98043 ci.yml
102891 ci.yml
1482 codeql.yml
9389 comment-attachment-guard.yml
31677 desktop-release.yml
Expand Down
17 changes: 15 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ env:
# BOTH the github_ci_only helper step and the full-profile Test step, so a
# new helper test can't be added to one path and silently dropped from the
# other.
HELPER_TESTS: '.github/scripts/pr-safety-precheck.test.mjs .github/scripts/cap-release-notes.test.mjs .github/scripts/ci/classify-profile.test.mjs .github/scripts/ci/classify-platform-sensitivity.test.mjs .github/scripts/ci/classify-pr-profile.test.mjs .github/scripts/upsert-bot-comment.test.mjs .github/scripts/ci/main-failure-signature.test.mjs .github/scripts/classify-release-notes.test.mjs .github/scripts/dsw-swe-verified/make-manifest.test.mjs .github/scripts/dsw-swe-verified/make-terminal-bench-manifest.test.mjs .github/scripts/resolve-sandbox-image.test.mjs .github/scripts/web-shell-visuals-publish.test.mjs .github/scripts/web-shell-visuals-compose.test.mjs .github/scripts/serve-ab-diff.test.mjs .github/scripts/serve-ab-drive.test.mjs .github/scripts/qwen-triage-workflow.test.mjs .github/scripts/assign-issue-owner.test.mjs .github/scripts/auto-minimize-spam.test.mjs .github/scripts/ci-runner-routing.test.mjs .github/scripts/autofix-status-heartbeat.test.mjs .github/scripts/assign-pr-owner.test.mjs .github/scripts/check-disk-floor.test.mjs'
HELPER_TESTS: '.github/scripts/pr-safety-precheck.test.mjs .github/scripts/cap-release-notes.test.mjs .github/scripts/ci/classify-profile.test.mjs .github/scripts/ci/classify-platform-sensitivity.test.mjs .github/scripts/ci/classify-pr-profile.test.mjs .github/scripts/upsert-bot-comment.test.mjs .github/scripts/ci/main-failure-signature.test.mjs .github/scripts/classify-release-notes.test.mjs .github/scripts/dsw-swe-verified/make-manifest.test.mjs .github/scripts/dsw-swe-verified/make-terminal-bench-manifest.test.mjs .github/scripts/resolve-sandbox-image.test.mjs .github/scripts/web-shell-visuals-publish.test.mjs .github/scripts/web-shell-visuals-compose.test.mjs .github/scripts/serve-ab-diff.test.mjs .github/scripts/serve-ab-drive.test.mjs .github/scripts/qwen-triage-workflow.test.mjs .github/scripts/assign-issue-owner.test.mjs .github/scripts/auto-minimize-spam.test.mjs .github/scripts/ci-runner-routing.test.mjs .github/scripts/autofix-status-heartbeat.test.mjs .github/scripts/assign-pr-owner.test.mjs .github/scripts/check-disk-floor.test.mjs .github/scripts/ci-disk-pressure.test.mjs'
Comment thread
yiliang114 marked this conversation as resolved.
Resolved
# The growth ratchet and its vitest mirror compare each workflow against
# the PR's base commit to tell "this PR grew the file" apart from "the
# baseline went stale on main" (#9904). Wired once here so every lane
Expand Down Expand Up @@ -479,6 +479,17 @@ jobs:
- name: 'Install dependencies'
if: "${{ needs.classify_pr.outputs.skip_ci != 'true' && steps.ci_profile.outputs.ci_profile == 'full' }}"
run: |-
DISK_SAMPLES="${RUNNER_TEMP}/disk-pressure-samples.log"
echo "DISKCONTEXT $(date -u +%Y-%m-%dT%H:%M:%SZ 2>/dev/null) runner[${RUNNER_NAME:-unknown}] run[${GITHUB_RUN_ID:-local}/${GITHUB_RUN_ATTEMPT:-1}] job[${GITHUB_JOB:-test}]" > "$DISK_SAMPLES" 2>/dev/null || true
Comment thread
yiliang114 marked this conversation as resolved.
Resolved
sample_disk() {
sample="DFSAMPLE $(date -u +%H:%M:%S 2>/dev/null) tmpdir[${RUNNER_TEMP:-/tmp}] space[$(df -h "${RUNNER_TEMP:-/tmp}" 2>/dev/null | tail -1)] inodes[$(df -i "${RUNNER_TEMP:-/tmp}" 2>/dev/null | tail -1)] memavail[$(awk '/MemAvailable/ {print $2, $3}' /proc/meminfo 2>/dev/null)]" || true
echo "$sample"
echo "$sample" >> "$DISK_SAMPLES" 2>/dev/null || true
}
sample_disk
( while sleep 10; do sample_disk; done ) &
Comment thread
yiliang114 marked this conversation as resolved.
Resolved
SAMPLER_PID=$!
trap 'pkill -TERM -P "$SAMPLER_PID" 2>/dev/null || true; kill "$SAMPLER_PID" 2>/dev/null || true' EXIT
npm ci --prefer-offline --no-audit --progress=false

- name: 'Report npm cache usage (self-hosted)'
Expand Down Expand Up @@ -659,7 +670,9 @@ jobs:
# the test/test_macos/test_windows legs; each DFSAMPLE line already
# carries the routed tmpdir, so the header only needs job/runner ids.
DISK_SAMPLES="${RUNNER_TEMP}/disk-pressure-samples.log"
echo "DISKCONTEXT $(date -u +%Y-%m-%dT%H:%M:%SZ 2>/dev/null) runner[${RUNNER_NAME:-unknown}] run[${GITHUB_RUN_ID:-local}/${GITHUB_RUN_ATTEMPT:-1}] job[${GITHUB_JOB:-test}]" > "$DISK_SAMPLES" 2>/dev/null || true
if [ ! -s "$DISK_SAMPLES" ]; then
echo "DISKCONTEXT $(date -u +%Y-%m-%dT%H:%M:%SZ 2>/dev/null) runner[${RUNNER_NAME:-unknown}] run[${GITHUB_RUN_ID:-local}/${GITHUB_RUN_ATTEMPT:-1}] job[${GITHUB_JOB:-test}]" > "$DISK_SAMPLES" 2>/dev/null || true
fi
Comment thread
yiliang114 marked this conversation as resolved.
Resolved
export TMPDIR="${RUNNER_TEMP:-${TMPDIR:-/tmp}}"
if [ "${RUNNER_OS:-}" = "Linux" ]; then
QWEN_CI_TMPDIR="$(mktemp -d /var/tmp/qwen-ci-XXXXXX 2>/dev/null || true)"
Expand Down
6 changes: 6 additions & 0 deletions scripts/tests/ci-platform-lanes.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -426,6 +426,12 @@ describe('platform lanes — the retired sensitivity classifier', () => {
});

describe('GitHub helper tests', () => {
it('includes the disk-pressure contract suite', () => {
expect(ci.env.HELPER_TESTS).toContain(
'.github/scripts/ci-disk-pressure.test.mjs',
);
});

it('runs every invocation serially', () => {
const helperSteps = Object.values(ci.jobs)
.flatMap((job) => job.steps ?? [])
Expand Down
Loading