test(ci): drive the shellcheck lane for the probe; copy scripts dir in shard harness

R2-1: the shebang test now runs the lane's own candidate selection with only
shellcheck stubbed, so a filter change dropping the probe is caught (removing the
shebang reddens it). R2-2: the shard-retry harness copies the whole .github/scripts
dir so any sourced sibling comes along instead of a hand-maintained file list.
This commit is contained in:
yiliang114 committed 2026-11-05 06:29:49 +08:00
1 parent 098070b210
commit 9b3d131cdb
2 files changed
+27 -17

No files matched your search

+5 -7
View File
@@ -7,6 +7,7 @@
import { execFileSync } from 'node:child_process';
import {
chmodSync,
cpSync,
mkdtempSync,
readFileSync,
rmSync,
@@ -22,16 +23,14 @@ import { describe, expect, it } from 'vitest';
// Windows lanes in vitest.config.ts.
describe('e2e workflow sandbox:none shard retry execution', () => {
const script = readFileSync('.github/scripts/run-e2e-tests.sh', 'utf8');
// run-e2e-tests.sh sources this sibling at startup; the temp-dir copy must
// carry it too or `set -e` aborts on the missing source before any shard runs.
const aptMirrorProbe = readFileSync(
'.github/scripts/apt-mirror-probe.sh',
'utf8',
);
function runStepScript({ failCalls, elapsedSeconds }) {
const dir = mkdtempSync(join(tmpdir(), 'qwen-e2e-retry-'));
try {
// Copy the whole scripts dir so any sibling the runner sources comes
// along, instead of hand-maintaining a per-file list (#16278 R2-2). The
// probe lands at dir/apt-mirror-probe.sh, where dirname BASH_SOURCE looks.
cpSync('.github/scripts', dir, { recursive: true });
const callCountFile = join(dir, 'npm-call-count');
const npmStub = join(dir, 'npm');
writeFileSync(callCountFile, '0');
@@ -60,7 +59,6 @@ describe('e2e workflow sandbox:none shard retry execution', () => {
chmodSync(dateStub, 0o755);
const scriptFile = join(dir, 'run-e2e-tests.sh');
writeFileSync(scriptFile, script);
writeFileSync(join(dir, 'apt-mirror-probe.sh'), aptMirrorProbe);
let exitCode = 0;
let output = '';
try {
+22 -10
View File
@@ -704,16 +704,28 @@ describe('git-sourced lint lanes', () => {
it.skipIf(process.platform === 'win32')(
'enrols the sourced apt-mirror probe in the shellcheck lane via its shebang',
() => {
// The lane filters candidates on file(1) mime type; a sourced-only .sh
// without a shebang reports text/plain and is silently dropped, so the
// probe must keep its shebang to stay linted (#16278 R1-2).
const probe = path.resolve('.github/scripts/apt-mirror-probe.sh');
const mime = spawnSync('file', ['--brief', '--mime-type', probe], {
encoding: 'utf8',
});
if (mime.status !== 0) return; // file(1) absent locally; CI gates have it
expect(mime.stdout.trim()).toBe('text/x-shellscript');
async (ctx) => {
// Drive the lane's own candidate selection (name regex + real file(1)
// mime filter) with only shellcheck stubbed, so a change to the lane's
// filter that drops the probe is caught here (#16278 R2-1). Removing the
// probe's shebang makes file(1) report text/plain and reddens this case.
const linters = await getLintersOrSkip(ctx);
const probeSrc = readFileSync(
'.github/scripts/apt-mirror-probe.sh',
'utf8',
);
const { root, repo, bin } = setup({ 'apt-mirror-probe.sh': probeSrc });
try {
const shellcheckLog = path.join(root, 'shellcheck.log');
stub(bin, 'shellcheck', `echo "$@" >> '${shellcheckLog}'`);
const result = runLane(linters.shellcheck.run, { repo, bin });
expect(result.status).toBe(0);
expect(readFileSync(shellcheckLog, 'utf8')).toContain(
'apt-mirror-probe.sh',
);
} finally {
rmSync(root, { recursive: true, force: true });
}
},
);