fix: 调试发布run

This commit is contained in:
npc0-hue
2026-07-22 11:44:48 +08:00
parent b06623d0ce
commit 6c3eb6e45f
41 changed files with 1289 additions and 206 deletions
+12 -52
View File
@@ -1,4 +1,4 @@
import { Archive, ChevronDown, ChevronRight, Download, MoonStar, PackageOpen, Pencil, ShieldCheck, Sparkles, Square, UserRoundMinus, UserRoundPlus, WandSparkles } from "lucide-react";
import { ChevronDown, ChevronRight, Download, MoonStar, PackageOpen, Pencil, ShieldCheck, Sparkles, Square, UserRoundMinus, UserRoundPlus, WandSparkles } from "lucide-react";
import { type FormEvent, type ReactNode, useCallback, useEffect, useMemo, useState } from "react";
import { platformApiClient } from "../api/client";
@@ -35,6 +35,7 @@ import {
runtimeDependencyStages,
runtimeDownloadStages,
runtimeLogStages,
runtimeRunBuildStages,
runtimeUpdateStages,
type RuntimeTaskDialogAction,
type RuntimeTaskStage,
@@ -43,7 +44,7 @@ import {
import { DiagnosticSummary, EmptyState, ErrorState, LoadingState, ResultBadge } from "../components/StateViews";
import type { PageComponentProps } from "../contracts/page";
import type { PluginBridgeAction, PluginBridgeManifestContract } from "../contracts/pluginBridge";
import { canArchiveServer, canStartServer, canStopServer, pluginLabel, runtimeBindingFields, serverMetadataFormFromInstance, type ServerMetadataFormState } from "../contracts/serverManagement";
import { canStartServer, canStopServer, pluginLabel, runtimeBindingFields, serverMetadataFormFromInstance, type ServerMetadataFormState } from "../contracts/serverManagement";
import {
serverDetailSections,
serverIsOnline,
@@ -60,7 +61,6 @@ import {
logBackfillRequest,
runDistributionGenerateRequest,
runUpdateRequest,
serverArchiveConfirmation,
serverLifecycleCommandRequest,
serverMetadataUpdateRequestFromForm
} from "../schemas/serverManagement";
@@ -312,7 +312,6 @@ export function ServerDetailPage({ session, params, operations, onNavigate }: Pa
session={session}
operations={operations}
onChanged={(next) => setInstance({ status: "ready", data: next })}
onArchived={() => onNavigate("servers")}
/>
)}
{section === "overview" && <ServerAdministratorsSection instance={instance.data} session={session} onChanged={(next) => setInstance({ status: "ready", data: next })} />}
@@ -360,14 +359,11 @@ interface ServerMetadataSectionProps {
session: PageComponentProps["session"];
operations: PageComponentProps["operations"];
onChanged: (instance: ServerInstanceResponse) => void;
onArchived: () => void;
}
function ServerMetadataSection({ instance, session, operations, onChanged, onArchived }: ServerMetadataSectionProps) {
function ServerMetadataSection({ instance, session, operations, onChanged }: ServerMetadataSectionProps) {
const [draft, setDraft] = useState<ServerMetadataFormState>(() => serverMetadataFormFromInstance(instance));
const [result, setResult] = useState<{ status: "succeeded" | "failed" | "pending"; label: string } | null>(null);
const [confirmArchive, setConfirmArchive] = useState<ReturnType<typeof serverArchiveConfirmation> | null>(null);
const [confirmBusy, setConfirmBusy] = useState(false);
useEffect(() => {
setDraft(serverMetadataFormFromInstance(instance));
@@ -388,23 +384,6 @@ function ServerMetadataSection({ instance, session, operations, onChanged, onArc
}
}
async function archiveServer() {
setConfirmBusy(true);
const operationId = operations.begin({ intent: "归档服务器", targetKind: "server", targetId: instance.id, requester: session.displayName });
try {
await platformApiClient.archiveServerInstance(instance.id);
operations.succeed(operationId, `服务器已归档:${instance.id}`);
setResult({ status: "succeeded", label: `${instance.name} 已归档` });
setConfirmArchive(null);
onArchived();
} catch (error) {
operations.fail(operationId, error instanceof Error ? error.message : "服务器归档失败");
setResult({ status: "failed", label: error instanceof Error ? error.message : "归档失败,平台拒绝当前状态" });
} finally {
setConfirmBusy(false);
}
}
return (
<article className="console-panel" aria-label="server metadata">
<div className="panel-header">
@@ -423,27 +402,8 @@ function ServerMetadataSection({ instance, session, operations, onChanged, onArc
<Pencil size={14} />
<span></span>
</button>
<button type="button" className="icon-command danger-command" disabled={!canArchiveServer(instance.state)} onClick={() => setConfirmArchive(serverArchiveConfirmation(instance))}>
<Archive size={14} />
<span></span>
</button>
</div>
</form>
{!canArchiveServer(instance.state) && (
<p className="provider-id" style={{ marginTop: 10 }}>
</p>
)}
<ConfirmDialog
open={confirmArchive !== null}
title="归档服务器"
description={`确认归档 ${confirmArchive?.name ?? ""}${confirmArchive?.serverInstanceId ?? ""})?运行中或安装中的服务器会被平台拒绝,历史记录会保留。`}
confirmLabel="确认归档"
danger
busy={confirmBusy}
onCancel={() => setConfirmArchive(null)}
onConfirm={() => void archiveServer()}
/>
</article>
);
}
@@ -930,7 +890,7 @@ function RuntimeDistributionSection({ instance, runtimeActions, session, operati
async function pushRunArtifact(artifact: { artifactId: string; checksum?: string }) {
setRuntimeTaskActions([]);
await runOperation(
"推送 run 更新",
"更新 run",
() => platformApiClient.pushRunUpdate(instance.id, runUpdateRequest(instance.id, artifact.artifactId, artifact.checksum)),
(update) => `run 更新任务已排队,job ${update.jobId ?? update.id}`,
{
@@ -1050,14 +1010,14 @@ function RuntimeDistributionSection({ instance, runtimeActions, session, operati
},
(distribution) => `run ${distribution.targetOs}/${distribution.targetArch} 二进制已构建,artifact ${distribution.artifactId}generation ${distribution.keyGeneration}`,
{
description: `${instance.name} 构建 ${targetOs}/${targetArch} run 包,包含拉取代码、安装环境、编译和打包进度。`,
stages: runtimeBuildStages,
description: `${instance.name} 构建 ${targetOs}/${targetArch} run 包,展示拉取 run 更新、检测构建环境、构建中和构建完成进度。`,
stages: runtimeRunBuildStages,
trackedJobId: (distribution) => distribution.buildJobId,
afterSuccess: (distribution) => {
const artifact = { artifactId: distribution.artifactId, checksum: distribution.checksum };
setRuntimeTaskActions([
{ label: "下载 run", kind: "primary", onClick: () => void downloadRunArtifact(artifact) },
{ label: "推送更新", onClick: () => void pushRunArtifact(artifact) }
{ label: "更新 run", disabled: !serverIsOnline(instance.state), title: serverIsOnline(instance.state) ? "更新 run" : "run 未运行,无法在线更新", onClick: () => void pushRunArtifact(artifact) }
]);
}
}
@@ -1087,12 +1047,12 @@ function RuntimeDistributionSection({ instance, runtimeActions, session, operati
}
)
}
secondaryLabel="推送更新"
secondaryDisabled={!canUse("push-run-update") || latestRunArtifact() === null}
secondaryReason={latestRunArtifact() === null ? "请先生成或下载 run 包" : reasonFor("push-run-update")}
secondaryLabel="更新 run"
secondaryDisabled={!canUse("push-run-update") || latestRunArtifact() === null || !serverIsOnline(instance.state)}
secondaryReason={!serverIsOnline(instance.state) ? "run 未运行,无法在线更新" : latestRunArtifact() === null ? "请先生成或下载 run 包" : reasonFor("push-run-update")}
onSecondary={() =>
void runOperation(
"推送 run 更新",
"更新 run",
async () => {
const artifact = latestRunArtifact();
if (!artifact) {