From fa3b60777ccbaa835fd1a8f84b0fcc99bc2bb2af Mon Sep 17 00:00:00 2001 From: Linghong Date: Fri, 28 Aug 2026 04:11:15 +0000 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E7=94=9F=E4=BA=A7=E8=BF=90?= =?UTF-8?q?=E7=BB=B4=E9=97=A8=E7=A6=81=E6=A0=BC=E5=BC=8F=E8=AF=AF=E6=8A=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 生产运维门禁对备份安全片段启用空白与尾逗号容错匹配 补充开发运维文档中的门禁匹配规则说明 --- ...发运维】本地开发验证与生产运维-2026-05-15.md | 2 +- scripts/check-production-ops-guardrails.mjs | 18 +++++++++++++++++- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/docs/【开发运维】本地开发验证与生产运维-2026-05-15.md b/docs/【开发运维】本地开发验证与生产运维-2026-05-15.md index 064bae248..eaca00df3 100644 --- a/docs/【开发运维】本地开发验证与生产运维-2026-05-15.md +++ b/docs/【开发运维】本地开发验证与生产运维-2026-05-15.md @@ -368,7 +368,7 @@ npm run check:spacetime-schema `rustfmt.toml` 固定 Edition 2024 的格式化口径。Rust 源码统一使用 `cargo fmt --all --manifest-path server-rs/Cargo.toml` 格式化,并用 `npm run check:rustfmt` 做只读校验;Codex 提交前门禁、API 生产构建和 -SpacetimeDB module 生产构建都会执行同一检查,避免不同开发机或构建节点反复产生格式差异。Web 生产构建还会执行 production-ops、ESLint、主站与后台类型检查,以及排除已下线旧玩法后的当前 Vitest;API 生产构建追加 production-ops、DDD/schema/runtime-access 和 api-server 全 target 编译检查;SpacetimeDB module 生产构建追加 production-ops、DDD/schema/runtime-access 和管理员 procedure smoke。上述门禁由 `npm run check:production-ops` 反查,不能只保留在本地说明中。 +SpacetimeDB module 生产构建都会执行同一检查,避免不同开发机或构建节点反复产生格式差异。Web 生产构建还会执行 production-ops、ESLint、主站与后台类型检查,以及排除已下线旧玩法后的当前 Vitest;API 生产构建追加 production-ops、DDD/schema/runtime-access 和 api-server 全 target 编译检查;SpacetimeDB module 生产构建追加 production-ops、DDD/schema/runtime-access 和管理员 procedure smoke。上述门禁由 `npm run check:production-ops` 反查,不能只保留在本地说明中。对需要跨格式保持稳定的脚本片段,门禁按去除空白后的源码片段匹配,避免仅因换行或格式化差异误报。 ## 前端改动验收 diff --git a/scripts/check-production-ops-guardrails.mjs b/scripts/check-production-ops-guardrails.mjs index bacd4b949..15fa3b1ad 100644 --- a/scripts/check-production-ops-guardrails.mjs +++ b/scripts/check-production-ops-guardrails.mjs @@ -973,12 +973,14 @@ const checks = [ { file: 'scripts/database-backup-to-oss.mjs', includes: 'assertSufficientWorkDirSpace({dataDir, workDir, args, env})', + normalizeWhitespace: true, reason: '生产冷备份必须先做工作目录剩余空间预检,避免停库后写满磁盘。', }, { file: 'scripts/database-backup-to-oss.mjs', includes: 'restoreServicesAfterBackup({stopService, serviceStopped, restartServicesAfter, stopMarkerPath})', + normalizeWhitespace: true, reason: '生产冷备份打包失败时也必须恢复 SpacetimeDB 及依赖服务。', }, { @@ -7504,9 +7506,23 @@ const databaseTargetSourceStashes = [ let failed = false; +function includesGuardrail(content, check) { + if (!check.includes) { + return true; + } + if (!check.normalizeWhitespace) { + return content.includes(check.includes); + } + const normalizeSourceFragment = (value) => + value.replace(/\s+/gu, '').replace(/,([})])/gu, '$1'); + const normalizedContent = normalizeSourceFragment(content); + const normalizedExpected = normalizeSourceFragment(check.includes); + return normalizedContent.includes(normalizedExpected); +} + for (const check of checks) { const content = readFileSync(check.file, 'utf8'); - if (check.includes && !content.includes(check.includes)) { + if (!includesGuardrail(content, check)) { failed = true; console.error( `[check:production-ops] ${check.file} 缺少 ${check.includes}。${check.reason}`,