From cb061890d342835be33808a70b2362623f1125d5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=89=8B=E7=93=9C=E4=B8=80=E5=8D=81=E9=9B=AA?= Date: Sat, 3 Jan 2026 15:28:18 +0800 Subject: [PATCH] Enhance artifact handling and display for action builds Extended artifact metadata to include workflow run ID and head SHA. Updated backend to filter artifacts by environment and provide additional metadata. Improved frontend to display new artifact details and adjusted UI for better clarity. --- packages/napcat-common/src/mirror.ts | 47 ++++++++++++------- .../napcat-webui-backend/src/api/BaseInfo.ts | 12 ++++- .../src/components/system_info.tsx | 37 ++++++++++----- .../src/controllers/webui_manager.ts | 2 + 4 files changed, 68 insertions(+), 30 deletions(-) diff --git a/packages/napcat-common/src/mirror.ts b/packages/napcat-common/src/mirror.ts index 17342a63..fde9f6ab 100644 --- a/packages/napcat-common/src/mirror.ts +++ b/packages/napcat-common/src/mirror.ts @@ -850,6 +850,8 @@ export interface ActionArtifact { created_at: string; expires_at: string; archive_download_url: string; + workflow_run_id?: number; + head_sha?: string; } /** @@ -860,13 +862,14 @@ export async function getLatestActionArtifacts ( owner: string, repo: string, workflow: string = 'build.yml', - branch: string = 'main' + branch: string = 'main', + maxRuns: number = 10 ): Promise { - const endpoint = `https://api.github.com/repos/${owner}/${repo}/actions/workflows/${workflow}/runs?branch=${branch}&status=success&per_page=1`; + const endpoint = `https://api.github.com/repos/${owner}/${repo}/actions/workflows/${workflow}/runs?branch=${branch}&status=success&per_page=${maxRuns}`; try { const runsResponse = await RequestUtil.HttpGetJson<{ - workflow_runs: Array<{ id: number; }>; + workflow_runs: Array<{ id: number; head_sha: string; created_at: string; }>; }>(endpoint, 'GET', undefined, { 'User-Agent': 'NapCat', 'Accept': 'application/vnd.github.v3+json', @@ -877,21 +880,33 @@ export async function getLatestActionArtifacts ( throw new Error('No successful workflow runs found'); } - const firstRun = workflowRuns[0]; - if (!firstRun) { - throw new Error('No workflow run found'); + // 获取所有 runs 的 artifacts + const allArtifacts: ActionArtifact[] = []; + + for (const run of workflowRuns) { + try { + const artifactsEndpoint = `https://api.github.com/repos/${owner}/${repo}/actions/runs/${run.id}/artifacts`; + const artifactsResponse = await RequestUtil.HttpGetJson<{ + artifacts: ActionArtifact[]; + }>(artifactsEndpoint, 'GET', undefined, { + 'User-Agent': 'NapCat', + 'Accept': 'application/vnd.github.v3+json', + }); + + if (artifactsResponse.artifacts) { + // 为每个 artifact 添加 run 信息 + for (const artifact of artifactsResponse.artifacts) { + artifact.workflow_run_id = run.id; + artifact.head_sha = run.head_sha; + allArtifacts.push(artifact); + } + } + } catch { + // 单个 run 获取失败,继续下一个 + } } - const runId = firstRun.id; - const artifactsEndpoint = `https://api.github.com/repos/${owner}/${repo}/actions/runs/${runId}/artifacts`; - const artifactsResponse = await RequestUtil.HttpGetJson<{ - artifacts: ActionArtifact[]; - }>(artifactsEndpoint, 'GET', undefined, { - 'User-Agent': 'NapCat', - 'Accept': 'application/vnd.github.v3+json', - }); - - return artifactsResponse.artifacts || []; + return allArtifacts; } catch { return []; } diff --git a/packages/napcat-webui-backend/src/api/BaseInfo.ts b/packages/napcat-webui-backend/src/api/BaseInfo.ts index 6b4f2282..2aae010e 100644 --- a/packages/napcat-webui-backend/src/api/BaseInfo.ts +++ b/packages/napcat-webui-backend/src/api/BaseInfo.ts @@ -5,6 +5,7 @@ import { sendSuccess } from '@/napcat-webui-backend/src/utils/response'; import { WebUiConfig } from '@/napcat-webui-backend/index'; import { getLatestTag, getAllTags, compareSemVer } from 'napcat-common/src/helper'; import { getLatestActionArtifacts } from '@/napcat-common/src/mirror'; +import { NapCatCoreWorkingEnv } from '@/napcat-webui-backend/src/types'; export const GetNapCatVersion: RequestHandler = (_, res) => { const data = WebUiDataRuntime.GetNapCatVersion(); @@ -32,6 +33,8 @@ export interface VersionInfo { createdAt?: string; expiresAt?: string; size?: number; + workflowRunId?: number; + headSha?: string; } /** @@ -75,8 +78,13 @@ export const getAllReleasesHandler: RequestHandler = async (req, res) => { if (includeActions) { try { const artifacts = await getLatestActionArtifacts('NapNeko', 'NapCatQQ', 'build.yml', 'main'); + + // 根据当前工作环境自动过滤对应的 artifact 类型 + const isFramework = WebUiDataRuntime.getWorkingEnv() === NapCatCoreWorkingEnv.Framework; + const targetArtifactName = isFramework ? 'NapCat.Framework' : 'NapCat.Shell'; + actionVersions = artifacts - .filter(a => a.name.includes('NapCat')) + .filter(a => a.name === targetArtifactName) .map(a => ({ tag: `action-${a.id}`, type: 'action' as const, @@ -85,6 +93,8 @@ export const getAllReleasesHandler: RequestHandler = async (req, res) => { createdAt: a.created_at, expiresAt: a.expires_at, size: a.size_in_bytes, + workflowRunId: a.workflow_run_id, + headSha: a.head_sha, })); } catch { // 忽略 action artifacts 获取失败 diff --git a/packages/napcat-webui-frontend/src/components/system_info.tsx b/packages/napcat-webui-frontend/src/components/system_info.tsx index a9aa2ee4..731a4184 100644 --- a/packages/napcat-webui-frontend/src/components/system_info.tsx +++ b/packages/napcat-webui-frontend/src/components/system_info.tsx @@ -267,6 +267,8 @@ interface VersionInfo { createdAt?: string; expiresAt?: string; size?: number; + workflowRunId?: number; + headSha?: string; } // 版本选择对话框内容 @@ -513,7 +515,7 @@ const VersionSelectDialogContent: React.FC = ({ setSelectedVersion(version || null); }} classNames={{ - trigger: 'h-10', + trigger: 'h-auto min-h-10', }} > {filteredVersions.map((version) => { @@ -524,19 +526,28 @@ const VersionSelectDialogContent: React.FC = ({ key={version.tag} textValue={version.tag} > -
- {version.tag} - {version.type === 'prerelease' && ( - 预发布 - )} +
+
+ {version.type === 'action' && version.artifactName ? version.artifactName : version.tag} + {version.type === 'prerelease' && ( + 预发布 + )} + {version.type === 'action' && ( + 临时 + )} + {isCurrent && ( + 当前 + )} + {downgrade && !isCurrent && version.type !== 'action' && ( + 降级 + )} +
{version.type === 'action' && ( - 临时 - )} - {isCurrent && ( - 当前 - )} - {downgrade && !isCurrent && version.type !== 'action' && ( - 降级 +
+ {version.headSha && {version.headSha.slice(0, 7)}} + {version.createdAt && {new Date(version.createdAt).toLocaleString()}} + {version.size && {(version.size / 1024 / 1024).toFixed(1)} MB} +
)}
diff --git a/packages/napcat-webui-frontend/src/controllers/webui_manager.ts b/packages/napcat-webui-frontend/src/controllers/webui_manager.ts index c9aa30b1..5bb344c5 100644 --- a/packages/napcat-webui-frontend/src/controllers/webui_manager.ts +++ b/packages/napcat-webui-frontend/src/controllers/webui_manager.ts @@ -83,6 +83,8 @@ export default class WebUIManager { createdAt?: string; expiresAt?: string; size?: number; + workflowRunId?: number; + headSha?: string; }>; pagination: { page: number;