diff --git a/packages/core/pipeline/src/core/executor.ts b/packages/core/pipeline/src/core/executor.ts index 55f6508c..8768014c 100644 --- a/packages/core/pipeline/src/core/executor.ts +++ b/packages/core/pipeline/src/core/executor.ts @@ -1,4 +1,4 @@ -import { ConcurrencyStrategy, Pipeline, ResultType, Runnable, RunStrategy, Stage, Step, Task } from "../d.ts"; +import { ConcurrencyStrategy, NotificationType, NotificationWhen, Pipeline, ResultType, Runnable, RunStrategy, Stage, Step, Task } from "../d.ts"; import _ from "lodash"; import { RunHistory, RunnableCollection } from "./run-history"; import { AbstractTaskPlugin, PluginDefine, pluginRegistry } from "../plugin"; @@ -10,6 +10,7 @@ import { request } from "../utils/util.request"; import { IAccessService } from "../access"; import { RegistryItem } from "../registry"; import { Decorator } from "../decorator"; +import { IEmailService } from "../service"; export type ExecutorOptions = { userId: any; @@ -17,6 +18,7 @@ export type ExecutorOptions = { storage: IStorage; onChanged: (history: RunHistory) => Promise; accessService: IAccessService; + emailService: IEmailService; }; export class Executor { pipeline: Pipeline; @@ -51,10 +53,13 @@ export class Executor { // 读取last this.runtime = new RunHistory(runtimeId, trigger, this.pipeline); this.logger.info(`pipeline.${this.pipeline.id} start`); + await this.notification("start"); await this.runWithHistory(this.pipeline, "pipeline", async () => { await this.runStages(this.pipeline); }); + await this.notification("success"); } catch (e) { + await this.notification("error"); this.logger.error("pipeline 执行失败", e); } finally { await this.pipelineContext.setObj("lastRuntime", this.runtime); @@ -203,4 +208,37 @@ export class Executor { this.runtime.context[stepOutputKey] = instance[key]; }); } + + async notification(when: NotificationWhen, error?: any) { + if (!this.pipeline.notifications) { + return; + } + let subject = ""; + let content = ""; + if (when === "start") { + subject = `【CertD】${this.pipeline.title} 开始执行,buildId:${this.runtime.id}`; + content = `【CertD】${this.pipeline.title} 开始执行,buildId:${this.runtime.id}`; + } else if (when === "success") { + subject = `【CertD】${this.pipeline.title} 执行成功,buildId:${this.runtime.id}`; + content = `【CertD】${this.pipeline.title} 执行成功,buildId:${this.runtime.id}`; + } else if (when === "error") { + subject = `【CertD】${this.pipeline.title} 执行失败,buildId:${this.runtime.id}`; + content = `
${error.message}
`; + } else { + return; + } + + for (const notification of this.pipeline.notifications) { + if (!notification.when.includes(when)) { + continue; + } + if (notification.type === "email") { + this.options.emailService?.send({ + subject, + content, + receivers: notification.options.receivers, + }); + } + } + } } diff --git a/packages/core/pipeline/src/index.ts b/packages/core/pipeline/src/index.ts index eba39c00..80292cf4 100644 --- a/packages/core/pipeline/src/index.ts +++ b/packages/core/pipeline/src/index.ts @@ -7,3 +7,4 @@ export * from "./plugin"; export * from "./utils"; export * from "./context"; export * from "./decorator"; +export * from "./service"; diff --git a/packages/core/pipeline/src/service/index.ts b/packages/core/pipeline/src/service/index.ts new file mode 100644 index 00000000..871a185b --- /dev/null +++ b/packages/core/pipeline/src/service/index.ts @@ -0,0 +1,9 @@ +export type EmailSend = { + subject: string; + content: string; + receivers: string[]; +}; + +export interface IEmailService { + send(email: EmailSend): Promise; +} diff --git a/packages/ui/certd-server/src/modules/system/controller/settings-controller.ts b/packages/ui/certd-server/src/modules/system/controller/settings-controller.ts new file mode 100644 index 00000000..d15901bd --- /dev/null +++ b/packages/ui/certd-server/src/modules/system/controller/settings-controller.ts @@ -0,0 +1,53 @@ +import { ALL, Body, Controller, Inject, Post, Provide, Query } from "@midwayjs/decorator"; +import { CrudController } from "../../../basic/crud-controller"; +import { SettingsService } from "../service/settings-service"; + +/** + */ +@Provide() +@Controller('/api/sys/settings') +export class SettingsController extends CrudController { + @Inject() + service: SettingsService; + + getService() { + return this.service; + } + + @Post('/page') + async page(@Body(ALL) body) { + body.query = body.query ?? {}; + body.query.userId = this.ctx.user.id; + return super.page(body); + } + + @Post('/list') + async list(@Body(ALL) body) { + body.userId = this.ctx.user.id; + return super.list(body); + } + + @Post('/add') + async add(@Body(ALL) bean) { + bean.userId = this.ctx.user.id; + return super.add(bean); + } + + @Post('/update') + async update(@Body(ALL) bean) { + await this.service.checkUserId(bean.id, this.ctx.user.id); + return super.update(bean); + } + @Post('/info') + async info(@Query('id') id) { + await this.service.checkUserId(id, this.ctx.user.id); + return super.info(id); + } + + @Post('/delete') + async delete(@Query('id') id) { + await this.service.checkUserId(id, this.ctx.user.id); + return super.delete(id); + } + +} diff --git a/packages/ui/certd-server/src/modules/system/entity/settings.ts b/packages/ui/certd-server/src/modules/system/entity/settings.ts new file mode 100644 index 00000000..ff68a002 --- /dev/null +++ b/packages/ui/certd-server/src/modules/system/entity/settings.ts @@ -0,0 +1,28 @@ +import { Column, Entity, PrimaryGeneratedColumn } from 'typeorm'; + +/** + */ +@Entity('sys_settings') +export class SettingsEntity { + @PrimaryGeneratedColumn() + id: number; + @Column({ name: 'user_id', comment: '用户id' }) + userId: number; + @Column({ comment: '名称', length: 100 }) + name: string; + @Column({ name: 'setting', comment: '设置', length: 1024, nullable: true }) + setting: string; + + @Column({ + name: 'create_time', + comment: '创建时间', + default: () => 'CURRENT_TIMESTAMP', + }) + createTime: Date; + @Column({ + name: 'update_time', + comment: '修改时间', + default: () => 'CURRENT_TIMESTAMP', + }) + updateTime: Date; +} diff --git a/packages/ui/certd-server/src/modules/system/service/settings-service.ts b/packages/ui/certd-server/src/modules/system/service/settings-service.ts new file mode 100644 index 00000000..0aedcaed --- /dev/null +++ b/packages/ui/certd-server/src/modules/system/service/settings-service.ts @@ -0,0 +1,33 @@ +import { Provide, Scope, ScopeEnum } from "@midwayjs/decorator"; +import { InjectEntityModel } from "@midwayjs/typeorm"; +import { Repository } from "typeorm"; +import { BaseService } from "../../../basic/base-service"; +import { SettingsEntity } from "../entity/settings"; + +/** + * 授权 + */ +@Provide() +@Scope(ScopeEnum.Singleton) +export class SettingsService + extends BaseService +{ + @InjectEntityModel(SettingsEntity) + repository: Repository; + + getRepository() { + return this.repository; + } + + async getById(id: any): Promise { + const entity = await this.info(id); + // const access = accessRegistry.get(entity.type); + const setting = JSON.parse(entity.setting); + return { + id: entity.id, + ...setting, + }; + } + + +}