ci(github actions): fix cross-compile arch issue for prepare step (#2075)

1. 为CI的Prepare步骤添加npm_config_arch和target_arch环境变量
2. 重构架构解析逻辑,支持从环境变量读取目标架构
3. 添加ELF架构校验,防止交叉编译时混入错误架构的二进制文件
This commit is contained in:
shenmo
2026-08-13 04:38:22 +08:00
committed by GitHub
parent 356f9817f0
commit c89e21b782
2 changed files with 66 additions and 3 deletions

View File

@@ -121,6 +121,9 @@ jobs:
GITHUB_EVENT_NAME: workflow_dispatch
run: node scripts/update-version.mjs
- name: Prepare
env:
npm_config_arch: ${{ matrix.arch }}
npm_config_target_arch: ${{ matrix.arch }}
run: pnpm prepare --${{ matrix.arch }}
- name: Build
env:
@@ -206,6 +209,8 @@ jobs:
run: node scripts/update-version.mjs
- name: Prepare
env:
npm_config_arch: ${{ matrix.arch }}
npm_config_target_arch: ${{ matrix.arch }}
LEGACY_BUILD: 'true'
run: pnpm prepare --${{ matrix.arch }}
- name: Build
@@ -293,6 +298,9 @@ jobs:
GITHUB_EVENT_NAME: workflow_dispatch
run: node scripts/update-version.mjs
- name: Prepare
env:
npm_config_arch: ${{ matrix.arch }}
npm_config_target_arch: ${{ matrix.arch }}
run: pnpm prepare --${{ matrix.arch }}
- name: Build
env:
@@ -369,6 +377,9 @@ jobs:
GITHUB_EVENT_NAME: workflow_dispatch
run: node scripts/update-version.mjs
- name: Prepare
env:
npm_config_arch: ${{ matrix.arch }}
npm_config_target_arch: ${{ matrix.arch }}
run: pnpm prepare --${{ matrix.arch }}
- name: Build
env:
@@ -467,6 +478,9 @@ jobs:
GITHUB_EVENT_NAME: workflow_dispatch
run: node scripts/update-version.mjs
- name: Prepare
env:
npm_config_arch: ${{ matrix.arch }}
npm_config_target_arch: ${{ matrix.arch }}
run: pnpm prepare --${{ matrix.arch }}
- name: Build
env:

View File

@@ -7,11 +7,24 @@ import { execSync } from 'child_process'
const cwd = process.cwd()
const TEMP_DIR = path.join(cwd, 'node_modules/.temp')
let arch = process.arch
const platform = process.platform
if (process.argv.slice(2).length !== 0) {
arch = process.argv.slice(2)[0].replace('--', '')
// 目标架构解析优先级:命令行参数 > npm_config_arch 环境变量 > 当前进程架构
// CI 交叉编译(如 ubuntu x64 宿主构建 arm64 包)时,若参数未传递到位,
// 会误用宿主机的 x64 架构下载 sidecar导致 arm64 包内混入 x64 二进制
const SUPPORTED_ARCHS = ['x64', 'ia32', 'arm64']
function resolveTargetArch() {
const args = process.argv.slice(2)
if (args.length !== 0) {
return args[0].replace('--', '')
}
const npmArch = process.env.npm_config_arch
if (npmArch && SUPPORTED_ARCHS.includes(npmArch)) {
return npmArch
}
return process.arch
}
const arch = resolveTargetArch()
/* ======= mihomo alpha======= */
const MIHOMO_ALPHA_VERSION_URL =
@@ -280,6 +293,11 @@ async function downloadFile(url, path) {
method: 'GET',
headers: { 'Content-Type': 'application/octet-stream' }
})
if (!response.ok) {
throw new Error(
`download failed: ${response.status} ${response.statusText} for "${url}"`
)
}
const buffer = await response.arrayBuffer()
fs.writeFileSync(path, new Uint8Array(buffer))
@@ -325,6 +343,33 @@ const resolveEnableLoopback = () =>
const SYSPROXY_RS_URL_PREFIX =
'https://github.com/mihomo-party-org/sysproxy-rs-opti/releases/latest/download'
// ELF e_machine 编号,用于校验下载的 .node 确为目标架构
const ELF_MACHINE = {
x64: 62, // EM_X86_64
ia32: 3, // EM_386
arm64: 183 // EM_AARCH64
}
function assertElfMachine(filePath, targetArch) {
const fd = fs.openSync(filePath, 'r')
const header = Buffer.alloc(20)
try {
fs.readSync(fd, header, 0, 20, 0)
} finally {
fs.closeSync(fd)
}
if (header.toString('ascii', 0, 4) !== '\x7fELF') {
throw new Error(`not a valid ELF file: ${filePath}`)
}
const machine = header.readUInt16LE(18)
const expected = ELF_MACHINE[targetArch]
if (expected !== undefined && machine !== expected) {
throw new Error(
`architecture mismatch for "${filePath}": expected ${targetArch} (ELF machine ${expected}), got ${machine}`
)
}
}
function getSysproxyNodeName() {
// 检测是否为 musl 系统(与 src/native/sysproxy/index.js 保持一致)
const isMusl = (() => {
@@ -385,6 +430,10 @@ const resolveSysproxy = async () => {
}
await downloadFile(`${SYSPROXY_RS_URL_PREFIX}/${nodeName}`, targetPath)
// 校验 .node 确为目标架构 ELF避免交叉编译时把宿主机架构产物误打进包仅 Linux
if (platform === 'linux') {
assertElfMachine(targetPath, arch)
}
console.log(`[INFO]: ${nodeName} finished`)
}