e23b0e871b
Project CI / AI game creator shell Rust crates (push) Successful in 1m45s
Project CI / AI game creator shell Rust smoke (push) Successful in 2m4s
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
- build-macos-ci:构建前按后缀清空 macos/ 下的 *.app.tar.gz / *.sig / *.dmg / *.dmg.sha256,构建后读 Info.plist 核对版本与渠道身份,生成清单后再断言选中本轮更新包 - 新增 macos-release-identity.mjs 与单测:回归用例直接用线上 dev-mac 里那份 0.1.139 release 身份包 - prepare-macos-codex.test:残留清理断言改成按后缀全覆盖,并校验清理在构建前、身份核对在验签前 - Jenkinsfile.ai-game-creator-shell-macos-build:mac Job 增加身份守卫用例 - check:agc-update-channel-manifests:下载后解出 mac 包内 Info.plist 核对版本与身份,并按 2026-09-21 决策只要求 darwin-aarch64 - 文档:两份里程碑按现行决策修正口径并记录线上缺陷,decision-log 记决策与边界,pitfalls 记录「按目录扫描挑产物会选中残留」
126 lines
4.0 KiB
JavaScript
126 lines
4.0 KiB
JavaScript
import assert from 'node:assert/strict';
|
|
import test from 'node:test';
|
|
|
|
import {
|
|
assertMacosAppMatchesChannelIdentity,
|
|
assertManifestArtifactMatchesExpected,
|
|
listStaleMacosArtifacts,
|
|
readMacosAppInfoIdentity,
|
|
} from './macos-release-identity.mjs';
|
|
|
|
const DEV_IDENTITY = {
|
|
productName: '陶泥儿开发版',
|
|
identifier: 'world.genarrative.ai-game-creator',
|
|
};
|
|
|
|
function plist({ version, identifier, name }) {
|
|
return `<?xml version="1.0" encoding="UTF-8"?>
|
|
<plist version="1.0"><dict>
|
|
<key>CFBundleShortVersionString</key><string>${version}</string>
|
|
<key>CFBundleIdentifier</key><string>${identifier}</string>
|
|
<key>CFBundleName</key><string>${name}</string>
|
|
<key>CFBundleDisplayName</key><string>${name}</string>
|
|
</dict></plist>`;
|
|
}
|
|
|
|
test('reads version, identifier and product name from Info.plist text', () => {
|
|
const identity = readMacosAppInfoIdentity(
|
|
plist({
|
|
version: '0.1.154',
|
|
...DEV_IDENTITY,
|
|
name: DEV_IDENTITY.productName,
|
|
}),
|
|
);
|
|
assert.deepEqual(identity, {
|
|
version: '0.1.154',
|
|
identifier: DEV_IDENTITY.identifier,
|
|
name: DEV_IDENTITY.productName,
|
|
displayName: DEV_IDENTITY.productName,
|
|
});
|
|
});
|
|
|
|
test('accepts the app bundle that matches this channel and version', () => {
|
|
assert.doesNotThrow(() =>
|
|
assertMacosAppMatchesChannelIdentity({
|
|
identity: readMacosAppInfoIdentity(
|
|
plist({
|
|
version: '0.1.154',
|
|
identifier: DEV_IDENTITY.identifier,
|
|
name: DEV_IDENTITY.productName,
|
|
}),
|
|
),
|
|
expectedVersion: '0.1.154',
|
|
expectedProductName: DEV_IDENTITY.productName,
|
|
expectedIdentifier: DEV_IDENTITY.identifier,
|
|
}),
|
|
);
|
|
});
|
|
|
|
// 回归:线上 dev-mac/0.1.142 清单实际指向 0.1.139 的 release 身份包。
|
|
test('rejects the release-identity bundle that shipped in the dev-mac channel', () => {
|
|
const shipped = readMacosAppInfoIdentity(
|
|
plist({
|
|
version: '0.1.139',
|
|
identifier: 'world.genarrative.ai-game-creator.release',
|
|
name: '陶泥儿 Release',
|
|
}),
|
|
);
|
|
assert.throws(
|
|
() =>
|
|
assertMacosAppMatchesChannelIdentity({
|
|
identity: shipped,
|
|
expectedVersion: '0.1.142',
|
|
expectedProductName: DEV_IDENTITY.productName,
|
|
expectedIdentifier: DEV_IDENTITY.identifier,
|
|
}),
|
|
/版本不一致:产物 0\.1\.139,本轮清单 0\.1\.142[\s\S]*bundle identifier 不一致[\s\S]*产品名不一致/u,
|
|
);
|
|
});
|
|
|
|
test('rejects a bundle whose version is right but channel identity is wrong', () => {
|
|
assert.throws(
|
|
() =>
|
|
assertMacosAppMatchesChannelIdentity({
|
|
identity: readMacosAppInfoIdentity(
|
|
plist({
|
|
version: '0.1.154',
|
|
identifier: 'world.genarrative.ai-game-creator.release',
|
|
name: '陶泥儿 Release',
|
|
}),
|
|
),
|
|
expectedVersion: '0.1.154',
|
|
expectedProductName: DEV_IDENTITY.productName,
|
|
expectedIdentifier: DEV_IDENTITY.identifier,
|
|
}),
|
|
/bundle identifier 不一致/u,
|
|
);
|
|
});
|
|
|
|
test('lists every stale mac artifact so the bundle directory cannot leak into the manifest', () => {
|
|
const files = [
|
|
'/bundle/macos/陶泥儿 Release.app.tar.gz',
|
|
'/bundle/macos/陶泥儿 Release.app.tar.gz.sig',
|
|
'/bundle/macos/陶泥儿开发版_0.1.139_aarch64.dmg',
|
|
'/bundle/macos/陶泥儿开发版_0.1.139_aarch64.dmg.sha256',
|
|
'/bundle/macos/陶泥儿开发版.app/Contents/Info.plist',
|
|
];
|
|
assert.deepEqual(listStaleMacosArtifacts(files), files.slice(0, 4));
|
|
});
|
|
|
|
test('rejects a manifest that selected a different artifact than this build wrote', () => {
|
|
assert.throws(
|
|
() =>
|
|
assertManifestArtifactMatchesExpected({
|
|
artifactPath: '/bundle/macos/陶泥儿 Release.app.tar.gz',
|
|
expectedPath: '/bundle/macos/陶泥儿开发版.app.tar.gz',
|
|
}),
|
|
/清单选中的更新包不是本轮产物/u,
|
|
);
|
|
assert.doesNotThrow(() =>
|
|
assertManifestArtifactMatchesExpected({
|
|
artifactPath: '/bundle/macos/陶泥儿开发版.app.tar.gz',
|
|
expectedPath: '/bundle/macos/陶泥儿开发版.app.tar.gz',
|
|
}),
|
|
);
|
|
});
|