mirror of
https://github.com/QwenLM/qwen-code.git
synced 2026-08-22 07:04:58 +00:00
* fix(ci): isolate web-shell Playwright smoke runner * fix(ci): avoid apt on ECS Playwright smoke * fix(ci): enable manual ecs smoke validation * fix(ci): repair manual runner input parsing * docs(ci): clarify self-hosted playwright deps * test(ci): fix Playwright runner assertion
134 lines
5 KiB
JavaScript
134 lines
5 KiB
JavaScript
/**
|
|
* @license
|
|
* Copyright 2026 Qwen Team
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
*/
|
|
|
|
import { readFileSync } from 'node:fs';
|
|
import path from 'node:path';
|
|
import { describe, expect, it } from 'vitest';
|
|
|
|
const ROOT = path.resolve(import.meta.dirname, '../..');
|
|
const NO_AK_SCRIPT = 'test:integration:no-ak:sandbox:none';
|
|
|
|
function getWorkflowJob(workflow, jobName) {
|
|
const marker = ` ${jobName}:`;
|
|
const start = workflow.indexOf(marker);
|
|
expect(start).toBeGreaterThanOrEqual(0);
|
|
|
|
const afterMarker = workflow.slice(start + marker.length);
|
|
const nextJob = afterMarker.match(/\n {2}[a-zA-Z0-9_-]+:\n/);
|
|
|
|
return workflow.slice(
|
|
start,
|
|
nextJob ? start + marker.length + nextJob.index : undefined,
|
|
);
|
|
}
|
|
|
|
describe('no-AK integration CI wiring', () => {
|
|
it('defines a focused no-AK integration script', () => {
|
|
const packageJson = JSON.parse(
|
|
readFileSync(path.join(ROOT, 'package.json'), 'utf8'),
|
|
);
|
|
|
|
expect(packageJson.scripts[NO_AK_SCRIPT]).toBe(
|
|
[
|
|
'cross-env QWEN_SANDBOX=false vitest run --root ./integration-tests',
|
|
'./fake-openai-server.test.ts',
|
|
'./cli/qwen-serve-routes.test.ts',
|
|
'./cli/qwen-serve-streaming.test.ts',
|
|
].join(' '),
|
|
);
|
|
});
|
|
|
|
it('runs the no-AK integration script in the Ubuntu gate only', () => {
|
|
const workflow = readFileSync(
|
|
path.join(ROOT, '.github/workflows/ci.yml'),
|
|
'utf8',
|
|
);
|
|
const ubuntuJob = getWorkflowJob(workflow, 'test');
|
|
const macosJob = getWorkflowJob(workflow, 'test_macos');
|
|
const windowsJob = getWorkflowJob(workflow, 'test_windows');
|
|
|
|
expect(workflow).not.toContain(' integration_no_ak:');
|
|
expect(workflow.split(`npm run ${NO_AK_SCRIPT}`).length - 1).toBe(1);
|
|
|
|
expect(ubuntuJob).toContain("name: 'Run no-AK integration smoke tests'");
|
|
expect(ubuntuJob).toContain("github.event_name == 'pull_request'");
|
|
expect(ubuntuJob).toContain(`npm run ${NO_AK_SCRIPT}`);
|
|
expect(ubuntuJob).not.toContain('secrets.OPENAI_API_KEY');
|
|
expect(ubuntuJob).not.toContain('secrets.OPENAI_BASE_URL');
|
|
expect(ubuntuJob).not.toContain('secrets.OPENAI_MODEL');
|
|
|
|
expect(macosJob).not.toContain(NO_AK_SCRIPT);
|
|
expect(windowsJob).not.toContain(NO_AK_SCRIPT);
|
|
});
|
|
|
|
it('checks out the immutable PR head ref instead of the lagging merge ref', () => {
|
|
const workflow = readFileSync(
|
|
path.join(ROOT, '.github/workflows/ci.yml'),
|
|
'utf8',
|
|
);
|
|
const ubuntuJob = getWorkflowJob(workflow, 'test');
|
|
const webShellJob = getWorkflowJob(workflow, 'web_shell_e2e_smoke');
|
|
const macosJob = getWorkflowJob(workflow, 'test_macos');
|
|
const windowsJob = getWorkflowJob(workflow, 'test_windows');
|
|
|
|
// On PRs every gate checks out refs/pull/N/head, which is published the
|
|
// instant the branch is pushed, instead of the merge ref that GitHub
|
|
// rebuilds asynchronously and can serve stale for minutes.
|
|
for (const job of [ubuntuJob, macosJob, windowsJob]) {
|
|
expect(job).toContain(
|
|
"format('refs/pull/{0}/head', github.event.pull_request.number)",
|
|
);
|
|
}
|
|
|
|
// The brittle merge-ref retry/refresh machinery is gone: in particular the
|
|
// direct GitHub fetch (the self-hosted proxy times it out) and the forced
|
|
// merge-ref checkout no longer exist.
|
|
expect(ubuntuJob).not.toContain(
|
|
"name: 'Fetch current PR merge ref from GitHub'",
|
|
);
|
|
expect(ubuntuJob).not.toContain('https://x-access-token:${GITHUB_TOKEN}');
|
|
expect(ubuntuJob).not.toContain('git checkout --force "${merge_ref}"');
|
|
expect(ubuntuJob).not.toContain(
|
|
"name: 'Back off for stale merge ref to refresh'",
|
|
);
|
|
|
|
// The cheap sanity guard stays: fail loud if HEAD lacks the expected head
|
|
// (PR head, or the merge-queue head once this job also runs on merge_group).
|
|
expect(ubuntuJob).toContain(
|
|
"name: 'Verify checkout includes expected head commit'",
|
|
);
|
|
expect(ubuntuJob).toContain('git merge-base --is-ancestor');
|
|
expect(ubuntuJob).toContain('github.event.pull_request.head.sha');
|
|
expect(webShellJob).toContain(
|
|
"name: 'Verify checkout includes expected head commit'",
|
|
);
|
|
expect(webShellJob).toContain('git merge-base --is-ancestor');
|
|
expect(webShellJob).toContain('github.event.pull_request.head.sha');
|
|
});
|
|
|
|
it('keeps the lightweight coverage comment job on the hosted runner', () => {
|
|
const workflow = readFileSync(
|
|
path.join(ROOT, '.github/workflows/ci.yml'),
|
|
'utf8',
|
|
);
|
|
const coverageJob = getWorkflowJob(workflow, 'post_coverage_comment');
|
|
|
|
expect(coverageJob).toContain("runs-on: 'ubuntu-latest'");
|
|
expect(coverageJob).not.toContain('ubuntu_runner');
|
|
});
|
|
|
|
it('does not install Linux packages on self-hosted Playwright runners', () => {
|
|
const workflow = readFileSync(
|
|
path.join(ROOT, '.github/workflows/ci.yml'),
|
|
'utf8',
|
|
);
|
|
const webShellJob = getWorkflowJob(workflow, 'web_shell_e2e_smoke');
|
|
|
|
expect(webShellJob).toContain('ubuntu_runner');
|
|
expect(webShellJob).toContain("run: 'npx playwright install chromium'");
|
|
expect(webShellJob).toContain('--with-deps chromium');
|
|
});
|
|
});
|