From e4692524ceb473128fe46afb6ef8fdf1acec1dd8 Mon Sep 17 00:00:00 2001 From: lbb00 Date: Tue, 8 Sep 2026 20:02:03 +0800 Subject: [PATCH] =?UTF-8?q?fix(release):=20=E8=BF=9B=20dimina/fe=20?= =?UTF-8?q?=E4=B9=8B=E5=89=8D=E6=94=B9=E7=94=A8=20runner=20=E4=B8=8A?= =?UTF-8?q?=E7=9A=84=20pnpm?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit release 通道今天在 Install dimina/fe deps 上全平台失败,退出码 2,报的是 `.../pnpm/12.2.0/.../node_modules/pnpm/pnpm.exe: 4: Syntax error: ")" unexpected`。 dimina/fe 是 submodule 里的独立 pnpm workspace,声明 packageManager 是 pnpm@12.2.0,本仓根声明的是 pnpm@12.3.4。pnpm 一进那个目录就去下载并切换到 12.2.0,而这次切换在 runner 上 exec 了下载包里的 pnpm.exe——Windows 二进制被 当成 shell 脚本跑,Linux 和 macOS 上必然报语法错。 #203 之前两边都是 pnpm@9.15.9,不触发切换,所以一直没暴露;#203 把根升到 12.3.4 之后,今天是第一次在含它的提交上跑 release 通道。ci.yml 不跑 `pnpm -C dimina/fe install`(改用 upstream-lockfile-snapshot 比对),所以 PR 的 CI 全绿也拦不住这条。 pnpm 12 已经没有能关掉版本自管的配置项了:--config.manage-package-manager-versions、 npm_config_* 环境变量和 --pm-on-fail 都不阻止切换,唯一的开关只能写进那个 workspace 自己的 pnpm-workspace.yaml,而它属于 submodule。所以改成在 runner 的 工作副本上摘掉 dimina/fe 的 packageManager 字段,让 submodule 用 runner 上已经 装好的 pnpm;改动不提交,也不进 submodule。 这一步排在两个 job 里所有进入 dimina/fe 的动作之前:除了装依赖, build-container.js 也会在那个目录 spawn pnpm build,同样会踩。 本地已验证 pnpm 12.3.4 能装 dimina/fe,脚本可重复执行,两边版本一致时不做改动。 Co-Authored-By: Claude Opus 5 (1M context) --- .../scripts/use-runner-pnpm-for-dimina-fe.js | 50 +++++++++++++++++++ .github/workflows/release.yml | 10 ++++ 2 files changed, 60 insertions(+) create mode 100644 .github/scripts/use-runner-pnpm-for-dimina-fe.js diff --git a/.github/scripts/use-runner-pnpm-for-dimina-fe.js b/.github/scripts/use-runner-pnpm-for-dimina-fe.js new file mode 100644 index 00000000..5790a029 --- /dev/null +++ b/.github/scripts/use-runner-pnpm-for-dimina-fe.js @@ -0,0 +1,50 @@ +#!/usr/bin/env node + +// dimina/fe 是 submodule 里的一个独立 pnpm workspace,它的 package.json 声明 +// packageManager: pnpm@12.2.0,和本仓根声明的版本不是同一个。pnpm 一进这个目录 +// 就会去下载并切换到它声明的那个版本,而 runner 上这次切换会 exec 下载包里的 +// pnpm.exe——Windows 二进制——于是 Linux 和 macOS 上直接以 +// `Syntax error: ")" unexpected` 退出 2。Install dimina/fe deps 和随后的 +// build:container 都断在这里。 +// +// pnpm 12 已经没有能关掉版本自管的配置项了:--config.manage-package-manager-versions、 +// npm_config_* 环境变量、--pm-on-fail 都不阻止切换,唯一的开关得写进那个 workspace +// 自己的 pnpm-workspace.yaml,而那是 submodule 的文件。所以这里在 runner 的工作副本 +// 上摘掉这个字段,让 submodule 用 runner 上已经装好的 pnpm。改动不提交,也不进 +// submodule。 +// +// 两边版本一致(或 submodule 自己去掉了这个字段)时什么都不做,可以重复跑。 + +import { readFileSync, writeFileSync } from 'node:fs' + +const FE_MANIFEST = 'dimina/fe/package.json' + +const source = readFileSync(FE_MANIFEST, 'utf8') +const declared = JSON.parse(source).packageManager + +if (!declared) { + console.log(`${FE_MANIFEST} 没有声明 packageManager,无需处理`) + process.exit(0) +} + +const rootDeclared = JSON.parse(readFileSync('package.json', 'utf8')).packageManager + +if (declared === rootDeclared) { + console.log(`dimina/fe 与本仓根都是 ${declared},不会触发版本切换,无需处理`) + process.exit(0) +} + +// 只删这一行,其余原样保留:这份 manifest 属于 submodule,不做格式化重写。 +const stripped = source.replace(/^[ \t]*"packageManager":[ \t]*"[^"]*",?\r?\n/m, '') + +if (stripped === source) { + throw new Error(`在 ${FE_MANIFEST} 里没找到可删除的 packageManager 行`) +} + +JSON.parse(stripped) +writeFileSync(FE_MANIFEST, stripped) + +console.log( + `已在 runner 的工作副本上移除 dimina/fe 的 packageManager(${declared}),` + + `改用本仓根的 ${rootDeclared}`, +) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 25202722..f1226f4c 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -166,6 +166,12 @@ jobs: - name: Install workspace deps run: pnpm install --frozen-lockfile --prefer-offline + # 必须排在任何进入 dimina/fe 的步骤之前:装依赖和 build:container 都会在那里 + # 起 pnpm,而 submodule 声明的 pnpm 版本和本仓根不同时,切换会 exec 到 + # pnpm.exe 并让这一步直接退出 2。脚本里写了完整来龙去脉。 + - name: Use the runner's pnpm inside dimina/fe + run: node .github/scripts/use-runner-pnpm-for-dimina-fe.js + - name: Install dimina/fe deps working-directory: dimina/fe run: pnpm install --no-frozen-lockfile @@ -354,6 +360,10 @@ jobs: - name: Install workspace deps run: pnpm install --frozen-lockfile --prefer-offline --ignore-scripts + # 同 build-clients:进 dimina/fe 之前先摘掉它声明的 pnpm 版本。 + - name: Use the runner's pnpm inside dimina/fe + run: node .github/scripts/use-runner-pnpm-for-dimina-fe.js + - name: Install dimina/fe deps working-directory: dimina/fe run: pnpm install --no-frozen-lockfile --ignore-scripts