Files
qinglong/cli/scripts/build.cjs
T
whyour 9bd9306455 feat: ship verified platform bundles for online and offline upgrades
Build complete tar.gz packages with production dependencies for 13 Linux
architecture/libc targets, including ARMv6 hard-float glibc 2.31. Retain the
existing Node runtime and share payload validation between panel downloads,
manual offline upgrades, and clean offline installs.

Verify immutable archive hashes, every payload file/link/mode, lockfiles and
native dependencies before publishing readiness. Apply on explicit restart,
verify the running build, and restore prior files/services on failure. Keep
ARMv6 archive workers interpreted and allow slow worker/startup readiness.

Synchronize prepared jobs when Bash or the operational CLI applies them;
verify the target build before committing and preserve recovery semantics.
Keep old self-contained Bash reloads working without panel job dependencies.

Validation: 770 backend/frontend tests passed (8 platform skips), 293 CLI
tests passed (5 platform skips), targeted reload/rollback regressions,
backend/CLI type checks, and standalone installer build.
2026-10-18 11:43:21 +08:00

99 lines
3.1 KiB
JavaScript

const fs = require('node:fs');
const path = require('node:path');
const { execFileSync } = require('node:child_process');
const root = path.resolve(__dirname, '..');
// Deleted commands must not survive incremental builds or npm prepack.
fs.rmSync(path.join(root, 'dist'), { recursive: true, force: true });
execFileSync(
process.execPath,
[
require.resolve('typescript/bin/tsc'),
'-p',
path.join(root, 'tsconfig.json'),
],
{ stdio: 'inherit' },
);
fs.copyFileSync(
path.join(root, 'src/internal/maintenance/upgradeArtifacts.cjs'),
path.join(root, 'dist/internal/maintenance/upgradeArtifacts.cjs'),
);
fs.copyFileSync(
path.join(root, 'src/internal/maintenance/panelUpgrade.cjs'),
path.join(root, 'dist/internal/maintenance/panelUpgrade.cjs'),
);
// The operational CLI may live outside the panel and has no panel node_modules.
require('esbuild').buildSync({
entryPoints: [path.join(root, 'src/internal/maintenance/platformBundle.cjs')],
outfile: path.join(root, 'dist/internal/maintenance/platformBundle.cjs'),
bundle: true,
platform: 'node',
format: 'cjs',
target: 'node20',
minify: true,
legalComments: 'inline',
});
require('esbuild').buildSync({
entryPoints: [path.join(root, 'src/shared/cli/commander.ts')],
outfile: path.join(root, 'dist/shared/cli/commander.js'),
bundle: true,
platform: 'node',
format: 'cjs',
target: 'node22',
minify: true,
sourcemap: true,
legalComments: 'inline',
});
const license = path.join(
path.dirname(require.resolve('commander')),
'LICENSE',
);
fs.mkdirSync(path.join(root, 'dist/licenses'), { recursive: true });
fs.copyFileSync(license, path.join(root, 'dist/licenses/commander-LICENSE'));
// The public npm artifact must not contain or import local operational code.
const remote = require('esbuild').buildSync({
entryPoints: [path.join(root, 'src/entrypoints/remote.ts')],
outfile: path.join(root, 'dist/npm/ql.js'),
bundle: true,
platform: 'node',
format: 'cjs',
target: 'node22',
minify: true,
sourcemap: true,
legalComments: 'inline',
metafile: true,
});
for (const input of Object.keys(remote.metafile.inputs)) {
if (
/(?:^|[\\/])src[\\/](?:internal|compatibility|developer)[\\/]/.test(input)
)
throw new Error(
'Local implementation leaked into remote npm bundle: ' + input,
);
}
fs.copyFileSync(license, path.join(root, 'dist/npm/commander-LICENSE'));
// Keep existing panel/cron executable paths stable after source reorganization.
for (const [name, entry] of Object.entries(require('./entrypoints.cjs'))) {
const target = path.join(root, 'dist', name);
let relative = path
.relative(path.dirname(target), path.join(root, 'dist', entry.module))
.split(path.sep)
.join('/');
if (!relative.startsWith('.')) relative = './' + relative;
const run = entry.method
? `
if (require.main === module) void entry.${entry.method}().then(code => { process.exitCode = code; });`
: '';
fs.mkdirSync(path.dirname(target), { recursive: true });
fs.writeFileSync(
target,
'#!/usr/bin/env node\nconst entry = require(' +
JSON.stringify(relative) +
');\nmodule.exports = entry;' +
run +
'\n',
{ mode: 0o755 },
);
}