windows release支持

This commit is contained in:
yonglin
2026-09-17 16:16:44 +08:00
parent 36d60bab1e
commit b9098ece5c
6 changed files with 100 additions and 62 deletions
+8
View File
@@ -146,6 +146,14 @@ const script = `(async () => {
report.validationRejected = true
}
// --- local PTY -------------------------------------------------------
// This catches platform-specific shell selection and packaged node-pty
// failures, neither of which the repository tests can exercise.
const local = await window.nexusterm.session.openLocal()
if (!local.ok) throw new Error(local.message)
report.localShell = true
await window.nexusterm.session.close(local.sessionId)
// --- clean up --------------------------------------------------------
tree = await api.list()
for (const node of tree) {
+29 -45
View File
@@ -1,6 +1,6 @@
// Checks that a built package is actually runnable, rather than merely built.
//
// node scripts/verify-package.mjs [path/to/NexusTerm-*.AppImage]
// node scripts/verify-package.mjs [path/to/AppImage-or-unpacked-directory]
//
// Native modules cannot be loaded from inside an asar archive, so they have to
// be unpacked beside it — and when that goes wrong the app still builds, still
@@ -14,35 +14,30 @@ import { existsSync, mkdtempSync, readdirSync, rmSync, statSync } from 'node:fs'
import { tmpdir } from 'node:os'
import { join, resolve } from 'node:path'
const EXPECTED_NATIVE = [
'node_modules/better-sqlite3/prebuilds/linux-x64.node',
'node_modules/node-pty/build/Release/pty.node',
]
/**
* Other-platform *binaries*, not everything with a platform in its name.
*
* better-sqlite3 also ships `lib/darwin-arm64.js` and friends — small loader
* shims that are part of the library on every platform. Flagging those would
* make this check cry wolf, and a check that cries wolf gets ignored.
*/
const FORBIDDEN = [
/win32-.*\.node$/,
/win32-.*\.dll$/,
/darwin-.*\.node$/,
/darwin-.*spawn-helper$/,
/linuxmusl-.*\.node$/,
/linux-arm64.*\.node$/,
]
const arch = process.arch
const EXPECTED_NATIVE =
process.platform === 'win32'
? [
`node_modules/better-sqlite3/prebuilds/win32-${arch}.node`,
`node_modules/node-pty/prebuilds/win32-${arch}/pty.node`,
`node_modules/node-pty/prebuilds/win32-${arch}/conpty.node`,
`node_modules/node-pty/prebuilds/win32-${arch}/winpty-agent.exe`,
]
: [
`node_modules/better-sqlite3/prebuilds/linux-${arch}.node`,
'node_modules/node-pty/build/Release/pty.node',
]
function fail(message) {
console.error(`\n ✗ ${message}`)
process.exitCode = 1
}
function findDefaultAppImage() {
function findDefaultPackage() {
const dir = resolve('release')
if (!existsSync(dir)) return null
const unpacked = join(dir, 'win-unpacked')
if (process.platform === 'win32' && existsSync(unpacked)) return unpacked
const name = readdirSync(dir).find((f) => f.endsWith('.AppImage'))
return name ? join(dir, name) : null
}
@@ -56,13 +51,13 @@ function walk(dir, out = []) {
return out
}
const appImage = process.argv[2] ? resolve(process.argv[2]) : findDefaultAppImage()
if (!appImage || !existsSync(appImage)) {
fail('no AppImage found — build one first with `npx electron-builder --linux`')
const packagePath = process.argv[2] ? resolve(process.argv[2]) : findDefaultPackage()
if (!packagePath || !existsSync(packagePath)) {
fail('no unpacked package found — build one first with `npm run dist` or `npm run dist:win`')
process.exit(1)
}
console.log(` inspecting ${appImage}`)
console.log(` inspecting ${packagePath}`)
const workdir = mkdtempSync(join(tmpdir(), 'nexusterm-verify-'))
@@ -71,12 +66,12 @@ try {
// form matters because `electron-builder --dir` is what you iterate against —
// it skips the squashfs and compression steps, which dominate a full build.
let resources
if (statSync(appImage).isDirectory()) {
resources = join(appImage, 'resources')
if (statSync(packagePath).isDirectory()) {
resources = join(packagePath, 'resources')
} else {
// `--appimage-extract` writes ./squashfs-root relative to the working
// directory, so this has to run from inside the scratch dir.
execFileSync(appImage, ['--appimage-extract'], {
execFileSync(packagePath, ['--appimage-extract'], {
cwd: workdir,
stdio: 'ignore',
timeout: 180_000,
@@ -92,7 +87,7 @@ try {
const files = walk(unpacked)
for (const expected of EXPECTED_NATIVE) {
const found = files.some((f) => f.endsWith(expected))
const found = files.some((f) => f.replaceAll('\\', '/').endsWith(expected))
if (found) console.log(` ✓ ${expected}`)
else fail(`${expected} is not unpacked — this module will fail to load at runtime`)
}
@@ -102,22 +97,11 @@ try {
// a JS implementation silently — so nothing would ever report it.
const sshCrypto = files.filter((f) => f.endsWith('sshcrypto.node'))
if (sshCrypto.length > 0) console.log(` ✓ ssh2 sshcrypto.node (${sshCrypto.length})`)
else fail('ssh2 sshcrypto.node is missing')
else if (process.platform === 'win32') {
console.log(' ! ssh2 sshcrypto.node is absent; ssh2 will use its JavaScript fallback')
} else fail('ssh2 sshcrypto.node is missing')
const strays = files.filter((f) => FORBIDDEN.some((p) => p.test(f)))
if (strays.length === 0) {
console.log(' ✓ no other-platform binaries')
} else {
// A warning rather than a failure: these are dead weight, not a defect.
console.log(` ! ${strays.length} other-platform file(s) shipped:`)
for (const stray of strays.slice(0, 5)) {
console.log(` ${stray.slice(unpacked.length + 1)}`)
}
}
const size = Number(
execFileSync('du', ['-sb', unpacked], { encoding: 'utf8' }).split('\t')[0],
)
const size = files.reduce((total, file) => total + statSync(file).size, 0)
console.log(` · unpacked: ${(size / 1024 / 1024).toFixed(1)} MB`)
const asar = join(resources, 'app.asar')