fix(db): 禁止修改已发布迁移并分批兼容旧库
This commit is contained in:
@@ -7,6 +7,8 @@ import path from 'node:path'
|
||||
import { execFileSync } from 'node:child_process'
|
||||
import { fileURLToPath } from 'node:url'
|
||||
|
||||
import { changedPublishedMigrations } from '../src/db/migration-integrity.js'
|
||||
|
||||
const SCRIPT_DIR = path.dirname(fileURLToPath(import.meta.url))
|
||||
const BACKEND_ROOT = path.resolve(SCRIPT_DIR, '..')
|
||||
|
||||
@@ -92,11 +94,6 @@ const failures: string[] = []
|
||||
// 用「已发布基线」而不是 HEAD 做比较,是因为以 HEAD 为基线时,本次提交新增的
|
||||
// 迁移也会被算成历史迁移,合并提交后必然自相矛盾。
|
||||
const MIGRATION_BASELINE_REF = resolveMigrationBaselineRef()
|
||||
// 生产当前已发布到 119;120+ 仍允许在部署前重写。部署 120 后应将此值提升到 120。
|
||||
const PUBLISHED_MIGRATION_MAX_VERSION = Math.max(
|
||||
0,
|
||||
Math.trunc(Number(process.env.PUBLISHED_MIGRATION_MAX_VERSION) || 119),
|
||||
)
|
||||
|
||||
function resolveMigrationBaselineRef(): string | null {
|
||||
const candidates = [process.env.MIGRATION_BASELINE_REF, 'main', 'origin/main'].filter(
|
||||
@@ -124,25 +121,18 @@ for (const file of listSourceFiles(path.join(BACKEND_ROOT, 'src'))) {
|
||||
}
|
||||
}
|
||||
|
||||
// 已发布的历史迁移必须保持字节不变,所有结构或数据修复都必须新增迁移文件。
|
||||
// 基线分支中存在的所有迁移都必须保持字节不变;新增文件不受影响。
|
||||
// 这样保护范围会随着 main 的发布自动扩展,不再依赖手工维护版本号。
|
||||
if (!MIGRATION_BASELINE_REF) {
|
||||
console.warn('[check-sql] 未找到迁移基线分支(main / origin/main),跳过迁移字节检查')
|
||||
} else {
|
||||
try {
|
||||
const diffOutput = execFileSync(
|
||||
'git',
|
||||
['diff', '--name-status', MIGRATION_BASELINE_REF, '--', 'src/db/migrations'],
|
||||
['diff', '--name-status', '--no-renames', MIGRATION_BASELINE_REF, '--', 'src/db/migrations'],
|
||||
{ cwd: BACKEND_ROOT, encoding: 'utf8' },
|
||||
)
|
||||
const changedHistoricalMigrations = diffOutput
|
||||
.split('\n')
|
||||
.map((line) => line.trim().split(/\s+/))
|
||||
.filter(([status, file]) => {
|
||||
if (!status || !file?.endsWith('.sql') || status === 'A') return false
|
||||
const version = Number(path.basename(file).slice(0, 3))
|
||||
return Number.isFinite(version) && version <= PUBLISHED_MIGRATION_MAX_VERSION
|
||||
})
|
||||
.map(([status, file]) => `${status} ${file}`)
|
||||
const changedHistoricalMigrations = changedPublishedMigrations(diffOutput)
|
||||
if (changedHistoricalMigrations.length > 0) {
|
||||
failures.push(
|
||||
`已发布迁移文件不可修改(基线 ${MIGRATION_BASELINE_REF}): ${changedHistoricalMigrations.join(', ')}`,
|
||||
|
||||
Reference in New Issue
Block a user