feat: 展示项目 Gitea 仓库诊断

- devopsApi: 接入项目 Gitea 诊断接口
- platform store: 回填仓库可达性和默认分支 commit
- ProjectsView: 展示 Gitea 状态、分支 tag 数量和 commit 摘要
This commit is contained in:
湛兮
2026-06-12 04:38:51 +08:00
parent 4e15547662
commit cb8519d3f9
4 changed files with 252 additions and 7 deletions
+68
View File
@@ -29,6 +29,8 @@ import type {
PipelineStep,
PlatformMessageSummary,
ProjectConfig,
ProjectGiteaDiagnosticsSummary,
ProjectGiteaRepositoryDiagnostic,
ProjectJenkinsDiagnosticsSummary,
ProjectJenkinsJobDiagnostic,
ProjectRefs,
@@ -359,6 +361,14 @@ export const devopsApi = {
return sanitizeProjectJenkinsDiagnostics(data)
},
async getProjectGiteaDiagnostics(): Promise<ProjectGiteaDiagnosticsSummary> {
const { data } = await http.get<ProjectGiteaDiagnosticsSummary>(
'/projects/gitea-diagnostics',
)
lastDataSource = 'backend'
return sanitizeProjectGiteaDiagnostics(data)
},
async getProjectRefs(projectKey: string): Promise<ProjectRefs> {
const { data } = await http.get<ProjectRefs>(`/projects/${projectKey}/refs`)
lastDataSource = 'backend'
@@ -786,6 +796,8 @@ function toProjectConfigs(backendProjects: BackendProject[]): ProjectConfig[] {
serviceType: serviceTypeLabel(project.key),
defaultBranch: project.defaultBranch,
tagPolicy: tagPolicyLabel(project.environments),
giteaStatus: 'warning',
giteaMessage: '尚未执行 Gitea 诊断',
environments: project.environments.map((environment) => {
return {
name: environment.name,
@@ -812,6 +824,62 @@ function toProjectConfigs(backendProjects: BackendProject[]): ProjectConfig[] {
})
}
function sanitizeProjectGiteaDiagnostics(
value: ProjectGiteaDiagnosticsSummary,
): ProjectGiteaDiagnosticsSummary {
return {
checkedAt: safeText(value.checkedAt, new Date().toISOString()),
repositories: Array.isArray(value.repositories)
? value.repositories.map(sanitizeProjectGiteaRepositoryDiagnostic)
: [],
}
}
function sanitizeProjectGiteaRepositoryDiagnostic(
value: ProjectGiteaRepositoryDiagnostic,
): ProjectGiteaRepositoryDiagnostic {
return {
projectKey: safeText(value.projectKey, 'unknown-project'),
repositoryUrl: safeText(value.repositoryUrl, ''),
owner: optionalSafeText(value.owner),
repo: optionalSafeText(value.repo),
status: toProjectGiteaDiagnosticStatus(value.status),
message: optionalSafeText(value.message),
defaultBranch: optionalSafeText(value.defaultBranch),
webUrl: optionalSafeText(value.webUrl),
cloneUrl: optionalSafeText(value.cloneUrl),
archived: typeof value.archived === 'boolean' ? value.archived : undefined,
private: typeof value.private === 'boolean' ? value.private : undefined,
empty: typeof value.empty === 'boolean' ? value.empty : undefined,
branchCount: Number.isFinite(value.branchCount) ? value.branchCount : undefined,
tagCount: Number.isFinite(value.tagCount) ? value.tagCount : undefined,
latestCommit: value.latestCommit
? {
sha: safeText(value.latestCommit.sha, ''),
message: safeText(value.latestCommit.message, ''),
authorName: optionalSafeText(value.latestCommit.authorName),
authoredAt: optionalSafeText(value.latestCommit.authoredAt),
}
: undefined,
updatedAt: optionalSafeText(value.updatedAt),
}
}
function toProjectGiteaDiagnosticStatus(
value: ProjectGiteaRepositoryDiagnostic['status'],
): ProjectGiteaRepositoryDiagnostic['status'] {
if (
value === 'ok' ||
value === 'missing' ||
value === 'not_configured' ||
value === 'unavailable'
) {
return value
}
return 'unavailable'
}
function sanitizeProjectJenkinsDiagnostics(
value: ProjectJenkinsDiagnosticsSummary,
): ProjectJenkinsDiagnosticsSummary {