zhaoyingbo e7dcd217fa
All checks were successful
CI Monitor MIflow / build-image (push) Successful in 42s
feat: 修复排序中的空值错误
修复了在排序过程中出现空值的错误,以确保代码的稳定性和正确性。
2024-08-02 03:11:06 +00:00

174 lines
4.9 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import db from "../../db"
import service from "../../service"
import netTool from "../../service/netTool"
import { EggMessage } from "../../types/eggMessage"
import { Gitlab } from "../../types/gitlab"
import { sec2minStr } from "../../utils/timeTools"
/**
* 判断是否是合并请求
* @param pipeline
* @returns
*/
const checkIsMergeCommit = (pipeline: Gitlab.PipelineEvent) => {
const regex = /^Merge branch '.*' into '.*'$/
return regex.test(pipeline.commit.title)
}
/**
* 判断是否是成功的CI
* @param pipeline
* @returns
*/
const checkIsSuccess = async (
pipeline: Gitlab.PipelineEvent,
stage?: string | null
) => {
/**
* 创建结果对象
* @param buildId 构建ID
* @param continueFlag 是否继续
* @returns 结果对象
*/
const makeResult = (buildId: string, continueFlag: boolean) => ({
buildId: continueFlag ? buildId : "",
continueFlag,
})
// 没有指定Stage则整个流水线成功即为成功
if (!stage)
return makeResult(
pipeline.builds
.sort((a, b) =>
(a.finished_at || "").localeCompare(b.finished_at || "")
)[0]
.id.toString(),
pipeline.object_attributes.status === "success"
)
// 指定了Stage该Stage是否全部成功
const builds = pipeline.builds.filter((build) => build.stage === stage)
// 没有该Stage的构建
if (builds.length === 0) return makeResult("", false)
// 有该Stage的构建但不全成功
if (!builds.every((build) => build.status === "success"))
return makeResult("", false)
// 按finished_at排序获取最后一个运行的id
const lastId = builds.sort((a, b) =>
(a.finished_at || "").localeCompare(b.finished_at || "")
)[0].id
// 该ID的通知是否已经发送过
const notify = await db.notify.getOne(lastId.toString())
if (notify) return makeResult("", false)
return makeResult(lastId.toString(), true)
}
/**
* 获取合并请求
* @param pipeline
* @returns
*/
const getMergeRequest = async (pipeline: Gitlab.PipelineEvent) => {
if (!checkIsMergeCommit(pipeline)) return null
const res = await service.gitlab.commit.getMr(
pipeline.project.id,
pipeline.object_attributes.sha
)
if (res.length === 0) return null
return res.find((mr) => mr.merge_commit_sha === pipeline.commit.id) || null
}
/**
* 获取用户信息
* @param pipeline
* @param mergeRequest
* @returns
*/
const getUserInfo = (
pipeline: Gitlab.PipelineEvent,
mergeRequest: Gitlab.MergeRequest | null
) => {
let participant = pipeline.user.name
const receiver = [pipeline.user.username]
// 有MR且用户不同
if (mergeRequest && mergeRequest.author.username !== pipeline.user.username) {
participant += `${mergeRequest.author.name}`
receiver.push(mergeRequest.author.username)
}
return { participant, receiver }
}
/**
* 获取机器人消息
* @param variable 模板变量
* @returns
*/
const getRobotMsg = async (variable: EggMessage.CardVariable) =>
JSON.stringify({
type: "template",
data: {
config: {
update_multi: true,
},
template_id: "ctp_AA36QafWyob2",
template_variable: variable,
},
})
/**
* 发送通知消息
* @param pipeline
* @param apiKey
* @returns
*/
const sendNotifyMsg = async (
pipeline: Gitlab.PipelineEvent,
apiKey: string,
params: URLSearchParams
) => {
const { continueFlag, buildId } = await checkIsSuccess(
pipeline,
params.get("stage")
)
// 只处理成功的CICD
if (!continueFlag) return netTool.ok()
// 获取对应的合并请求
const mergeRequest = await getMergeRequest(pipeline)
// 获取用户信息
const { participant, receiver } = getUserInfo(pipeline, mergeRequest)
// sonar的ID
const sonarParams = new URLSearchParams({
id: pipeline.project.path_with_namespace.replaceAll("/", ":"),
branch: pipeline.object_attributes.ref,
})
// 获取模板变量
const variable: EggMessage.CardVariable = {
project: pipeline.project.path_with_namespace,
project_link: pipeline.project.web_url,
pipeline: pipeline.object_attributes.id.toString(),
pipeline_link: `${pipeline.project.web_url}/-/pipelines`,
ref: pipeline.object_attributes.ref,
ref_link: `${pipeline.project.web_url}/-/commits/${pipeline.object_attributes.ref}`,
commit_user: pipeline.user.name,
duration: sec2minStr(pipeline.object_attributes.duration),
participant,
commit_message: pipeline.commit.title,
mr: mergeRequest ? mergeRequest.references.full : "无关联的MR",
mr_link: mergeRequest ? mergeRequest.web_url : "",
sonar_link: `https://sonarqube.mioffice.cn/dashboard?${sonarParams}`,
}
// 获取机器人消息
const robotMsg = await getRobotMsg(variable)
// 发送消息
service.message.byUserIdList(receiver, robotMsg, apiKey)
// 记录日志
await db.notify.create({ ...variable, build_id: buildId })
// 返回成功
return netTool.ok()
}
const managePipelineEvent = {
sendNotifyMsg,
}
export default managePipelineEvent