补齐跨渠道产物隔离核对并把 dev-mac 缺陷钉到字节级
Project CI / AI game creator shell Rust crates (push) Failing after 1m11s
Project CI / AI game creator shell Rust smoke (push) Successful in 1m59s
Project CI / AI game creator shell Rust lane 2/2 (push) Has been cancelled
Project CI / Frontend tests (push) Has been cancelled
Project CI / Repository checks (push) Has been cancelled
Project CI / Backend tests (push) Has been cancelled
Project CI / AI game creator shell web tests (push) Has been cancelled
Project CI / AI game creator shell Rust lane 1/2 (push) Has been cancelled
Project CI / Native shell tests (push) Has been cancelled
Project CI / AI game creator shell Rust crates (push) Failing after 1m11s
Project CI / AI game creator shell Rust smoke (push) Successful in 1m59s
Project CI / AI game creator shell Rust lane 2/2 (push) Has been cancelled
Project CI / Frontend tests (push) Has been cancelled
Project CI / Repository checks (push) Has been cancelled
Project CI / Backend tests (push) Has been cancelled
Project CI / AI game creator shell web tests (push) Has been cancelled
Project CI / AI game creator shell Rust lane 1/2 (push) Has been cancelled
Project CI / Native shell tests (push) Has been cancelled
- check:agc-update-channel-manifests:新增「不同渠道更新包不得字节相同」断言(需 AGC_UPDATE_VERIFY_DOWNLOAD=1),并核对 Windows 安装包文件名带本渠道产品名 - 只读核对 dev-win/dev-mac/release-win/release-mac:dev-win 0.1.154、release-win 0.1.150、release-mac 0.1.139 身份与版本一致;dev-mac 0.1.142 与 release-mac 0.1.139 的更新包 sha256 相同,字节级证明 dev 分区放了 release 渠道的产物 - 渠道安装身份隔离里程碑补本轮核对(发布产物身份 + 跨渠道唯一性),真机并存仍待验收 - macOS 里程碑与 pitfalls、decision-log 记录字节级取证与新断言
This commit is contained in:
@@ -56,6 +56,8 @@ const WINDOWS_PLATFORM_KEY = 'windows-x86_64';
|
||||
|
||||
let failures = 0;
|
||||
let skipped = 0;
|
||||
/** 下载过的更新包摘要:用于「不同渠道不能共用同一份产物字节」这条隔离断言。 */
|
||||
const downloadedArtifacts = [];
|
||||
function check(name, ok, detail = '') {
|
||||
if (!ok) failures += 1;
|
||||
console.log(
|
||||
@@ -261,6 +263,20 @@ async function verifyChannel(channel, tempDir) {
|
||||
Boolean(platforms[WINDOWS_PLATFORM_KEY]),
|
||||
`platforms=${platformKeys.join(',')}`,
|
||||
);
|
||||
// 渠道身份会写进产物文件名的产品名,这里先用清单里的地址核对(下载后再验签与摘要)。
|
||||
const expectedIdentity = resolveChannelInstallIdentity(
|
||||
channel.replace(/-win$/u, ''),
|
||||
);
|
||||
const artifactNames = platformKeys.map((key) =>
|
||||
decodeURIComponent(new URL(String(platforms[key].url ?? '')).pathname),
|
||||
);
|
||||
check(
|
||||
`${channel} 安装包文件名带本渠道产品名`,
|
||||
artifactNames.every((name) =>
|
||||
name.includes(expectedIdentity.productName),
|
||||
),
|
||||
`names=${artifactNames.map((name) => path.basename(name)).join(',')} expected=${expectedIdentity.productName}`,
|
||||
);
|
||||
}
|
||||
|
||||
if (channel === 'dev-win') {
|
||||
@@ -315,6 +331,13 @@ async function verifyChannel(channel, tempDir) {
|
||||
`downloaded=${size} head=${artifactHead.length}`,
|
||||
);
|
||||
const sha256 = await sha256Of(artifactPath);
|
||||
downloadedArtifacts.push({
|
||||
channel,
|
||||
platformKey: key,
|
||||
sha256,
|
||||
size,
|
||||
url,
|
||||
});
|
||||
if (channel === 'dev-win' && key === WINDOWS_PLATFORM_KEY) {
|
||||
const bridgeJson = await (
|
||||
await fetch(`${OSS_BASE_URL}/latest.json`)
|
||||
@@ -359,6 +382,48 @@ try {
|
||||
await rm(tempDir, { recursive: true, force: true });
|
||||
}
|
||||
|
||||
// 渠道隔离:同一次核对里如果下载到多个渠道的更新包,它们不能是同一份字节——
|
||||
// 不同渠道的 productName / identifier 不同,产物就不会相同(2026-09-28 的 dev-mac
|
||||
// 事故正是「dev 分区里放的其实是 release 渠道那份包」,字节级完全相同)。
|
||||
const channelNames = [
|
||||
...new Set(
|
||||
downloadedArtifacts.map((item) => item.channel.replace(/-(win|mac)$/u, '')),
|
||||
),
|
||||
];
|
||||
if (!VERIFY_DOWNLOAD) {
|
||||
skip(
|
||||
'不同渠道的更新包互不相同(渠道隔离)',
|
||||
'需要 AGC_UPDATE_VERIFY_DOWNLOAD=1 才能比对产物字节',
|
||||
);
|
||||
} else if (channelNames.length < 2) {
|
||||
skip(
|
||||
'不同渠道的更新包互不相同(渠道隔离)',
|
||||
`本次只核对到 ${channelNames.length} 个渠道(${channelNames.join(',')});用 AGC_UPDATE_CHANNELS=dev-win,dev-mac,release-win,release-mac 可覆盖全量`,
|
||||
);
|
||||
} else {
|
||||
const byHash = new Map();
|
||||
for (const item of downloadedArtifacts) {
|
||||
const bucket = byHash.get(item.sha256) ?? [];
|
||||
bucket.push(item);
|
||||
byHash.set(item.sha256, bucket);
|
||||
}
|
||||
const collisions = [...byHash.entries()].filter(
|
||||
([, items]) =>
|
||||
new Set(items.map((item) => item.channel.replace(/-(win|mac)$/u, '')))
|
||||
.size > 1,
|
||||
);
|
||||
check(
|
||||
'不同渠道的更新包互不相同(渠道隔离)',
|
||||
collisions.length === 0,
|
||||
collisions
|
||||
.map(
|
||||
([hash, items]) =>
|
||||
`${hash.slice(0, 12)}: ${items.map((item) => `${item.channel}/${item.platformKey}`).join(' = ')}`,
|
||||
)
|
||||
.join(';'),
|
||||
);
|
||||
}
|
||||
|
||||
console.log(
|
||||
failures === 0
|
||||
? `\n全部通过${skipped > 0 ? `(${skipped} 项跳过)` : ''}`
|
||||
|
||||
Reference in New Issue
Block a user