From 2c60c350482c3b31d2c404d4404b66a79be7e0e6 Mon Sep 17 00:00:00 2001 From: Donald Date: Thu, 20 Aug 2026 03:53:33 +0000 Subject: [PATCH] fix: package complete Windows bridge runtime --- package-lock.json | 4 ++-- package.json | 2 +- scripts/build-release.mjs | 2 +- scripts/verify-release.mjs | 17 ++++++++++++++++- src/version.ts | 2 +- test/distribution.test.ts | 5 +++++ 6 files changed, 26 insertions(+), 6 deletions(-) diff --git a/package-lock.json b/package-lock.json index 0f04e60..0c51e83 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "dingtalk-approval-mcp", - "version": "1.1.0-rc.15", + "version": "1.1.0-rc.16", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "dingtalk-approval-mcp", - "version": "1.1.0-rc.15", + "version": "1.1.0-rc.16", "dependencies": { "@modelcontextprotocol/sdk": "^1.30.0", "express": "^5.2.1", diff --git a/package.json b/package.json index f9427ea..89944b7 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "dingtalk-approval-mcp", - "version": "1.1.0-rc.15", + "version": "1.1.0-rc.16", "description": "A lightweight Agent bridge for a unified DingTalk OA and XFT approval gateway.", "private": true, "type": "module", diff --git a/scripts/build-release.mjs b/scripts/build-release.mjs index 1678211..81bb725 100644 --- a/scripts/build-release.mjs +++ b/scripts/build-release.mjs @@ -44,7 +44,7 @@ mkdirSync(out, { recursive: true, mode: 0o755 }); execFileSync("npm", ["run", "build"], { stdio: "inherit", env: npmEnvironment() }); mkdirSync(join(clientStaging, "dist", "src"), { recursive: true }); -for (const name of ["bridge.js", "entrypoint.js", "client-installer.js", "approval-contract.js"]) { +for (const name of ["bridge.js", "entrypoint.js", "client-installer.js", "approval-contract.js", "version.js"]) { cpSync(resolve("dist", "src", name), join(clientStaging, "dist", "src", name)); } cpSync(resolve("skills/dingtalk-approval"), join(clientStaging, "skill", "dingtalk-approval"), { recursive: true }); diff --git a/scripts/verify-release.mjs b/scripts/verify-release.mjs index 9f9cc28..77a1242 100644 --- a/scripts/verify-release.mjs +++ b/scripts/verify-release.mjs @@ -2,7 +2,7 @@ import { createHash, createPublicKey, verify as verifySignature } from "node:crypto"; import { mkdtempSync, readFileSync, readdirSync, rmSync, statSync } from "node:fs"; import { tmpdir } from "node:os"; -import { basename, join, resolve, sep } from "node:path"; +import { basename, dirname, join, resolve, sep } from "node:path"; import { execFileSync } from "node:child_process"; import { parseArgs } from "node:util"; @@ -54,6 +54,7 @@ try { scanTree(clientRoot); const packageMetadata = JSON.parse(readFileSync(join(root, "client", "package", "package.json"), "utf8")); if (packageMetadata.name !== "dingtalk-approval-client" || packageMetadata.version !== version) throw new Error("客户端 package.json 名称或版本不一致"); + assertRelativeModuleClosure(join(root, "client", "package", "dist", "src")); if (JSON.stringify(Object.keys(packageMetadata.bin ?? {}).sort()) !== JSON.stringify(["dingtalk-approval", "dingtalk-approval-bridge"])) { throw new Error("客户端只能发布安装 CLI 和 Bridge 两个 bin"); } @@ -154,6 +155,20 @@ function releaseKeyId(value) { return createHash("sha256").update(der).digest("hex"); } function existsFile(path) { try { return statSync(path).isFile(); } catch { return false; } } +function assertRelativeModuleClosure(rootPath) { + const prefix = `${resolve(rootPath)}${sep}`; + for (const path of walk(rootPath)) { + if (!path.endsWith(".js")) continue; + const body = readFileSync(path, "utf8"); + const imports = body.matchAll(/(?:\bfrom\s*|\bimport\s*)["'](\.\.?\/[^"']+\.js)["']/g); + for (const match of imports) { + const target = resolve(dirname(path), match[1]); + if (!target.startsWith(prefix) || !existsFile(target)) { + throw new Error(`客户端模块依赖缺失:${match[1]}(由 ${path.slice(prefix.length)} 导入)`); + } + } + } +} function scanTree(rootPath) { for (const path of walk(rootPath)) { if (statSync(path).size > 2_000_000) continue; diff --git a/src/version.ts b/src/version.ts index 26f0bbd..b4cc622 100644 --- a/src/version.ts +++ b/src/version.ts @@ -1 +1 @@ -export const APPLICATION_VERSION = "1.1.0-rc.15"; +export const APPLICATION_VERSION = "1.1.0-rc.16"; diff --git a/test/distribution.test.ts b/test/distribution.test.ts index ec150d5..e0092d6 100644 --- a/test/distribution.test.ts +++ b/test/distribution.test.ts @@ -122,9 +122,14 @@ test("customer distribution prefers remote MCP OAuth and keeps a generic compati assert.match(builder, /utf8Bom: true/); assert.match(builder, /validateNodeRuntime/); assert.match(builder, /cpSync\(resolve\("skills\/dingtalk-approval"\).*recursive: true/s); + assert.match(builder, /"approval-contract\.js", "version\.js"/); assert.doesNotMatch(builder, /codexPlugin|codex-plugin|\.codex-plugin|openai\.yaml/); assert.doesNotMatch(builder, /dingtalk-workspace-cli|DWS_URL|DWS_SHA256/); + const releaseVerifier = readFileSync("scripts/verify-release.mjs", "utf8"); + assert.match(releaseVerifier, /assertRelativeModuleClosure\(join\(root, "client", "package", "dist", "src"\)\)/); + assert.match(releaseVerifier, /客户端模块依赖缺失/); + const deploy = readFileSync("deploy/install.sh", "utf8"); assert.match(deploy, /--download-base-url "\$\{gitea_release_base_url\}"[\s\S]*--download-mirror-base-url "\$\{public_download_base_url\}"/s); assert.match(deploy, /refs\/tags\/\$\{release_tag\}[\s\S]*release_created_at_commit="\$\{release_tag_commit:-\$\{release_commit\}\}"/s);