发布灰度改为默认关闭并修掉客户端“看得到点不动”
Project CI / AI game creator shell Rust crates (pull_request) Successful in 1m28s
Project CI / AI game creator shell Rust smoke (pull_request) Successful in 2m2s
Project CI / Backend tests (pull_request) Successful in 5m37s
Project CI / AI game creator shell Rust lane 2/2 (pull_request) Successful in 7m8s
Project CI / AI game creator shell Rust lane 1/2 (pull_request) Successful in 8m29s
Project CI / Native shell tests (pull_request) Successful in 6m53s
Project CI / Frontend tests (pull_request) Successful in 2m52s
Project CI / Repository checks (pull_request) Successful in 2m59s
Project CI / AI game creator shell web tests (pull_request) Successful in 2m21s
Project CI / AI game creator shell Rust crates (pull_request) Successful in 1m28s
Project CI / AI game creator shell Rust smoke (pull_request) Successful in 2m2s
Project CI / Backend tests (pull_request) Successful in 5m37s
Project CI / AI game creator shell Rust lane 2/2 (pull_request) Successful in 7m8s
Project CI / AI game creator shell Rust lane 1/2 (pull_request) Successful in 8m29s
Project CI / Native shell tests (pull_request) Successful in 6m53s
Project CI / Frontend tests (pull_request) Successful in 2m52s
Project CI / Repository checks (pull_request) Successful in 2m59s
Project CI / AI game creator shell web tests (pull_request) Successful in 2m21s
- 后端:is_game_distribution_publish_enabled_for_user 现在要求 gate 行存在且 enabled=true(未登录、无行、enabled=false 一律不开放),因此没配灰度时 gameDistributionPublishEnabled=false;新增与作者无关的 is_game_distribution_publish_open,管理员审核激活新版本只按总开关判定,避免被作者白名单挡住(修复合入后立即发现的回归)。 - AGC:新增 announcePublishMessage,把「已构建并打包试玩包」「先打开一个项目再发布」等提示通过 DirectProject 聊天容器的 announce 出口回话;普通项目不渲染工作台状态行,之前只写 workspaceStatus 才会表现为点了没反应。 - 后台:「灰度发布配置」新增「可配置开关」列表,预设开关在未创建行时也可见并可一键配置(game-distribution:publish 不再需要先猜键名)。 - 脚本:check:game-distribution-media-e2e 先验证「灰度关闭 → 作者拿不到入口 + 写入口 503」,再开启灰度把真实 Phaser 构建产物发布到可玩,全链路 25 项断言通过。 - 文档:玩法链路、后端契约、开发运维与实施计划统一改为「灰度默认关闭,运营配置后开放」口径。
This commit is contained in:
@@ -214,6 +214,78 @@ async function main() {
|
||||
});
|
||||
const another = otherEntry.data.token;
|
||||
|
||||
// 1.1 管理员登录:发布灰度默认关闭,脚本先验证关闭态再为本轮验证开启。
|
||||
const adminLogin = await api('/admin/api/login', {
|
||||
method: 'POST',
|
||||
body: { username: ADMIN_USER, password: ADMIN_PASSWORD },
|
||||
});
|
||||
check(
|
||||
'管理员登录成功',
|
||||
adminLogin.status === 200 &&
|
||||
Boolean(adminLogin.data?.token ?? adminLogin.data?.accessToken),
|
||||
`status=${adminLogin.status}`,
|
||||
);
|
||||
const admin = adminLogin.data?.token ?? adminLogin.data?.accessToken;
|
||||
|
||||
const setPublishGate = (enabled, rolloutPercent) =>
|
||||
api('/admin/api/feature-gates', {
|
||||
method: 'PUT',
|
||||
token: admin,
|
||||
body: {
|
||||
gateKey: 'game-distribution:publish',
|
||||
enabled,
|
||||
rolloutPercent,
|
||||
allowUserIds: [],
|
||||
allowUserTags: [],
|
||||
denyUserIds: [],
|
||||
description: 'E2E 发布灰度',
|
||||
},
|
||||
});
|
||||
|
||||
const gateClosed = await setPublishGate(false, 0);
|
||||
check(
|
||||
'发布灰度可配置为关闭',
|
||||
gateClosed.status === 200,
|
||||
`status=${gateClosed.status}`,
|
||||
);
|
||||
|
||||
const closedAvailability = await api('/api/runtime/frontend-config', {
|
||||
token: author,
|
||||
});
|
||||
check(
|
||||
'灰度关闭时作者拿不到发布入口',
|
||||
closedAvailability.data?.gameDistributionPublishEnabled === false,
|
||||
`value=${closedAvailability.data?.gameDistributionPublishEnabled}`,
|
||||
);
|
||||
|
||||
const closedPublish = await api('/api/game-distribution/games', {
|
||||
method: 'POST',
|
||||
token: author,
|
||||
headers: { 'Idempotency-Key': `e2e-gate-closed-${Date.now()}` },
|
||||
body: gameMetadata({ title: `灰度关闭验证 ${Date.now()}` }),
|
||||
});
|
||||
check(
|
||||
'灰度关闭时写入口 503',
|
||||
closedPublish.status === 503,
|
||||
`status=${closedPublish.status} code=${closedPublish.error?.code ?? ''}`,
|
||||
);
|
||||
|
||||
const gateOpen = await setPublishGate(true, 100);
|
||||
check(
|
||||
'发布灰度可开启并放量',
|
||||
gateOpen.status === 200,
|
||||
`status=${gateOpen.status}`,
|
||||
);
|
||||
|
||||
const openAvailability = await api('/api/runtime/frontend-config', {
|
||||
token: author,
|
||||
});
|
||||
check(
|
||||
'灰度开启后作者拿到发布入口',
|
||||
openAvailability.data?.gameDistributionPublishEnabled === true,
|
||||
`value=${openAvailability.data?.gameDistributionPublishEnabled}`,
|
||||
);
|
||||
|
||||
// 2. 真实素材直传
|
||||
const id = stamp();
|
||||
const cover = await uploadImage(author, 'cover', id);
|
||||
@@ -444,19 +516,7 @@ async function main() {
|
||||
`status=${readBefore.status}`,
|
||||
);
|
||||
|
||||
// 7. 管理员审核通过(本地非生产允许回环 http 入口)
|
||||
const adminLogin = await api('/admin/api/login', {
|
||||
method: 'POST',
|
||||
body: { username: ADMIN_USER, password: ADMIN_PASSWORD },
|
||||
});
|
||||
check(
|
||||
'管理员登录成功',
|
||||
adminLogin.status === 200 &&
|
||||
Boolean(adminLogin.data?.token ?? adminLogin.data?.accessToken),
|
||||
`status=${adminLogin.status}`,
|
||||
);
|
||||
const admin = adminLogin.data?.token ?? adminLogin.data?.accessToken;
|
||||
|
||||
// 7. 管理员审核通过(本地非生产允许回环 http 入口;管理员 token 在步骤 1.1 已取得)
|
||||
const approved = await api(
|
||||
`/admin/api/game-distribution/versions/${versionId}/review`,
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user