86 lines
2.6 KiB
JavaScript
86 lines
2.6 KiB
JavaScript
|
|
#!/usr/bin/env node
|
|||
|
|
/**
|
|||
|
|
* Feature-flag 质量门控促升补丁 — 2026-04-25
|
|||
|
|
*
|
|||
|
|
* 目标: 3 个 warn 态钩子提前升 enforce
|
|||
|
|
* - code-quality-gate
|
|||
|
|
* - post-edit-quality-check
|
|||
|
|
* - build-outcome-tracker
|
|||
|
|
*
|
|||
|
|
* 依据: 2026-04-25 四维度评审 (production-reviewer / red-team-logic /
|
|||
|
|
* red-team-attacker / delivery-quality-assessor) 一致建议
|
|||
|
|
* "先走已有路径性价比最高";且三个 flag 自 2026-03-xx 起已在
|
|||
|
|
* warn 态运行 30+ 天,实际数据已满足升级前提。
|
|||
|
|
*
|
|||
|
|
* 原 promoteToEnforceAfter: 2026-05-06 (距今 11 天)
|
|||
|
|
* 本补丁: 提前促升,同步更新 promoteNote 为 "评审驱动提前促升"
|
|||
|
|
*
|
|||
|
|
* 幂等: 若 mode 已为 enforce 则跳过。
|
|||
|
|
* 原子: tmp + rename。
|
|||
|
|
* 回滚: .bak 保留。
|
|||
|
|
*/
|
|||
|
|
'use strict';
|
|||
|
|
|
|||
|
|
const fs = require('fs');
|
|||
|
|
const path = require('path');
|
|||
|
|
|
|||
|
|
const TARGET = path.join(__dirname, '..', '..', 'feature-flags.json');
|
|||
|
|
const FLAGS_TO_PROMOTE = [
|
|||
|
|
'code-quality-gate',
|
|||
|
|
'post-edit-quality-check',
|
|||
|
|
'build-outcome-tracker',
|
|||
|
|
];
|
|||
|
|
const PROMOTE_NOTE = '2026-04-25 多维评审驱动提前促升 (30天静默期已满足)';
|
|||
|
|
|
|||
|
|
function main() {
|
|||
|
|
if (!fs.existsSync(TARGET)) {
|
|||
|
|
console.error('[patch-promote] 目标不存在:', TARGET);
|
|||
|
|
process.exit(1);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
const raw = fs.readFileSync(TARGET, 'utf8');
|
|||
|
|
const json = JSON.parse(raw);
|
|||
|
|
|
|||
|
|
let changed = 0;
|
|||
|
|
const changedFlags = [];
|
|||
|
|
|
|||
|
|
for (const flagName of FLAGS_TO_PROMOTE) {
|
|||
|
|
const flag = json.features && json.features[flagName];
|
|||
|
|
if (!flag) {
|
|||
|
|
console.warn('[patch-promote] flag 不存在, 跳过:', flagName);
|
|||
|
|
continue;
|
|||
|
|
}
|
|||
|
|
if (flag.mode === 'enforce') {
|
|||
|
|
console.log('[patch-promote] 已 enforce, 跳过:', flagName);
|
|||
|
|
continue;
|
|||
|
|
}
|
|||
|
|
flag.mode = 'enforce';
|
|||
|
|
flag.promoteNote = PROMOTE_NOTE;
|
|||
|
|
flag.promotedAt = new Date().toISOString();
|
|||
|
|
delete flag.promoteToEnforceAfter;
|
|||
|
|
changed++;
|
|||
|
|
changedFlags.push(flagName);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (changed === 0) {
|
|||
|
|
console.log('[patch-promote] 无需修改, 所有 flag 已为目标状态');
|
|||
|
|
process.exit(0);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 备份
|
|||
|
|
const bakPath = TARGET + '.bak.promote-quality.' + new Date().toISOString().replace(/[:.]/g, '-');
|
|||
|
|
fs.writeFileSync(bakPath, raw, 'utf8');
|
|||
|
|
|
|||
|
|
// 原子写
|
|||
|
|
const newRaw = JSON.stringify(json, null, 2) + '\n';
|
|||
|
|
const tmp = TARGET + '.tmp.' + process.pid;
|
|||
|
|
fs.writeFileSync(tmp, newRaw, 'utf8');
|
|||
|
|
fs.renameSync(tmp, TARGET);
|
|||
|
|
|
|||
|
|
console.log('[patch-promote] 已促升', changed, '个 flag:');
|
|||
|
|
changedFlags.forEach(f => console.log(' ✓', f, 'warn → enforce'));
|
|||
|
|
console.log('[patch-promote] 备份:', path.basename(bakPath));
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
main();
|