From 71461a04df743c273c0934494a814ba26e4dc2e2 Mon Sep 17 00:00:00 2001 From: zhaoyingbo Date: Mon, 1 Jul 2024 12:33:40 +0000 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=9B=B4=E6=96=B0GitLab=20API=E8=B0=83?= =?UTF-8?q?=E7=94=A8=E6=96=B9=E6=B3=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- controllers/managePipeLine/index.ts | 7 +- controllers/manageProject/index.ts | 4 +- controllers/manageRobot/index.ts | 7 +- service/egg.ts | 34 +++++++++ service/gitlab.ts | 81 +++++++++++++++++++++ service/index.ts | 106 ++-------------------------- service/netTool.ts | 98 +++++++++++++++++++++++++ 7 files changed, 230 insertions(+), 107 deletions(-) create mode 100644 service/egg.ts create mode 100644 service/gitlab.ts create mode 100644 service/netTool.ts diff --git a/controllers/managePipeLine/index.ts b/controllers/managePipeLine/index.ts index af61a45..ebd7f7a 100644 --- a/controllers/managePipeLine/index.ts +++ b/controllers/managePipeLine/index.ts @@ -19,7 +19,10 @@ const getFullPipelineList = async (project: ProjectRecordModel) => { let page = 1; let hasBeforeLatestTime = false; while (!hasBeforeLatestTime) { - const pipelines = await service.fetchPipelines(project.project_id, page++); + const pipelines = await service.gitlab.fetchPipelines( + project.project_id, + page++ + ); // 如果当前页没有数据,则直接跳出 if (pipelines.length === 0) break; pipelines.forEach((pipeline) => { @@ -32,7 +35,7 @@ const getFullPipelineList = async (project: ProjectRecordModel) => { } const fullPipelineDetailList = await Promise.all( fullPipelineList.map(({ project_id, id, created_at }) => - service.fetchPipelineDetails(project_id, id, created_at) + service.gitlab.fetchPipelineDetails(project_id, id, created_at) ) ); return fullPipelineDetailList.filter( diff --git a/controllers/manageProject/index.ts b/controllers/manageProject/index.ts index 7f43a69..2035217 100644 --- a/controllers/manageProject/index.ts +++ b/controllers/manageProject/index.ts @@ -6,7 +6,9 @@ import service from "../../service"; * 填充项目信息 */ const fillProj = async (project: ProjectRecordModel) => { - const projDetail = await service.fetchProjectDetails(project.project_id); + const projDetail = await service.gitlab.fetchProjectDetails( + project.project_id + ); if (!projDetail) { return project; } diff --git a/controllers/manageRobot/index.ts b/controllers/manageRobot/index.ts index ad1155b..fcb5a9f 100644 --- a/controllers/manageRobot/index.ts +++ b/controllers/manageRobot/index.ts @@ -121,7 +121,7 @@ const getRobotMsg = async () => * @param chat_id */ const sendCIReportByChatId = async (chat_id: string) => { - await service.sendMessage.byChatId(chat_id, await getRobotMsg()); + await service.egg.sendMessage.byChatId(chat_id, await getRobotMsg()); }; /** @@ -129,7 +129,10 @@ const sendCIReportByChatId = async (chat_id: string) => { * @returns */ const sendCIReportByCron = async () => - await service.sendMessage.byGroupId("52usf3w8l6z4vs1", await getRobotMsg()); + await service.egg.sendMessage.byGroupId( + "52usf3w8l6z4vs1", + await getRobotMsg() + ); const manageRobot = { sendCIReportByChatId, diff --git a/service/egg.ts b/service/egg.ts new file mode 100644 index 0000000..c266206 --- /dev/null +++ b/service/egg.ts @@ -0,0 +1,34 @@ +import netTool from "./netTool"; + +const sendMessage = async (body: any) => { + const URL = "https://egg.imoaix.cn/message"; + try { + const res = await netTool.post(URL, JSON.stringify(body)); + return res; + } catch { + return null; + } +}; + +sendMessage.byGroupId = async (group_id: string, content: string) => { + return sendMessage({ + group_id, + msg_type: "interactive", + content, + }); +}; + +sendMessage.byChatId = async (chat_id: string, content: string) => { + return sendMessage({ + receive_id: chat_id, + receive_id_type: "chat_id", + msg_type: "interactive", + content, + }); +}; + +const egg = { + sendMessage, +}; + +export default egg; diff --git a/service/gitlab.ts b/service/gitlab.ts new file mode 100644 index 0000000..0c08095 --- /dev/null +++ b/service/gitlab.ts @@ -0,0 +1,81 @@ +import netTool from "./netTool"; + +const AUTH_HEADER = { "PRIVATE-TOKEN": "Zd1UASPcMwVox5tNS6ep" }; + +const BASE_URL = "https://git.n.xiaomi.com/api/v4"; + +/** + * 获取项目详情 + * @param id + * @returns + */ +const fetchProjectDetails = async (id: number) => { + const URL = `${BASE_URL}/projects/${id}`; + try { + const response = (await netTool.get( + URL, + {}, + AUTH_HEADER + )) as GitlabProjDetail & GitlabError; + if (response.message === "404 Project Not Found") return null; + return response; + } catch { + return null; + } +}; + +/** + * 获取流水线列表 + * @param project_id + * @param page + * @returns + */ +const fetchPipelines = async (project_id: number, page = 1) => { + const URL = `${BASE_URL}/projects/${project_id}/pipelines`; + const params = { scope: "finished", per_page: 100, page }; + try { + const response = (await netTool.get( + URL, + params, + AUTH_HEADER + )) as GitlabPipeline[] & GitlabError; + if (response?.message === "404 Project Not Found") return []; + return response; + } catch { + return [] as GitlabPipeline[]; + } +}; + +/** + * 获取流水线详情 + * @param project_id + * @param pipeline_id + * @param created_at + * @returns + */ +const fetchPipelineDetails = async ( + project_id: number, + pipeline_id: number, + created_at: string +) => { + const URL = `${BASE_URL}/projects/${project_id}/pipelines/${pipeline_id}`; + try { + const response = (await netTool.get( + URL, + {}, + AUTH_HEADER + )) as GitlabPipelineDetail & GitlabError; + if (response.message === "404 Project Not Found") return null; + return { ...response, created_at }; + } catch { + return null; + } +}; + +const gitlab = { + fetchProjectDetails, + fetchPipelines, + fetchPipelineDetails, +}; + +export default gitlab; diff --git a/service/index.ts b/service/index.ts index d10087b..efa591c 100644 --- a/service/index.ts +++ b/service/index.ts @@ -1,107 +1,9 @@ -const fetchGetParams = { - method: "GET", - headers: { "PRIVATE-TOKEN": "Zd1UASPcMwVox5tNS6ep" }, -}; - -/** - * 获取项目详情 - * @param id 项目id - */ -const fetchProjectDetails = async (id: number) => { - try { - const response = await fetch( - `https://git.n.xiaomi.com/api/v4/projects/${id}`, - fetchGetParams - ); - const body = (await response.json()) as GitlabProjDetail; - if (body.message === "404 Project Not Found") return null; - return body; - } catch { - return null; - } -}; - -/** - * 获取流水线列表 - */ -const fetchPipelines = async (project_id: number, page = 1) => { - try { - const response = await fetch( - `https://git.n.xiaomi.com/api/v4/projects/${project_id}/pipelines?scope=finished&per_page=100&page=${page}`, - fetchGetParams - ); - const body = (await response.json()) as GitlabPipeline[] & GitlabError; - if (body?.message === "404 Project Not Found") return []; - return body; - } catch { - return [] as GitlabPipeline[]; - } -}; - -/** - * 获取流水线详情 - */ -const fetchPipelineDetails = async ( - project_id: number, - pipeline_id: number, - created_at: string -) => { - try { - const response = await fetch( - `https://git.n.xiaomi.com/api/v4/projects/${project_id}/pipelines/${pipeline_id}`, - fetchGetParams - ); - const body = (await response.json()) as GitlabPipelineDetail; - if (body.message === "404 Project Not Found") return null; - return { - ...body, - created_at, - }; - } catch { - return null; - } -}; - -const sendMessage = async (body: string) => { - try { - const response = await fetch("https://egg.imoaix.cn/message", { - method: "POST", - headers: { - "Content-Type": "application/json", - }, - body, - }); - const res = await response.json(); - return res; - } catch { - return null; - } -}; - -sendMessage.byGroupId = async (group_id: string, content: string) => { - const body = JSON.stringify({ - group_id, - msg_type: "interactive", - content, - }); - return sendMessage(body); -}; - -sendMessage.byChatId = async (chat_id: string, content: string) => { - const body = JSON.stringify({ - receive_id: chat_id, - receive_id_type: "chat_id", - msg_type: "interactive", - content, - }); - return sendMessage(body); -}; +import egg from "./egg"; +import gitlab from "./gitlab"; const service = { - fetchProjectDetails, - fetchPipelines, - fetchPipelineDetails, - sendMessage, + gitlab, + egg, }; export default service; diff --git a/service/netTool.ts b/service/netTool.ts new file mode 100644 index 0000000..256cbf3 --- /dev/null +++ b/service/netTool.ts @@ -0,0 +1,98 @@ +interface NetGetParams { + url: string; + method: string; + params?: any; + data?: any; + headers?: any; +} + +/** + * 打印请求日志 + * @param response + * @param method + * @param data + */ +const logResponse = async ( + response: Response, + method: string, + data: any, + headers: any +) => { + let responseData = null; + try { + responseData = await response.json(); + } catch (error) { + responseData = "parse to json error"; + } + const responseLog = { + ok: response.ok, + status: response.status, + statusText: response.statusText, + url: response.url, + method: method, + requestHeaders: headers, + responseHeaders: response.headers, + requestBody: data, + responseBody: responseData as any, + }; + console.log("🚀 ~ responseLog:", JSON.stringify(responseLog, null, 2)); + return responseLog; +}; + +const netTool = ({ + url, + method, + params, + data, + headers, +}: NetGetParams): Promise => { + let fullUrl = url; + if (params) { + if (typeof params === "string") { + fullUrl = `${url}?${params}`; + } else { + const queryString = new URLSearchParams(params).toString(); + fullUrl = `${url}?${queryString}`; + } + } + + return fetch(fullUrl, { + method, + body: JSON.stringify(data), + headers: { + "Content-Type": "application/json", + ...headers, + }, + }) + .then((response) => logResponse(response, method, data, headers)) + .then((responseLog) => { + if (!responseLog.ok) { + if (responseLog?.responseBody?.msg) { + throw new Error(responseLog.responseBody.msg); + } + throw new Error("网络响应异常"); + } + if (responseLog.responseBody === "parse to json error") { + throw new Error("解析响应数据异常"); + } + return responseLog.responseBody as T; + }); +}; + +netTool.get = (url: string, params?: any, headers?: any): Promise => + netTool({ url, method: "get", params, headers }); + +netTool.post = ( + url: string, + data?: any, + params?: any, + headers?: any +): Promise => netTool({ url, method: "post", data, params, headers }); + +netTool.del = (url: string, data: any, headers?: any): Promise => + netTool({ url, method: "delete", data, headers }); + +netTool.patch = (url: string, data: any, headers?: any): Promise => + netTool({ url, method: "patch", data, headers }); + +export default netTool;