feat: 支持前端独立打包与测试服Docker发布

This commit is contained in:
Yvan
2026-11-05 11:54:02 +08:00
parent c7d4ffbd9c
commit c4acb91c27
16 changed files with 702 additions and 1 deletions
+59
View File
@@ -0,0 +1,59 @@
import crypto from 'node:crypto'
import path from 'node:path'
import { fileURLToPath } from 'node:url'
import { options, packageRelease, inspectPackage, deploymentTarget, shellQuote, run, fail } from './release.mjs'
export const installScript = `set -euo pipefail
BASE_DIR=$(cd -- "$1" && pwd -P)
ARCHIVE=$2
EXPECTED=$3
TAG=$4
MODE=$5
RELEASE="$BASE_DIR/frontend-releases/$TAG"
STAGING=''
cleanup() {
rm -f -- "$ARCHIVE"
if [[ -n "$STAGING" && "$STAGING" == "$BASE_DIR/frontend-releases/.incoming-"* ]]; then rm -rf -- "$STAGING"; fi
}
trap cleanup EXIT
exec 8>"$BASE_DIR/frontend-releases/.install-$TAG.lock"
flock -x 8
printf '%s %s\\n' "$EXPECTED" "$ARCHIVE" | sha256sum -c -
if [[ -e "$RELEASE" ]]; then
[[ -f "$RELEASE/package.sha256" && "$(cat "$RELEASE/package.sha256")" == "$EXPECTED" ]] || { echo 'Existing release has a different checksum' >&2; exit 1; }
else
STAGING=$(mktemp -d "$BASE_DIR/frontend-releases/.incoming-$TAG.XXXXXX")
tar --no-same-owner -xzf "$ARCHIVE" -C "$STAGING"
printf '%s\\n' "$EXPECTED" > "$STAGING/package.sha256"
mv -T -- "$STAGING" "$RELEASE"
STAGING=''
fi
SW_DEPLOY_BASE="$BASE_DIR" bash "$RELEASE/deploy.sh" "$TAG" "$MODE"
`
function main() {
const args = options({
archive: { type: 'string' }, tag: { type: 'string' }, 'source-ref': { type: 'string' }, 'skip-install': { type: 'boolean' },
host: { type: 'string' }, user: { type: 'string' }, port: { type: 'string' }, identity: { type: 'string' }, directory: { type: 'string' }, 'build-only': { type: 'boolean' }
})
if (args.help) {
console.log('pnpm deploy:test [--archive FILE.tar.gz] [--tag VERSION] [--build-only] [--host 192.168.2.226] [--user root] [--port 22] [--identity SSH_KEY] [--directory /www/wwwroot/sw2.fuhua91.com]\n不指定 --archive 时先独立构建前端;--build-only 仅在服务器构建并预检,不替换当前容器。')
return
}
if (args.archive && (args.tag || args['source-ref'] || args['skip-install'])) throw new Error('--archive 复用现有包,不能再指定构建参数')
const target = deploymentTarget(args)
const release = args.archive ? inspectPackage(args.archive) : inspectPackage(packageRelease(args).archive)
const identity = args.identity ? ['-i', path.resolve(args.identity)] : []
const ssh = ['-o', 'BatchMode=yes', '-o', 'ConnectTimeout=10', '-p', target.port, ...identity, target.remote]
const uploads = `${target.base}/frontend-releases`
const uploaded = `${uploads}/.upload-${release.info.version}-${crypto.randomBytes(6).toString('hex')}.tar.gz`
run('ssh', [...ssh, `test -d ${shellQuote(target.base)} && test -w ${shellQuote(target.base)} && mkdir -p ${shellQuote(uploads)}`])
run('scp', ['-o', 'BatchMode=yes', '-o', 'ConnectTimeout=10', '-P', target.port, ...identity, release.archive, `${target.remote}:${uploaded}`])
const parameters = [target.base, uploaded, release.checksum, release.info.version, args['build-only'] ? '--build-only' : '']
run('ssh', [...ssh, `bash -s -- ${parameters.map(shellQuote).join(' ')}`], { stdio: ['pipe', 'inherit', 'inherit'], input: installScript })
console.log(args['build-only'] ? `预检通过:${release.info.version},当前前端未替换` : `前端发布完成:${release.info.version};http://sw2.fuhua91.com`)
}
if (process.argv[1] && path.resolve(process.argv[1]) === fileURLToPath(import.meta.url)) {
try { main() } catch (error) { fail(error) }
}