mirror of https://github.com/certd/certd
fix: 修复首次创建任务运行时不自动设置当前运行情况的bug
parent
8ed16b3ea2
commit
ecd83ee136
|
@ -12,7 +12,7 @@ import { RegistryItem } from "../registry/index.js";
|
||||||
import { Decorator } from "../decorator/index.js";
|
import { Decorator } from "../decorator/index.js";
|
||||||
import { IEmailService } from "../service/index.js";
|
import { IEmailService } from "../service/index.js";
|
||||||
import { FileStore } from "./file-store.js";
|
import { FileStore } from "./file-store.js";
|
||||||
import { hashUtils } from "../utils/index.js";
|
import { hashUtils, utils } from "../utils/index.js";
|
||||||
// import { TimeoutPromise } from "../utils/util.promise.js";
|
// import { TimeoutPromise } from "../utils/util.promise.js";
|
||||||
|
|
||||||
export type ExecutorOptions = {
|
export type ExecutorOptions = {
|
||||||
|
@ -276,6 +276,7 @@ export class Executor {
|
||||||
rootDir: this.options.fileRootDir,
|
rootDir: this.options.fileRootDir,
|
||||||
}),
|
}),
|
||||||
signal: this.abort.signal,
|
signal: this.abort.signal,
|
||||||
|
utils,
|
||||||
};
|
};
|
||||||
instance.setCtx(taskCtx);
|
instance.setCtx(taskCtx);
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,7 @@ import { IEmailService } from "../service/index.js";
|
||||||
import { IContext } from "../core/index.js";
|
import { IContext } from "../core/index.js";
|
||||||
import { ILogger, logger } from "../utils/index.js";
|
import { ILogger, logger } from "../utils/index.js";
|
||||||
import { HttpClient } from "../utils/util.request";
|
import { HttpClient } from "../utils/util.request";
|
||||||
|
import { utils } from "../utils/index.js";
|
||||||
export enum ContextScope {
|
export enum ContextScope {
|
||||||
global,
|
global,
|
||||||
pipeline,
|
pipeline,
|
||||||
|
@ -57,18 +57,32 @@ export type TaskResult = {
|
||||||
pipelineVars: Record<string, any>;
|
pipelineVars: Record<string, any>;
|
||||||
};
|
};
|
||||||
export type TaskInstanceContext = {
|
export type TaskInstanceContext = {
|
||||||
|
//流水线定义
|
||||||
pipeline: Pipeline;
|
pipeline: Pipeline;
|
||||||
|
//步骤定义
|
||||||
step: Step;
|
step: Step;
|
||||||
|
//日志
|
||||||
logger: Logger;
|
logger: Logger;
|
||||||
|
//当前步骤输入参数跟上一次执行比较是否有变化
|
||||||
inputChanged: boolean;
|
inputChanged: boolean;
|
||||||
|
//授权获取服务
|
||||||
accessService: IAccessService;
|
accessService: IAccessService;
|
||||||
|
//邮件服务
|
||||||
emailService: IEmailService;
|
emailService: IEmailService;
|
||||||
|
//流水线上下文
|
||||||
pipelineContext: IContext;
|
pipelineContext: IContext;
|
||||||
|
//用户上下文
|
||||||
userContext: IContext;
|
userContext: IContext;
|
||||||
|
//http请求客户端
|
||||||
http: HttpClient;
|
http: HttpClient;
|
||||||
|
//文件存储
|
||||||
fileStore: FileStore;
|
fileStore: FileStore;
|
||||||
|
//上一次执行结果状态
|
||||||
lastStatus?: Runnable;
|
lastStatus?: Runnable;
|
||||||
|
//用户取消信号
|
||||||
signal: AbortSignal;
|
signal: AbortSignal;
|
||||||
|
//工具类
|
||||||
|
utils: typeof utils;
|
||||||
};
|
};
|
||||||
|
|
||||||
export abstract class AbstractTaskPlugin implements ITaskPlugin {
|
export abstract class AbstractTaskPlugin implements ITaskPlugin {
|
||||||
|
|
|
@ -4,9 +4,19 @@ export * from "./util.request.js";
|
||||||
export * from "./util.log.js";
|
export * from "./util.log.js";
|
||||||
export * from "./util.file.js";
|
export * from "./util.file.js";
|
||||||
export * from "./util.sp.js";
|
export * from "./util.sp.js";
|
||||||
export * as promises from "./util.promise.js";
|
export * from "./util.promise.js";
|
||||||
export * from "./util.hash.js";
|
export * from "./util.hash.js";
|
||||||
|
import { sp } from "./util.sp.js";
|
||||||
|
import { hashUtils } from "./util.hash.js";
|
||||||
|
import { promises } from "./util.promise.js";
|
||||||
|
import { fileUtils } from "./util.file.js";
|
||||||
|
import _ from "lodash-es";
|
||||||
export const utils = {
|
export const utils = {
|
||||||
sleep,
|
sleep,
|
||||||
http,
|
http,
|
||||||
|
sp,
|
||||||
|
hash: hashUtils,
|
||||||
|
promises,
|
||||||
|
file: fileUtils,
|
||||||
|
_,
|
||||||
};
|
};
|
||||||
|
|
|
@ -24,3 +24,8 @@ export function safePromise<T>(callback: (resolve: (ret: T) => void, reject: (re
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const promises = {
|
||||||
|
TimeoutPromise,
|
||||||
|
safePromise,
|
||||||
|
};
|
||||||
|
|
|
@ -186,10 +186,15 @@ h1, h2, h3, h4, h5, h6 {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
.disabled{
|
|
||||||
color: #c7c7c7;
|
|
||||||
}
|
|
||||||
.deleted{
|
.deleted{
|
||||||
|
color: #c7c7c7;
|
||||||
//删除线
|
//删除线
|
||||||
text-decoration: line-through;
|
text-decoration: line-through;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.cursor-move{
|
||||||
|
cursor: move !important;
|
||||||
|
}
|
||||||
|
.cursor-pointer{
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
|
@ -51,11 +51,11 @@
|
||||||
<h4 class="title" :class="{ disabled: element.disabled, deleted: element.disabled }">{{ element.title }}</h4>
|
<h4 class="title" :class="{ disabled: element.disabled, deleted: element.disabled }">{{ element.title }}</h4>
|
||||||
</div>
|
</div>
|
||||||
<div class="action">
|
<div class="action">
|
||||||
<a key="disabled" @click="element.disabled = !!!element.disabled">{{ element.disabled ? "启用" : "禁用" }}</a>
|
|
||||||
<a key="edit" @click="stepEdit(currentTask, element, index)">编辑</a>
|
<a key="edit" @click="stepEdit(currentTask, element, index)">编辑</a>
|
||||||
<a key="edit" @click="stepCopy(currentTask, element, index)">复制</a>
|
<a key="edit" @click="stepCopy(currentTask, element, index)">复制</a>
|
||||||
<a key="remove" @click="stepDelete(currentTask, index)">删除</a>
|
<a key="remove" @click="stepDelete(currentTask, index)">删除</a>
|
||||||
<fs-icon v-plus class="icon-button handle" title="拖动排序" icon="ion:move-outline"></fs-icon>
|
<a key="disabled" @click="element.disabled = !!!element.disabled">{{ element.disabled ? "启用" : "禁用" }}</a>
|
||||||
|
<fs-icon v-plus class="icon-button handle cursor-move" title="拖动排序" icon="ion:move-outline"></fs-icon>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
@ -354,7 +354,7 @@ export default defineComponent({
|
||||||
await loadHistoryList();
|
await loadHistoryList();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!currentHistory.value) {
|
if (currentHistory.value != null) {
|
||||||
if (currentHistory.value.pipeline?.status?.status === "start") {
|
if (currentHistory.value.pipeline?.status?.status === "start") {
|
||||||
await loadCurrentHistoryDetail();
|
await loadCurrentHistoryDetail();
|
||||||
} else {
|
} else {
|
||||||
|
@ -614,6 +614,9 @@ export default defineComponent({
|
||||||
saveLoading.value = true;
|
saveLoading.value = true;
|
||||||
try {
|
try {
|
||||||
if (props.options.doSave) {
|
if (props.options.doSave) {
|
||||||
|
if (pipeline.value.version == null) {
|
||||||
|
pipeline.value.version = 0;
|
||||||
|
}
|
||||||
pipeline.value.version++;
|
pipeline.value.version++;
|
||||||
currentPipeline.value = pipeline.value;
|
currentPipeline.value = pipeline.value;
|
||||||
await props.options.doSave(pipeline.value);
|
await props.options.doSave(pipeline.value);
|
||||||
|
|
|
@ -1 +1,2 @@
|
||||||
export * from './plugin-k8s.js';
|
export * from './plugin-k8s.js';
|
||||||
|
export * from './plugin-script.js';
|
||||||
|
|
|
@ -0,0 +1,58 @@
|
||||||
|
import { AbstractTaskPlugin, IsTaskPlugin, pluginGroups, RunStrategy, TaskInput, TaskInstanceContext } from '@certd/pipeline';
|
||||||
|
import { CertInfo, CertReader } from '@certd/plugin-cert';
|
||||||
|
|
||||||
|
export type CustomScriptContext = {
|
||||||
|
CertReader: typeof CertReader;
|
||||||
|
self: CustomScriptPlugin;
|
||||||
|
} & TaskInstanceContext;
|
||||||
|
|
||||||
|
@IsTaskPlugin({
|
||||||
|
name: 'CustomScript',
|
||||||
|
title: '自定义js脚本',
|
||||||
|
desc: '测试',
|
||||||
|
group: pluginGroups.other.key,
|
||||||
|
default: {
|
||||||
|
strategy: {
|
||||||
|
runStrategy: RunStrategy.SkipWhenSucceed,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
export class CustomScriptPlugin extends AbstractTaskPlugin {
|
||||||
|
@TaskInput({
|
||||||
|
title: '脚本',
|
||||||
|
helper: '自定义js脚本',
|
||||||
|
component: {
|
||||||
|
name: 'a-textarea',
|
||||||
|
vModel: 'value',
|
||||||
|
rows: 10,
|
||||||
|
style: 'background-color: #000c17;color: #fafafa;',
|
||||||
|
},
|
||||||
|
required: true,
|
||||||
|
})
|
||||||
|
script!: string;
|
||||||
|
|
||||||
|
@TaskInput({
|
||||||
|
title: '域名证书',
|
||||||
|
helper: '请选择前置任务输出的域名证书',
|
||||||
|
component: {
|
||||||
|
name: 'pi-output-selector',
|
||||||
|
from: 'CertApply',
|
||||||
|
},
|
||||||
|
required: true,
|
||||||
|
})
|
||||||
|
cert!: CertInfo;
|
||||||
|
|
||||||
|
async onInstance() {}
|
||||||
|
async execute(): Promise<void> {
|
||||||
|
this.logger.info('执行自定义脚本:\n', this.script);
|
||||||
|
const ctx: CustomScriptContext = {
|
||||||
|
CertReader,
|
||||||
|
self: this,
|
||||||
|
...this.ctx,
|
||||||
|
};
|
||||||
|
const AsyncFunction = Object.getPrototypeOf(async () => {}).constructor;
|
||||||
|
const func = new AsyncFunction('ctx', this.script);
|
||||||
|
return await func(ctx);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
new CustomScriptPlugin();
|
Loading…
Reference in New Issue