flnxi-Wu/scripts/__tests__/deploy-registry-script.test.ts
2026-06-01 17:06:57 +08:00

85 lines
4.7 KiB
TypeScript
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 fs from 'fs'
import path from 'path'
describe('deploy-registry.ps1', () => {
const script = fs.readFileSync(
path.join(process.cwd(), 'deploy-registry.ps1'),
'utf8'
)
it('远程部署默认包含升级前数据库、对象存储和 .env 备份', () => {
expect(script).toContain('[switch]$NoRemoteDbBackup')
expect(script).toContain('[switch]$NoRemoteObjectStorageBackup')
expect(script).toContain('[switch]$ExternalDataBackupConfirmed')
expect(script).toContain('[string]$RemoteBackupHelperImage = "busybox:1.36"')
expect(script).toContain('env_backup="$backup_dir/.env.before-upgrade"')
expect(script).toContain('enter_maintenance_for_backup')
expect(script).toContain('APP_STOPPED_FOR_BACKUP.txt')
expect(script).toContain("docker compose -f \"$compose_file\" exec -T postgres sh -c 'pg_dump")
expect(script).toContain('test -s "$db_backup"')
expect(script).toContain('backup_minio_volume()')
expect(script).toContain('docker volume inspect "$minio_volume_name"')
expect(script).toContain('tar -czf /backup/minio-data.tar.gz')
expect(script).toContain('rm -rf /target/* /target/.[!.]* /target/..?*')
expect(script).toContain('OBJECT_STORAGE_EXTERNAL.txt')
expect(script).toContain('backup_minio_volume')
expect(script).toContain('is_external_database()')
expect(script).toContain('is_external_object_storage()')
expect(script).toContain('EXTERNAL_DATABASE_BACKUP_REQUIRED.txt')
expect(script).toContain('EXTERNAL_OBJECT_STORAGE_BACKUP_REQUIRED.txt')
expect(script).toContain('external_data_backup_confirmed=$externalDataBackupConfirmed')
expect(script).toContain('外部数据库备份未确认,已中止升级')
expect(script).toContain('外部对象存储备份未确认,已中止升级')
})
it('远程部署失败时默认会恢复旧 APP_IMAGE 或旧容器镜像', () => {
expect(script).toContain('[switch]$NoRollback')
expect(script).toContain('rollback()')
expect(script).toContain('trap rollback ERR')
expect(script.indexOf('trap rollback ERR')).toBeLessThan(script.indexOf('upsert_env APP_IMAGE'))
expect(script).toContain('write_deploy_context')
expect(script).toContain('LAST_DEPLOY_CONTEXT.env')
expect(script).toContain('rollback_image="$old_container_image"')
expect(script).toContain('docker compose -f "$compose_file" up -d --no-deps --pull never --force-recreate "$compose_service" || true')
expect(script).toContain('自动回滚只恢复应用镜像和 .env,不自动恢复数据库')
})
it('本地最终健康检查失败时会触发远程回滚', () => {
expect(script).toContain('function New-RemoteRollbackScript')
expect(script).toContain('应用健康检查失败,尝试远程回滚')
expect(script).toContain('New-RemoteRollbackScript -Reason $healthError')
expect(script).toContain('Invoke-RemoteCommand -Command $rollbackScript -NoRegistryPasswordInput')
expect(script).toContain('本地最终健康检查失败,准备远程回滚')
expect(script).toContain('cp "$env_backup" .env')
expect(script).toContain('docker compose -f "`${compose_file:-docker-compose.prod.yml}" up -d --no-deps --pull never --force-recreate "`${compose_service:-app}"')
})
it('部署后校验运行镜像、版本文件和数据库迁移状态', () => {
expect(script).toContain('verify_running_image')
expect(script).toContain('actual_image="$(docker inspect "$container_id" --format')
expect(script).toContain('运行镜像不匹配')
expect(script).toContain('运行版本不匹配')
expect(script).toContain('npx prisma migrate status --schema=prisma/schema.prisma')
})
it('远程健康检查使用可配置超时和最终访问入口', () => {
expect(script).toContain('[int]$RemoteHealthTimeoutSec = 120')
expect(script).toContain('$baseUrl = if (-not [string]::IsNullOrWhiteSpace($AppPublicUrl))')
expect(script).toContain('$deadline = (Get-Date).AddSeconds($RemoteHealthTimeoutSec)')
expect(script).toContain('健康检查没有在 $RemoteHealthTimeoutSec 秒内通过')
expect(script).not.toContain('健康检查没有在 60 秒内通过')
})
it('运行时镜像同步包含对象存储备份 helper', () => {
expect(script).toContain('Source = "busybox:1.36"')
expect(script).toContain('Repository = "runtime/busybox"')
expect(script).toContain('Tag = "1.36"')
})
it('远端 shell 变量应以单引号字符串保留,避免被 PowerShell 提前展开', () => {
expect(script).toContain('$lines.Add(\'docker compose -f "$compose_file" up -d --pull never\')')
expect(script).toContain('$lines.Add(\'docker compose -f "$compose_file" ps\')')
expect(script).not.toContain('$lines.Add("docker compose -f `"$compose_file`"')
})
})