feat: move distribution builds to platform Docker builder

This commit is contained in:
npc0-hue
2026-07-30 19:25:50 +08:00
parent 1e004dc9ec
commit e614a17fe3
45 changed files with 4492 additions and 294 deletions
+21 -8
View File
@@ -168,17 +168,16 @@ describe("first-party console pages", () => {
expect(serversPageSource).toContain("旧 run 会话已失效");
});
it("uses a staged deployment workflow for create and edit without exposing protected inputs", () => {
it("separates minimal creation from post-create deployment editing without exposing protected inputs", () => {
expect(serversPageSource).toContain("<ServerDeploymentWorkflow");
expect(serversPageSource).toContain("openEditDeployment");
expect(serversPageSource).toContain("编辑部署");
expect(serverDetailPageSource).toContain("<ServerDeploymentWorkflow");
expect(serverDeploymentWorkflowSource).toContain("选择目标");
expect(serverDeploymentWorkflowSource).toContain("基本信息");
expect(serverDeploymentWorkflowSource).toContain("部署方式");
expect(serverDeploymentWorkflowSource).toContain("相关配置");
expect(serverDeploymentWorkflowSource).toContain("选择部署目标");
expect(serverDeploymentWorkflowSource).toContain("专属 Run");
expect(serverDeploymentWorkflowSource).toContain("保存草稿并准备专属 Run");
expect(serverDeploymentWorkflowSource).toContain("创建服务器");
expect(serverDeploymentWorkflowSource).toContain("执行目录(可选)");
expect(serverDeploymentWorkflowSource).toContain("默认使用服务器目录");
expect(serverDeploymentWorkflowSource).toContain("安装目录{isScum ? \"(必填)\" : \"(可选)\"}");
@@ -193,14 +192,14 @@ describe("first-party console pages", () => {
expect(serverDeploymentWorkflowSource).toContain("当前平台尚未提供 SCUM 服务端的受控升级任务");
expect(serverDeploymentWorkflowSource).toContain("已绑定服务器编辑时会直接进入相关配置");
expect(serverDeploymentWorkflowSource).toContain("可在此调整部署方式;不会重复要求选择已绑定的运行节点");
expect(serversPageSource).toContain('onNavigate("serverDetail", { serverId: result.instance.id, routeKey: "run-builder" })');
expect(serverDeploymentWorkflowSource).toContain("运行连接设置");
expect(serverDeploymentWorkflowSource).toContain('type={field.sensitive ? "password" : "text"}');
expect(serversPageSource).toContain('onNavigate("serverDetail", { serverId: result.instance.id })');
expect(serverDetailPageSource).toContain("运行配置绑定");
expect(serverDetailPageSource).toContain('type={field.sensitive ? "password" : "text"}');
expect(serverDeploymentWorkflowSource).toContain("显示已保存配置");
expect(serverDeploymentWorkflowSource).toContain("revealSavedInputs");
expect(serversPageSource).toContain("revealServerDeployment");
expect(serverDetailPageSource).toContain("最近 Run 调度");
expect(serversPageSource).toContain("serverCreateRequestFromForm(nextForm)");
expect(serversPageSource).toContain("minimalServerCreateRequestFromForm(nextForm)");
expect(serverDeploymentWorkflowSource).not.toContain('name="id"');
expect(serverDeploymentWorkflowSource).not.toContain("实例 ID");
for (const forbidden of ["secret://", "/Users/", "/var/run/", "unix://", "tcp://"]) {
@@ -208,6 +207,20 @@ describe("first-party console pages", () => {
}
});
it("keeps create-only controls structurally minimal", () => {
expect(serverDeploymentWorkflowSource).not.toContain('name="deploymentTargetId"');
expect(serverDeploymentWorkflowSource).not.toContain("请选择部署目标");
expect(serverDeploymentWorkflowSource).not.toContain("saveAsDraft");
expect(serverDeploymentWorkflowSource).not.toContain("暂不指定部署目标");
expect(serverDeploymentWorkflowSource).toContain('if (step === pluginStep) return Boolean(form.pluginId) && Boolean(form.name.trim());');
expect(serverDeploymentWorkflowSource).toContain("await onSubmit(form)");
expect(serverDeploymentWorkflowSource).not.toContain('kind === "create" && <label>运行预设');
expect(serverDeploymentWorkflowSource).not.toContain('kind === "create" && bindingFields');
expect(serverDeploymentWorkflowSource).toContain("插件类型和服务器名称是创建时仅有的必填信息");
expect(serverDeploymentWorkflowSource).toContain('const needsTargetSelection = kind === "edit" && !initialForm.runEndpointId;');
expect(serversPageSource).toContain("minimalServerCreateRequestFromForm(nextForm)");
});
it("renders server runtime actions as a compact popover trigger instead of an in-card details stack", () => {
expect(serversPageSource).toContain('aria-haspopup="menu"');
expect(serversPageSource).toContain("createPortal");
+4 -4
View File
@@ -35,7 +35,7 @@ import {
logBackfillRequest,
runDistributionGenerateRequest,
runUpdateRequest,
serverCreateRequestFromForm,
minimalServerCreateRequestFromForm,
serverDeleteConfirmation
} from "../schemas/serverManagement";
import { isPlatformAdmin } from "../contracts/workspace";
@@ -156,12 +156,12 @@ export function ServersPage({ session, operations, onNavigate }: PageComponentPr
async function handleCreate(nextForm: ServerCreateFormState) {
const operationId = operations.begin({ intent: "创建服务器", targetKind: "server", targetId: "platform", requester: session.displayName });
try {
const result = await platformApiClient.createServerWorkflow(serverCreateRequestFromForm(nextForm));
operations.succeed(operationId, result.job.id ? `已创建实例 ${result.instance.id},安装任务 ${result.job.id} 已派发` : `保存草稿 ${result.instance.id}请生成并启动专属 Run,注册成功后平台会自动部署`, result.job.id ? result.job : undefined);
const result = await platformApiClient.createServerWorkflow(minimalServerCreateRequestFromForm(nextForm));
operations.succeed(operationId, result.job.id ? `已创建实例 ${result.instance.id},安装任务 ${result.job.id} 已派发` : `创建服务器 ${result.instance.id}可在详情页按需补充运行配置和部署设置,再生成专属 Run`, result.job.id ? result.job : undefined);
setForm(defaultServerCreateForm(plugins, endpoints));
setShowCreate(false);
await refresh();
onNavigate("serverDetail", { serverId: result.instance.id, routeKey: "run-builder" });
onNavigate("serverDetail", { serverId: result.instance.id });
} catch (error) {
operations.fail(operationId, error instanceof Error ? error.message : "创建失败", operationId);
}