mirror of
https://github.com/zhw2590582/ArtPlayer.git
synced 2026-10-17 18:11:20 -08:00
test(release): [REL-04] checkpoint renamed rollback and mainline conflict recovery
This commit is contained in:
1 parent
aa29dc9212
commit
d0c33f6258
14 files changed
+1718
-8
No files matched your search
@@ -0,0 +1,75 @@
|
||||
import assert from 'node:assert/strict'
|
||||
import fs from 'node:fs'
|
||||
import path from 'node:path'
|
||||
import process from 'node:process'
|
||||
import { fileURLToPath } from 'node:url'
|
||||
import { ensureArchive, readMember } from './releases.mjs'
|
||||
|
||||
const root = fileURLToPath(new URL('../../', import.meta.url))
|
||||
assert(['--write', '--check'].includes(process.argv[2]) && process.argv.length === 3, 'Use --write or --check')
|
||||
const read = file => JSON.parse(fs.readFileSync(path.join(root, file), 'utf8'))
|
||||
const ledger = read('refactor/release-ledger.json')
|
||||
const rows = []
|
||||
for (const pkg of ledger.packages) {
|
||||
const baseline = read(pkg.history.file)
|
||||
const release = pkg.history.selector?.split('.').reduce((value, key) => value?.[key], baseline)
|
||||
const current = read(`packages/${pkg.name}/package.json`)
|
||||
const row = { name: pkg.name, targetVersion: pkg.targetVersion, distribution: pkg.distribution, history: pkg.history, currentDependencies: current.dependencies || {}, currentPeers: current.peerDependencies || {}, currentOptionalDependencies: current.optionalDependencies || {} }
|
||||
if (pkg.distribution === 'site') {
|
||||
rows.push({ ...row, restore: 'Previously verified Pages artifact, exact source SHA and URL map; npm rollback does not apply.', status: 'previous-deployment-artifact-required', evidence: 'refactor/pages-deployment.md' })
|
||||
continue
|
||||
}
|
||||
if (pkg.distribution === 'recovered-npm') {
|
||||
assert(release, 'Missing recovered history')
|
||||
rows.push({ ...row, restore: 'No intact historical npm tarball. Preserve a complete pre-upgrade application/artifact snapshot and verify it before any candidate deployment.', status: 'complete-rollback-artifact-required', evidence: pkg.history.file })
|
||||
continue
|
||||
}
|
||||
assert(release?.integrity && release.sha256 && release.files, `Missing frozen rollback archive: ${pkg.name}`)
|
||||
const archive = await ensureArchive(release)
|
||||
const manifest = JSON.parse(readMember(archive, 'package/package.json'))
|
||||
assert.equal(manifest.name, release.name)
|
||||
assert.equal(manifest.version, release.version)
|
||||
rows.push({
|
||||
...row,
|
||||
previous: { name: release.name, version: release.version, tarball: release.tarball, integrity: release.integrity, sha256: release.sha256, memberCount: Object.keys(release.files).length, dependencies: manifest.dependencies || {}, peerDependencies: manifest.peerDependencies || {}, optionalDependencies: manifest.optionalDependencies || {} },
|
||||
exactDependency: { [release.name]: release.version },
|
||||
restore: pkg.distribution === 'renamed-npm'
|
||||
? 'Restore application import code, old package name and saved lock together; npm alias alone does not restore the old export/helper surface.'
|
||||
: 'Restore the saved application manifest/lock and matching artifacts, then frozen-install the previous exact version with its tested core/plugin combination.',
|
||||
status: 'archive-verified-batch-rehearsal-required',
|
||||
})
|
||||
}
|
||||
assert.equal(rows.length, 22)
|
||||
const result = { task: 'REL-04', source: 'refactor/release-ledger.json and frozen historical archives', registryAvailabilityRefreshed: false, mutableTagPolicy: 'Use exact versions and saved lock/artifact hashes. No latest/next/rollback tag is assumed or changed.', packages: rows }
|
||||
const json = `${JSON.stringify(result, null, 2)}\n`
|
||||
const dependencies = value => Object.entries(value).map(([name, version]) => `${name}@${version}`).join(', ') || '无声明'
|
||||
const lines = [
|
||||
'# 逐包回退清单',
|
||||
'',
|
||||
'由 `node refactor/scripts/rollback-inventory.mjs --write` 生成;`--check` 校验同步并复核冻结 tarball 完整性。',
|
||||
'',
|
||||
'本表核对 20 份完整历史 archive 的 SHA-512/SHA-256 和 manifest。它不表示当前 registry 可用,',
|
||||
'也不表示全部包的实际回退已验收。机器清单同时保存旧/新 dependencies、peerDependencies 与精确 integrity。',
|
||||
'',
|
||||
'| 当前包 | 目标版本 | 恢复版本/对象 | 旧包运行依赖 | 恢复状态 |',
|
||||
'| --- | --- | --- | --- | --- |',
|
||||
...rows.map(row => `| ${row.name} | ${row.targetVersion} | ${row.previous ? `${row.previous.name}@${row.previous.version}` : row.distribution === 'site' ? '已验证 Pages 产物' : '完整旧产物尚缺'} | ${row.previous ? dependencies(row.previous.dependencies) : '见原有门槛'} | ${row.status} |`),
|
||||
'',
|
||||
'每包优先恢复升级前已验证的应用代码、package.json 和 yarn.lock,再执行 `yarn install --frozen-lockfile`;',
|
||||
'离线恢复还需保存所需 tarball/依赖缓存。单独把版本改回去并重新解析依赖,不能替代已测试锁文件。',
|
||||
'外部播放器 SDK、worker/WASM、远端媒体和平台能力也要恢复对应配置,npm 依赖表不覆盖它们。',
|
||||
'',
|
||||
'iframe 必须同步恢复旧包名、CommonJS `.default`、helper 路径和应用代码;不将 npm alias 当作兼容门面。',
|
||||
'Thumbnail 完整原包缺失以及站点部署恢复仍是发布门槛。正式每批重新绑定候选和回退内容,不能直接复用早期演练结果。',
|
||||
'',
|
||||
'来源:[机器清单](baselines/rollback-inventory.json)、[维护入口](rollback-rehearsal.md)、[发布台账](release-ledger.md)。',
|
||||
'',
|
||||
]
|
||||
const markdown = lines.join('\n')
|
||||
for (const [file, contents] of [['refactor/baselines/rollback-inventory.json', json], ['refactor/rollback-inventory.md', markdown]]) {
|
||||
if (process.argv[2] === '--write')
|
||||
fs.writeFileSync(path.join(root, file), contents)
|
||||
else
|
||||
assert.equal(fs.readFileSync(path.join(root, file), 'utf8').replaceAll('\r\n', '\n'), contents, `Stale rollback inventory: ${file}`)
|
||||
}
|
||||
console.log(`Rollback inventory: ${rows.length} packages, ${rows.filter(row => row.previous).length} verified historical archives, remaining batch gates retained`)
|
||||
Reference in new issue
Block a user