From 1af1bb8a55fa09b050cedb14a9b04eef1003086a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=98=93=E8=89=AF?= <1204183885@qq.com> Date: Mon, 29 Jun 2026 19:54:11 +0800 Subject: [PATCH] fix(ci): cover release integration regressions (#5994) * fix(ci): cover release integration regressions * fix(ci): retry linter archive downloads * fix(ci): keep release CI PR focused --- .../cli/qwen-serve-client-mcp.test.ts | 9 +++++- packages/chrome-extension/package.json | 4 +-- .../tests/chrome-extension-package.test.js | 28 +++++++++++++++++++ 3 files changed, 38 insertions(+), 3 deletions(-) create mode 100644 scripts/tests/chrome-extension-package.test.js diff --git a/integration-tests/cli/qwen-serve-client-mcp.test.ts b/integration-tests/cli/qwen-serve-client-mcp.test.ts index f87f51829c..0ac716eaf1 100644 --- a/integration-tests/cli/qwen-serve-client-mcp.test.ts +++ b/integration-tests/cli/qwen-serve-client-mcp.test.ts @@ -58,7 +58,12 @@ const REPO_ROOT = path.resolve(__dirname, '../..'); // platform-agnostic, but daemon SIGTERM teardown is cleaner on POSIX. Keep it // running everywhere `ws` works. const SKIP = process.platform === 'win32'; +const SANDBOX_MODE = process.env['QWEN_SANDBOX']?.toLowerCase().trim(); +const SKIP_PROMPTED_MODEL_TEST = Boolean( + SANDBOX_MODE && SANDBOX_MODE !== 'false' && SANDBOX_MODE !== '0', +); const describeMaybe = SKIP ? describe.skip : describe; +const itPromptedModelMaybe = SKIP_PROMPTED_MODEL_TEST ? it.skip : it; let daemon: ChildProcess; let port = 0; @@ -417,7 +422,9 @@ describeMaybe('qwen serve — reverse tool channel (client-hosted MCP over WS)', // // This test does session/new THEN mcp_register (the "register after a session // already exists" timing), exercising the fan-out path specifically. - it('drives a model→agent tools/call of chrome_read_page over the reverse WS channel and consumes the result', async () => { + // Under container sandboxing, the ACP child cannot reach the host-loopback + // fake model server used below; keep the discovery-only test running there. + itPromptedModelMaybe('drives a model→agent tools/call of chrome_read_page over the reverse WS channel and consumes the result', async () => { const ws = new WebSocket(`ws://127.0.0.1:${port}/acp`, { headers: { Authorization: `Bearer ${TOKEN}` }, }); diff --git a/packages/chrome-extension/package.json b/packages/chrome-extension/package.json index d0228253f1..d4bfec7f69 100644 --- a/packages/chrome-extension/package.json +++ b/packages/chrome-extension/package.json @@ -24,12 +24,12 @@ "README.md" ], "scripts": { - "dev": "EXTENSION_OUT_DIR=dist/extension node scripts/dev-watch.js", + "dev": "node scripts/dev-watch.js", "debug:mac": "./scripts/debug.sh", "sync:extension": "node scripts/sync-extension.js", "build:bg": "node scripts/sync-extension.js && node config/esbuild.background.config.js", "build:bg:watch": "node scripts/sync-extension.js && node config/esbuild.background.config.js --watch", - "build": "EXTENSION_OUT_DIR=dist/extension npm run clean && EXTENSION_OUT_DIR=dist/extension node scripts/sync-extension.js && EXTENSION_OUT_DIR=dist/extension node config/esbuild.background.config.js --production", + "build": "node scripts/sync-extension.js && node config/esbuild.background.config.js --production", "test": "vitest run --config vitest.config.ts", "test:ci": "vitest run --config vitest.config.ts", "dev:chrome": "open -a 'Google Chrome' --args --load-extension=$PWD/dist/extension --auto-open-devtools-for-tabs", diff --git a/scripts/tests/chrome-extension-package.test.js b/scripts/tests/chrome-extension-package.test.js new file mode 100644 index 0000000000..b289078cb2 --- /dev/null +++ b/scripts/tests/chrome-extension-package.test.js @@ -0,0 +1,28 @@ +/** + * @license + * Copyright 2026 Qwen Team + * SPDX-License-Identifier: Apache-2.0 + */ + +import { readFileSync } from 'node:fs'; +import path from 'node:path'; +import { fileURLToPath } from 'node:url'; +import { describe, expect, it } from 'vitest'; + +const __dirname = path.dirname(fileURLToPath(import.meta.url)); +const root = path.resolve(__dirname, '../..'); + +describe('chrome extension package scripts', () => { + it('keeps the build script portable for Windows npm lifecycle runs', () => { + const packageJson = JSON.parse( + readFileSync( + path.join(root, 'packages/chrome-extension/package.json'), + 'utf8', + ), + ); + + expect(packageJson.scripts.build).not.toMatch( + /(?:^|\s&&\s)[A-Za-z_][A-Za-z0-9_]*=/, + ); + }); +});