feat(acceptance): 建立同构验收与弹性容量体系

实现本地三节点 K3s 同构环境、脱敏生产快照、Gemini 图片和多参考图视频协议模拟、统一验收报告及故障注入。\n\n新增 Worker 容量控制器、资源与连接预算、任务恢复保护,并将生产验收拆分为 validation 执行和人工 CAS 放量。\n\n验证包括 Go 全量测试、PostgreSQL HTTP 集成测试、go vet、OpenAPI、ShellCheck、前端检查、迁移及发布脚本测试。
This commit is contained in:
2026-07-31 18:02:24 +08:00
parent 93d36d0e55
commit e05922b0f4
94 changed files with 12379 additions and 826 deletions
+55
View File
@@ -32,6 +32,7 @@ function releaseIntegrity(manifest) {
const payload = structuredClone(manifest)
delete payload.integrity
delete payload.deployment
delete payload.certification
return createHash('sha256').update(JSON.stringify(payload)).digest('hex')
}
@@ -58,6 +59,8 @@ function validate(manifest) {
'migrationsChanged', 'images', 'smoke', 'integrity',
]
if (manifest.deployment !== undefined) rootKeys.push('deployment')
if (manifest.certification !== undefined) rootKeys.push('certification')
if (manifest.migrationVersion !== undefined) rootKeys.push('migrationVersion')
requireExactKeys(manifest, rootKeys, 'manifest')
if (manifest.schemaVersion !== 1) fail('schemaVersion must be 1')
if (!shaPattern.test(manifest.sourceSha || '')) fail('sourceSha must be a full lowercase Git SHA')
@@ -84,6 +87,10 @@ function validate(manifest) {
if (manifest.migrationsChanged && !manifest.components.includes('api')) {
fail('migration changes require the api component')
}
if (manifest.migrationVersion !== undefined &&
!/^\d{4}_[a-z0-9][a-z0-9_]*$/.test(manifest.migrationVersion)) {
fail('migrationVersion must identify the latest migration without .sql')
}
if (!manifest.images || typeof manifest.images !== 'object') fail('images must be an object')
requireExactKeys(manifest.images, ['api', 'web'], 'images')
for (const component of allowedComponents) {
@@ -126,6 +133,28 @@ function validate(manifest) {
fail('deployment record is invalid')
}
}
if (manifest.certification !== undefined) {
if (!manifest.certification || typeof manifest.certification !== 'object') {
fail('certification must be an object')
}
requireExactKeys(manifest.certification, [
'status', 'runId', 'certifiedAt', 'configHash', 'capacityProfile',
'workerInstanceSlots', 'workerMaxReplicasNingbo', 'workerMaxReplicasHongkong',
], 'certification')
if (manifest.certification.status !== 'passed' ||
!/^[0-9a-f-]{36}$/.test(manifest.certification.runId || '') ||
!Number.isFinite(Date.parse(manifest.certification.certifiedAt)) ||
!/^[0-9a-f]{64}$/.test(manifest.certification.configHash || '') ||
!['P24', 'P28', 'P32'].includes(manifest.certification.capacityProfile) ||
!Number.isInteger(manifest.certification.workerInstanceSlots) ||
manifest.certification.workerInstanceSlots < 1 ||
!Number.isInteger(manifest.certification.workerMaxReplicasNingbo) ||
manifest.certification.workerMaxReplicasNingbo < 1 ||
!Number.isInteger(manifest.certification.workerMaxReplicasHongkong) ||
manifest.certification.workerMaxReplicasHongkong < 1) {
fail('certification record is invalid')
}
}
const forbiddenKey = /(password|secret|token|credential|private.?key)/i
const visit = (value, path = '') => {
@@ -166,6 +195,7 @@ if (command === 'create') {
targetPlatform: 'linux/amd64',
components,
migrationsChanged,
migrationVersion: requireEnv('RELEASE_MIGRATION_VERSION', /^\d{4}_[a-z0-9][a-z0-9_]*$/),
images: {
api: requireEnv('RELEASE_API_IMAGE', digestImagePattern),
web: requireEnv('RELEASE_WEB_IMAGE', digestImagePattern),
@@ -206,6 +236,31 @@ if (command === 'record-deployment') {
process.exit(0)
}
if (command === 'record-certification') {
if (!field) fail('record-certification requires an output path')
const certifiedAt = requireEnv('RELEASE_CERTIFIED_AT')
const runId = requireEnv('RELEASE_ACCEPTANCE_RUN_ID', /^[0-9a-f-]{36}$/)
const configHash = requireEnv('RELEASE_CONFIG_HASH', /^[0-9a-f]{64}$/)
const capacityProfile = requireEnv('RELEASE_CAPACITY_PROFILE', /^P(?:24|28|32)$/)
const workerInstanceSlots = Number(process.env.RELEASE_WORKER_INSTANCE_SLOTS || '')
const workerMaxReplicasNingbo = Number(process.env.RELEASE_WORKER_MAX_REPLICAS_NINGBO || '')
const workerMaxReplicasHongkong = Number(process.env.RELEASE_WORKER_MAX_REPLICAS_HONGKONG || '')
manifest.certification = {
status: 'passed',
runId,
certifiedAt,
configHash,
capacityProfile,
workerInstanceSlots,
workerMaxReplicasNingbo,
workerMaxReplicasHongkong,
}
validate(manifest)
writeFileSync(field, `${JSON.stringify(manifest, null, 2)}\n`, { flag: 'wx', mode: 0o600 })
console.log(`release_manifest=CERTIFIED release=${manifest.releaseId} run=${runId}`)
process.exit(0)
}
if (command === 'validate') {
const digest = createHash('sha256').update(readFileSync(path)).digest('hex')
console.log(`release_manifest=PASS release=${manifest.releaseId} sha256=${digest}`)