feat: 初始化DevOps平台后端
This commit is contained in:
@@ -0,0 +1,103 @@
|
||||
import { Injectable } from '@nestjs/common';
|
||||
import { redactSensitive } from '../../common/security/redact-sensitive';
|
||||
import { DeployRunSummary } from '../../deploy-runs/deploy-run.types';
|
||||
import { WeComClient } from './wecom.client';
|
||||
|
||||
export type DeployNotificationEvent =
|
||||
| 'created'
|
||||
| 'queued'
|
||||
| 'succeeded'
|
||||
| 'failed'
|
||||
| 'canceled'
|
||||
| 'retried';
|
||||
|
||||
export type DeployNotificationResult = {
|
||||
status: 'sent' | 'skipped' | 'failed';
|
||||
channel: 'wecom';
|
||||
reason?: string;
|
||||
};
|
||||
|
||||
/**
|
||||
* 统一封装发布单企微通知,保证 webhook 只存在于后端配置边界内。
|
||||
*/
|
||||
@Injectable()
|
||||
export class DeployNotificationService {
|
||||
constructor(private readonly weComClient: WeComClient) {}
|
||||
|
||||
async sendDeployRunEvent(
|
||||
run: DeployRunSummary,
|
||||
event: DeployNotificationEvent,
|
||||
): Promise<DeployNotificationResult> {
|
||||
const health = this.weComClient.healthSummary();
|
||||
|
||||
if (health.status === 'not_configured') {
|
||||
return {
|
||||
status: 'skipped',
|
||||
channel: 'wecom',
|
||||
reason: health.message ?? 'WeCom webhook is not configured',
|
||||
};
|
||||
}
|
||||
|
||||
try {
|
||||
await this.weComClient.sendMarkdown({
|
||||
title: this.titleFor(event),
|
||||
markdown: this.markdownFor(run, event),
|
||||
});
|
||||
|
||||
return { status: 'sent', channel: 'wecom' };
|
||||
} catch (error) {
|
||||
return {
|
||||
status: 'failed',
|
||||
channel: 'wecom',
|
||||
reason:
|
||||
error instanceof Error
|
||||
? redactSensitive({ message: error.message }).message
|
||||
: 'Unknown WeCom notification error',
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
private titleFor(event: DeployNotificationEvent): string {
|
||||
if (event === 'canceled') {
|
||||
return 'DevOps 发布已取消';
|
||||
}
|
||||
|
||||
if (event === 'queued') {
|
||||
return 'DevOps 发布已进入 Jenkins 队列';
|
||||
}
|
||||
|
||||
if (event === 'succeeded') {
|
||||
return 'DevOps 发布成功';
|
||||
}
|
||||
|
||||
if (event === 'failed') {
|
||||
return 'DevOps 发布失败';
|
||||
}
|
||||
|
||||
if (event === 'retried') {
|
||||
return 'DevOps 发布已重试';
|
||||
}
|
||||
|
||||
return 'DevOps 发布已创建';
|
||||
}
|
||||
|
||||
private markdownFor(
|
||||
run: DeployRunSummary,
|
||||
event: DeployNotificationEvent,
|
||||
): string {
|
||||
return [
|
||||
`> 事件:${this.titleFor(event)}`,
|
||||
`> 项目:${run.projectKey}`,
|
||||
`> 环境:${run.environment}`,
|
||||
`> Ref:${run.ref}`,
|
||||
`> 状态:${run.status}`,
|
||||
`> 操作者:${run.operator}`,
|
||||
`> Run ID:${run.id}`,
|
||||
run.jenkinsQueueId ? `> Jenkins Queue:${run.jenkinsQueueId}` : undefined,
|
||||
run.jenkinsBuildNumber ? `> Jenkins Build:#${run.jenkinsBuildNumber}` : undefined,
|
||||
run.failureSummary ? `> 失败摘要:${run.failureSummary}` : undefined,
|
||||
]
|
||||
.filter(Boolean)
|
||||
.join('\n');
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user