Files
kra-new/web/deploy/deploy-test.mjs
T

70 lines
4.2 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import crypto from 'node:crypto'
import path from 'node:path'
import fs from 'node:fs'
import { fileURLToPath } from 'node:url'
import { options, packageRelease, inspectPackage, deploymentTarget, shellQuote, frontendRoot, frontendImage, validTag, 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' },
'image-tag': { type: 'string' },
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 | --image-tag VERSION] [--tag VERSION] [--build-only] [--host 192.168.2.226] [--user root] [--port 22] [--identity SSH_KEY] [--directory /www/wwwroot/sw2.fuhua91.com]\n默认打包并在服务器构建、推送 Harbor 后部署;--image-tag 直接拉取已有 Harbor 镜像;--build-only 仅预检,不替换当前容器。')
return
}
if (args.archive && (args.tag || args['source-ref'] || args['skip-install'])) throw new Error('--archive 复用现有包,不能再指定构建参数')
if (args['image-tag'] && (args.archive || args.tag || args['source-ref'] || args['skip-install'])) throw new Error('--image-tag 直接使用 Harbor 镜像,不能同时指定发布包或构建参数')
const target = deploymentTarget(args)
const identity = args.identity ? ['-i', path.resolve(args.identity)] : []
const ssh = ['-o', 'BatchMode=yes', '-o', 'ConnectTimeout=10', '-p', target.port, ...identity, target.remote]
if (args['image-tag']) {
const tag = validTag(args['image-tag'])
const command = `SW_DEPLOY_BASE=${shellQuote(target.base)} bash -s -- ${shellQuote(tag)} --pull-only${args['build-only'] ? ' --build-only' : ''}`
run('ssh', [...ssh, command], { stdio: ['pipe', 'inherit', 'inherit'], input: fs.readFileSync(path.join(frontendRoot, 'deploy/deploy.sh'), 'utf8').replaceAll('\r\n', '\n') })
console.log(`${args['build-only'] ? 'Harbor 镜像预检通过' : 'Harbor 镜像部署完成'}:${frontendImage(tag)}`)
return
}
const release = args.archive ? inspectPackage(args.archive) : inspectPackage(packageRelease(args).archive)
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) }
}