From 9647f806ce6c0d552050a879c8e4d0756ac078dd Mon Sep 17 00:00:00 2001 From: zhaoyingbo Date: Tue, 2 Jul 2024 03:54:25 +0000 Subject: [PATCH] =?UTF-8?q?feat:=20=E4=BC=98=E5=8C=96GitLab=E5=BE=BD?= =?UTF-8?q?=E7=AB=A0=E8=AE=BE=E7=BD=AE=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- badge/cloudml.ts | 141 +++++++++++++++++++++++++++++++++++++++++++ badge/miai.ts | 117 +++++++++++++++++++++++++++++++++++ service/gitlab.ts | 30 +++++---- service/typings.d.ts | 9 +++ 4 files changed, 284 insertions(+), 13 deletions(-) create mode 100644 badge/cloudml.ts create mode 100644 badge/miai.ts diff --git a/badge/cloudml.ts b/badge/cloudml.ts new file mode 100644 index 0000000..066224c --- /dev/null +++ b/badge/cloudml.ts @@ -0,0 +1,141 @@ +import service from "../service"; + +const projectList = [ + "cloud-ml/cloudml-maas", + "cloud-ml/cloudml-permission", + "cloud-ml/cloudml-base", + "cloud-ml/cloudml-dataset", + "cloud-ml/cloudml-dev", + "cloud-ml/cloudml-train", + "cloud-ml/cloudml-finetune", + "cloud-ml/model-repository", + "cloud-ml-public/cloudml-grpc-java", + "cloud-ml/cloudml_runqueue", + "cloud-ml/cloudml_syncqueue", + "cloud-ml/resource-instance", + "cloud-ml/ai-workbench-common", + "cloud-ml/evaluate.git", + "ai-service-data/ai-train-platform-service.git", + "cloud-ml/embedding_management", + "cloud-ml/knowledge-base", + "cloud-ml/ai-proxy", +]; + +const getNewProjectBadge = async ( + projectDetail: GitlabProjDetail +): Promise => { + // 项目路径 cloud-ml/cloudml-dev + const projectPath = projectDetail.path_with_namespace; + // 根据项目路径获取sonarqubeId 类似于 cloud-ml/cloudml-dev -> cloud-ml:cloudml-dev + const sonarqubeId = projectPath.replace("/", ":"); + // 获取项目的badges + const badges: GitlabBadge[] = await service.gitlab.fetchProjectBadges( + projectDetail.id + ); + // 对badges进行补全,可能只有 name: "sonarqube_coverage" 的情况,把剩下的补全 + const badgeNames = badges.map((badge) => badge.name); + const badgeNameSet = new Set(badgeNames); + const badgeNameList = [ + "sonarqube_bugs", + "sonarqube_vulnerabilities", + "sonarqube_security_hotspots", + "sonarqube_coverage", + "sonarqube_quality_gate", + ]; + const diff = [...badgeNameList].filter((x) => !badgeNameSet.has(x)); + const newBadges: GitlabBadgeSetParams[] = diff.map((name) => { + const link_url = `https://sonarqube.mioffice.cn/dashboard?id=${sonarqubeId}`; + const image_url = + name !== "sonarqube_quality_gate" + ? `https://sonarqube.mioffice.cn/api/badges/measure?key=${sonarqubeId}&metric=${name}` + : `https://sonarqube.mioffice.cn/api/badges/gate?key=${sonarqubeId}`; + return { + id: projectDetail.id, + link_url, + image_url, + rendered_image_url: image_url, + rendered_link_url: link_url, + name, + }; + }); + return newBadges; +}; + +const addNewProjectBadge = async ( + badgeSetParamsList: GitlabBadgeSetParams[] +) => { + const chunkSize = 5; // 每次并发请求的数量 + for (let i = 0; i < badgeSetParamsList.length; i += chunkSize) { + const chunk = badgeSetParamsList.slice(i, i + chunkSize); + const res = await Promise.all( + chunk.map((badgeSetParams) => + service.gitlab.addProjectBadge(badgeSetParams) + ) + ); + console.log(res); + } +}; + +const main = async () => { + const errorList: string[] = []; + const badgeAddParamsList = await Promise.all( + projectList.map(async (projectName) => { + const projectDetail = await service.gitlab.fetchProjectDetails( + projectName + ); + if (!projectDetail) { + errorList.push(projectName); + return []; + } + return await getNewProjectBadge(projectDetail); + }) + ); + + await addNewProjectBadge(badgeAddParamsList.flat()); +}; + +main(); + +// [ +// { +// name: "sonarqube_bugs", +// link_url: "https://sonarqube.mioffice.cn/dashboard?id=miai-fe:fe:ai-voiceprint-fe", +// image_url: "https://sonarqube.mioffice.cn/api/badges/measure?key=miai-fe:fe:ai-voiceprint-fe&metric=bugs", +// rendered_link_url: "https://sonarqube.mioffice.cn/dashboard?id=miai-fe:fe:ai-voiceprint-fe", +// rendered_image_url: "https://sonarqube.mioffice.cn/api/badges/measure?key=miai-fe:fe:ai-voiceprint-fe&metric=bugs", +// id: 9725, +// kind: "project", +// }, { +// name: "sonarqube_vulnerabilities", +// link_url: "https://sonarqube.mioffice.cn/dashboard?id=miai-fe:fe:ai-shortcut-fe", +// image_url: "https://sonarqube.mioffice.cn/api/badges/measure?key=miai-fe:fe:ai-shortcut-fe&metric=vulnerabilities", +// rendered_link_url: "https://sonarqube.mioffice.cn/dashboard?id=miai-fe:fe:ai-shortcut-fe", +// rendered_image_url: "https://sonarqube.mioffice.cn/api/badges/measure?key=miai-fe:fe:ai-shortcut-fe&metric=vulnerabilities", +// id: 10943, +// kind: "project", +// }, { +// name: "sonarqube_security_hotspots", +// link_url: "https://sonarqube.mioffice.cn/dashboard?id=miai-fe:fe:ai-shortcut-fe", +// image_url: "https://sonarqube.mioffice.cn/api/badges/measure?key=miai-fe:fe:ai-shortcut-fe&metric=security_hotspots", +// rendered_link_url: "https://sonarqube.mioffice.cn/dashboard?id=miai-fe:fe:ai-shortcut-fe", +// rendered_image_url: "https://sonarqube.mioffice.cn/api/badges/measure?key=miai-fe:fe:ai-shortcut-fe&metric=security_hotspots", +// id: 10944, +// kind: "project", +// }, { +// name: "sonarqube_coverage", +// link_url: "https://sonarqube.mioffice.cn/dashboard?id=miai-fe:fe:ai-shortcut-fe", +// image_url: "https://sonarqube.mioffice.cn/api/badges/measure?key=miai-fe:fe:ai-shortcut-fe&metric=coverage", +// rendered_link_url: "https://sonarqube.mioffice.cn/dashboard?id=miai-fe:fe:ai-shortcut-fe", +// rendered_image_url: "https://sonarqube.mioffice.cn/api/badges/measure?key=miai-fe:fe:ai-shortcut-fe&metric=coverage", +// id: 10945, +// kind: "project", +// }, { +// name: "sonarqube_quality_gate", +// link_url: "https://sonarqube.mioffice.cn/dashboard?id=miai-fe:fe:ai-shortcut-fe", +// image_url: "https://sonarqube.mioffice.cn/api/badges/gate?key=miai-fe:fe:ai-shortcut-fe", +// rendered_link_url: "https://sonarqube.mioffice.cn/dashboard?id=miai-fe:fe:ai-shortcut-fe", +// rendered_image_url: "https://sonarqube.mioffice.cn/api/badges/gate?key=miai-fe:fe:ai-shortcut-fe", +// id: 10946, +// kind: "project", +// } +// ] diff --git a/badge/miai.ts b/badge/miai.ts new file mode 100644 index 0000000..6c52af1 --- /dev/null +++ b/badge/miai.ts @@ -0,0 +1,117 @@ +import service from "../service"; + +const projectList = [ + "miai-fe/fe/ai-admin-fe", + "miai-fe/fe/ai-operation-fe", + "miai-fe/fe/ai-dripback-fe", + "miai-fe/fe/ai-open-admin-fe", + "miai-fe/fe/ai-model-deployment-fe", + "miai-fe/fe/ai-workbench", + "miai-fe/fe/ai-review-fe", + "miai-fe/fe/cms", + "miai-fe/fe/xiaoai-open-Platform", + "miai-fe/fe/ai-robot-fe", + "miai-fe/fe/ai-scene-review-fe", + "miai-fe/fe/houyi", + "miai-fe/fe/kms", + "miai-fe/fe/ai-productive-fe", + "miai-fe/fe/ai-sliding-label-fe", + "miai-fe/fe/ai-label-control-fe", + "miai-fe/fe/asr-fe", + "miai-fe/fe/feedback-platform-fe", + "miai-fe/fe/statisfaction-evaluation-platform-fe", + "miai-fe/fe/ai-quality-score-fe", + "miai-fe/fe/wakeup", + "miai-fe/fe/ai-badcase-label-fe", + "miai-fe/fe/func-manager", + "miai-fe/service/ado-server", + "miai-fe/fe/ado-fe", + "miai-fe/pwa/ai-rn-domain", + "miai-fe/pwa/ai-ak-fe", + "miai-fe/fe/ai-user-info-fe", + "miai-fe/fe-infra/xiaoai-jssdk", + "miai-fe/fe-infra/ai-ui", + "miai-fe/fe/ai-class-sheducle-fe", + "miai-fe/service/ai-schedule-service", + "miai-fe/fe/ai-schedule-devtool-v3", + "miai-fe/ai-scenes-fe", + "miai-fe/activity/om-music-tone", + "miai-fe/activity/ug-guide-test", + "miai-fe/activity/om-mood-blindbox", + "miai-fe/activity/om-love-poem", + "miai-fe/fe/ai-introduce", + "miai-fe/fe/ai-phonecall-guider-fe", + "miai-fe/activity/om-spring-couplets", + "miai-fe/activity/ug-play-assistant", + "miai-fe/fe/ai-iot-introduce-fe", + "miai-fe/fe/ai-rookie-play-fe", + "miai-fe/fe/ai-custom-tts-fe", + "miai-fe/fe-infra/split-rpk-sdk", + "miai-fe/fe/ai-full-animation-template-fe", + "miai-fe/fe/ai-schedule-manager-fe", + "miai-fe/fe/ai-voiceprint-fe", + "miai-fe/fe/ai-shortcut-fe", +]; + +const getProjectId = async (projectName: string) => { + const res = await service.gitlab.fetchProjectDetails(projectName); + return res?.id; +}; + +const getNewProjectBadge = async ( + projectId: number +): Promise => { + const badges: GitlabBadge[] = await service.gitlab.fetchProjectBadges( + projectId + ); + + const replacePath = (value: string) => + value.replace( + "https://sonarqube.mioffice.cn", + "http://scan.sonarqube.xiaomi.srv" + ); + + return badges.map((badge: GitlabBadge) => ({ + id: projectId, + badge_id: badge.id, + link_url: replacePath(badge.link_url), + image_url: badge.image_url, + rendered_image_url: badge.rendered_image_url, + rendered_link_url: replacePath(badge.rendered_link_url), + })); +}; + +const setNewProjectBadge = async ( + badgeSetParamsList: GitlabBadgeSetParams[] +) => { + const chunkSize = 5; // 每次并发请求的数量 + for (let i = 0; i < badgeSetParamsList.length; i += chunkSize) { + const chunk = badgeSetParamsList.slice(i, i + chunkSize); + const res = await Promise.all( + chunk.map((badgeSetParams) => + service.gitlab.setProjectBadge(badgeSetParams) + ) + ); + console.log(res); + } +}; + +const main = async () => { + const errorList: string[] = []; + const badgeSetParamsList = await Promise.all( + projectList.map(async (projectName) => { + const projectId = await getProjectId(projectName); + if (!projectId) { + errorList.push(projectName); + return []; + } + return await getNewProjectBadge(projectId); + }) + ); + + await setNewProjectBadge(badgeSetParamsList.flat()); + + console.log("errorList", errorList); +}; + +main(); diff --git a/service/gitlab.ts b/service/gitlab.ts index 6e24746..d489a04 100644 --- a/service/gitlab.ts +++ b/service/gitlab.ts @@ -7,16 +7,16 @@ const BASE_URL = "https://git.n.xiaomi.com/api/v4"; const gitlabReq = async ( url: string, params: any, - defaultValue: any, + default_value: any, reqFunc: any = netTool.get ): Promise => { try { const response = (await reqFunc(url, params, AUTH_HEADER)) as T & GitlabError; - if (response.message === "404 Project Not Found") return defaultValue; + if (response.message === "404 Project Not Found") return default_value; return response; } catch { - return defaultValue; + return default_value; } }; @@ -72,22 +72,26 @@ const fetchProjectBadges = async (project_id: number) => { /** * 设置徽章 - * @param project_id - * @param badge_id - * @param new_badge + * @param badge */ -const setProjectBadge = async ( - project_id: number, - badge_id: number, - new_badge: GitlabBadge -) => { - const URL = `${BASE_URL}/projects/${project_id}/badges/${badge_id}`; - return gitlabReq(URL, new_badge, new_badge, netTool.put); +const setProjectBadge = async (badge: GitlabBadgeSetParams) => { + const URL = `${BASE_URL}/projects/${badge.id}/badges/${badge.badge_id}`; + return gitlabReq(URL, badge, null, netTool.put); +}; + +/** + * 添加徽章 + * @param badge + */ +const addProjectBadge = async (badge: GitlabBadgeSetParams) => { + const URL = `${BASE_URL}/projects/${badge.id}/badges`; + return gitlabReq(URL, badge, null, netTool.post); }; const gitlab = { fetchPipelines, setProjectBadge, + addProjectBadge, fetchProjectBadges, fetchProjectDetails, fetchPipelineDetails, diff --git a/service/typings.d.ts b/service/typings.d.ts index 91eb74d..1db3e0d 100644 --- a/service/typings.d.ts +++ b/service/typings.d.ts @@ -60,3 +60,12 @@ interface GitlabBadge { rendered_image_url: string; kind: "project" | "group"; } + +interface GitlabBadgeSetParams { + id: number; + badge_id?: number; + link_url: string; + image_url: string; + rendered_link_url: string; + rendered_image_url: string; +}