tuyoo-devflow 0.1.32 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.js +2 -0
- package/dist/cli.js.map +1 -1
- package/dist/commands/pipeline/index.d.ts +2 -0
- package/dist/commands/pipeline/index.js +6 -0
- package/dist/commands/pipeline/index.js.map +1 -0
- package/dist/commands/pipeline/sync.d.ts +2 -0
- package/dist/commands/pipeline/sync.js +169 -0
- package/dist/commands/pipeline/sync.js.map +1 -0
- package/dist/core/jenkins/jobClient.d.ts +37 -0
- package/dist/core/jenkins/jobClient.js +147 -0
- package/dist/core/jenkins/jobClient.js.map +1 -0
- package/dist/core/jenkins/jobConfigXml.d.ts +27 -0
- package/dist/core/jenkins/jobConfigXml.js +231 -0
- package/dist/core/jenkins/jobConfigXml.js.map +1 -0
- package/dist/core/store/jenkinsCredentialStore.d.ts +12 -0
- package/dist/core/store/jenkinsCredentialStore.js +33 -0
- package/dist/core/store/jenkinsCredentialStore.js.map +1 -0
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
import { createRequire } from "node:module";
|
|
3
3
|
import { Command } from "commander";
|
|
4
4
|
import { registerAgentCommand } from "./commands/agent/index.js";
|
|
5
|
+
import { registerPipelineCommand } from "./commands/pipeline/index.js";
|
|
5
6
|
import { safeErrorMessage } from "./core/log/redact.js";
|
|
6
7
|
const require = createRequire(import.meta.url);
|
|
7
8
|
const pkg = require("../package.json");
|
|
@@ -12,6 +13,7 @@ async function bootstrap() {
|
|
|
12
13
|
.description("Tuyoo DevFlow CLI 工具集")
|
|
13
14
|
.version(pkg.version, "-V, --version", "输出版本号");
|
|
14
15
|
registerAgentCommand(program);
|
|
16
|
+
registerPipelineCommand(program);
|
|
15
17
|
await program.parseAsync(process.argv);
|
|
16
18
|
}
|
|
17
19
|
bootstrap().catch((error) => {
|
package/dist/cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.tsx"],"names":[],"mappings":";AACA,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAC;AACjE,OAAO,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAExD,MAAM,OAAO,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAC/C,MAAM,GAAG,GAAG,OAAO,CAAC,iBAAiB,CAAwB,CAAC;AAE9D,KAAK,UAAU,SAAS;IACtB,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAC;IAE9B,OAAO;SACJ,IAAI,CAAC,KAAK,CAAC;SACX,WAAW,CAAC,uBAAuB,CAAC;SACpC,OAAO,CAAC,GAAG,CAAC,OAAO,EAAE,eAAe,EAAE,OAAO,CAAC,CAAC;IAElD,oBAAoB,CAAC,OAAO,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.tsx"],"names":[],"mappings":";AACA,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAC;AACjE,OAAO,EAAE,uBAAuB,EAAE,MAAM,8BAA8B,CAAC;AACvE,OAAO,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAExD,MAAM,OAAO,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAC/C,MAAM,GAAG,GAAG,OAAO,CAAC,iBAAiB,CAAwB,CAAC;AAE9D,KAAK,UAAU,SAAS;IACtB,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAC;IAE9B,OAAO;SACJ,IAAI,CAAC,KAAK,CAAC;SACX,WAAW,CAAC,uBAAuB,CAAC;SACpC,OAAO,CAAC,GAAG,CAAC,OAAO,EAAE,eAAe,EAAE,OAAO,CAAC,CAAC;IAElD,oBAAoB,CAAC,OAAO,CAAC,CAAC;IAC9B,uBAAuB,CAAC,OAAO,CAAC,CAAC;IAEjC,MAAM,OAAO,CAAC,UAAU,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;AACzC,CAAC;AAED,SAAS,EAAE,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;IAC1B,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;IACrB,OAAO,CAAC,KAAK,CAAC,WAAW,gBAAgB,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;AACtD,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { registerPipelineSyncCommand } from "./sync.js";
|
|
2
|
+
export function registerPipelineCommand(program) {
|
|
3
|
+
const pipelineCommand = program.command("pipeline").description("Jenkins Pipeline job 管理命令");
|
|
4
|
+
registerPipelineSyncCommand(pipelineCommand);
|
|
5
|
+
}
|
|
6
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/commands/pipeline/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,2BAA2B,EAAE,MAAM,WAAW,CAAC;AAExD,MAAM,UAAU,uBAAuB,CAAC,OAAgB;IACtD,MAAM,eAAe,GAAG,OAAO,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,WAAW,CAAC,2BAA2B,CAAC,CAAC;IAC7F,2BAA2B,CAAC,eAAe,CAAC,CAAC;AAC/C,CAAC"}
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
import { confirm, input, password } from "@inquirer/prompts";
|
|
2
|
+
import fs from "fs-extra";
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
import { JenkinsJobClient, joinJenkinsFullName } from "../../core/jenkins/jobClient.js";
|
|
5
|
+
import { inspectJenkinsConfigXml, patchJenkinsConfigXml, } from "../../core/jenkins/jobConfigXml.js";
|
|
6
|
+
import { safeErrorMessage } from "../../core/log/redact.js";
|
|
7
|
+
import { loadJenkinsCredentialProfile, saveJenkinsCredentialProfile, } from "../../core/store/jenkinsCredentialStore.js";
|
|
8
|
+
function coerceScalar(value) {
|
|
9
|
+
const trimmed = value.trim();
|
|
10
|
+
if (trimmed === "true") {
|
|
11
|
+
return true;
|
|
12
|
+
}
|
|
13
|
+
if (trimmed === "false") {
|
|
14
|
+
return false;
|
|
15
|
+
}
|
|
16
|
+
if (/^-?\d+$/.test(trimmed)) {
|
|
17
|
+
return Number(trimmed);
|
|
18
|
+
}
|
|
19
|
+
return value;
|
|
20
|
+
}
|
|
21
|
+
function parseParamOptions(values) {
|
|
22
|
+
const params = {};
|
|
23
|
+
for (const raw of values ?? []) {
|
|
24
|
+
const index = raw.indexOf("=");
|
|
25
|
+
if (index <= 0) {
|
|
26
|
+
throw new Error(`参数格式错误: ${raw},应为 NAME=value`);
|
|
27
|
+
}
|
|
28
|
+
const name = raw.slice(0, index).trim();
|
|
29
|
+
const value = raw.slice(index + 1);
|
|
30
|
+
if (!name) {
|
|
31
|
+
throw new Error(`参数名不能为空: ${raw}`);
|
|
32
|
+
}
|
|
33
|
+
params[name] = coerceScalar(value);
|
|
34
|
+
}
|
|
35
|
+
return params;
|
|
36
|
+
}
|
|
37
|
+
async function readConfig(filePath) {
|
|
38
|
+
if (!filePath) {
|
|
39
|
+
return {};
|
|
40
|
+
}
|
|
41
|
+
const absPath = path.resolve(filePath);
|
|
42
|
+
const data = (await fs.readJson(absPath));
|
|
43
|
+
return data;
|
|
44
|
+
}
|
|
45
|
+
async function resolveRequired(label, value, promptMessage) {
|
|
46
|
+
if (value?.trim()) {
|
|
47
|
+
return value.trim();
|
|
48
|
+
}
|
|
49
|
+
return await input({
|
|
50
|
+
message: promptMessage,
|
|
51
|
+
validate(answer) {
|
|
52
|
+
return answer.trim().length > 0 ? true : `${label}不能为空`;
|
|
53
|
+
},
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
function printValidation(title, validation) {
|
|
57
|
+
console.log(title);
|
|
58
|
+
console.log(` displayName: ${validation.displayName ?? "(未设置)"}`);
|
|
59
|
+
console.log(` scriptPath: ${validation.scriptPath ?? "(未设置)"}`);
|
|
60
|
+
console.log(` scmBranch: ${validation.scmBranch ?? "(未设置)"}`);
|
|
61
|
+
console.log(` disabled: ${validation.disabled === undefined ? "(未设置)" : validation.disabled}`);
|
|
62
|
+
console.log(` parameters: ${validation.parameters.join(", ") || "(无)"}`);
|
|
63
|
+
}
|
|
64
|
+
export function registerPipelineSyncCommand(pipelineCommand) {
|
|
65
|
+
pipelineCommand
|
|
66
|
+
.command("sync")
|
|
67
|
+
.description("基于模板创建或更新 Jenkins Pipeline job")
|
|
68
|
+
.option("--config <path>", "JSON 配置文件")
|
|
69
|
+
.option("--jenkins-url <url>", "Jenkins URL")
|
|
70
|
+
.option("--username <name>", "Jenkins 用户名")
|
|
71
|
+
.option("--token <token>", "Jenkins API Token(不建议命令行明文传入)")
|
|
72
|
+
.option("--save-credentials", "保存 Jenkins URL/用户名/Token 到本机配置")
|
|
73
|
+
.option("--template-job <job>", "模板 job 全路径")
|
|
74
|
+
.option("--target-folder <folder>", "目标 Jenkins 文件夹全路径")
|
|
75
|
+
.option("--target-name <name>", "目标 job 名")
|
|
76
|
+
.option("--display-name <name>", "目标 job 展示名")
|
|
77
|
+
.option("--script-path <path>", "目标 Jenkinsfile scriptPath")
|
|
78
|
+
.option("--branch <branch>", "SCM 分支,例如 */lixin02")
|
|
79
|
+
.option("--param <NAME=value>", "覆盖已有 Jenkins 参数默认值,可重复", (value, previous = []) => [...previous, value])
|
|
80
|
+
.option("--remove-param <NAME>", "删除 Jenkins 上已废弃的参数,可重复", (value, previous = []) => [...previous, value])
|
|
81
|
+
.option("--apply", "实际创建或更新 Jenkins job;默认只 dry-run")
|
|
82
|
+
.option("--yes", "跳过 apply 前确认")
|
|
83
|
+
.option("--trigger", "同步成功后触发一次构建")
|
|
84
|
+
.action(async (options) => {
|
|
85
|
+
try {
|
|
86
|
+
const config = await readConfig(options.config);
|
|
87
|
+
const cachedCredential = await loadJenkinsCredentialProfile();
|
|
88
|
+
const jenkinsUrl = await resolveRequired("Jenkins URL", options.jenkinsUrl ?? config.jenkins?.url ?? cachedCredential?.jenkinsUrl, "请输入 Jenkins URL");
|
|
89
|
+
const username = await resolveRequired("Jenkins 用户名", options.username ?? config.jenkins?.username ?? cachedCredential?.username, "请输入 Jenkins 用户名");
|
|
90
|
+
const token = options.token ??
|
|
91
|
+
config.jenkins?.token ??
|
|
92
|
+
cachedCredential?.token ??
|
|
93
|
+
(await password({
|
|
94
|
+
message: "请输入 Jenkins API Token",
|
|
95
|
+
mask: "*",
|
|
96
|
+
validate(value) {
|
|
97
|
+
return value.trim().length > 0 ? true : "Token 不能为空";
|
|
98
|
+
},
|
|
99
|
+
}));
|
|
100
|
+
if (options.saveCredentials) {
|
|
101
|
+
await saveJenkinsCredentialProfile({ jenkinsUrl, username, token });
|
|
102
|
+
console.log("已保存 Jenkins 凭据到本机配置。");
|
|
103
|
+
}
|
|
104
|
+
const templateJob = await resolveRequired("模板 job", options.templateJob ?? config.templateJob, "请输入模板 job 全路径");
|
|
105
|
+
const targetFolder = await resolveRequired("目标文件夹", options.targetFolder ?? config.target?.folder, "请输入目标 Jenkins 文件夹全路径");
|
|
106
|
+
const targetName = await resolveRequired("目标 job 名", options.targetName ?? config.target?.name, "请输入目标 job 名");
|
|
107
|
+
const displayName = options.displayName ?? config.target?.displayName;
|
|
108
|
+
const scriptPath = await resolveRequired("scriptPath", options.scriptPath ?? config.pipeline?.scriptPath, "请输入目标 Jenkinsfile scriptPath");
|
|
109
|
+
const scmBranch = options.branch ?? config.scm?.branch;
|
|
110
|
+
const parameterOverrides = {
|
|
111
|
+
...(config.params ?? {}),
|
|
112
|
+
...parseParamOptions(options.param),
|
|
113
|
+
};
|
|
114
|
+
const removeParameters = [...new Set([...(config.removeParams ?? []), ...(options.removeParam ?? [])])]
|
|
115
|
+
.map((item) => item.trim())
|
|
116
|
+
.filter(Boolean);
|
|
117
|
+
const client = new JenkinsJobClient({ baseUrl: jenkinsUrl, username, token });
|
|
118
|
+
const targetJob = joinJenkinsFullName(targetFolder, targetName);
|
|
119
|
+
const targetExists = await client.jobExists(targetJob);
|
|
120
|
+
const sourceJob = targetExists ? targetJob : templateJob;
|
|
121
|
+
const sourceXml = await client.getJobConfig(sourceJob);
|
|
122
|
+
const patchedXml = patchJenkinsConfigXml(sourceXml, {
|
|
123
|
+
displayName,
|
|
124
|
+
scriptPath,
|
|
125
|
+
scmBranch,
|
|
126
|
+
parameterOverrides,
|
|
127
|
+
parameters: config.parameters,
|
|
128
|
+
removeParameters,
|
|
129
|
+
});
|
|
130
|
+
console.log(targetExists ? "目标 job 已存在,将执行更新流程。" : "目标 job 不存在,将基于模板创建。");
|
|
131
|
+
printValidation("生成后的关键配置:", inspectJenkinsConfigXml(patchedXml));
|
|
132
|
+
if (!options.apply) {
|
|
133
|
+
console.log("当前为 dry-run,未写入 Jenkins。确认无误后添加 --apply 执行。");
|
|
134
|
+
return;
|
|
135
|
+
}
|
|
136
|
+
const shouldApply = options.yes ??
|
|
137
|
+
(await confirm({
|
|
138
|
+
message: `${targetExists ? "更新" : "创建"} Jenkins job ${targetJob}?`,
|
|
139
|
+
default: false,
|
|
140
|
+
}));
|
|
141
|
+
if (!shouldApply) {
|
|
142
|
+
console.log("已取消写入 Jenkins。");
|
|
143
|
+
return;
|
|
144
|
+
}
|
|
145
|
+
if (targetExists) {
|
|
146
|
+
await client.updateJobConfig(targetJob, patchedXml);
|
|
147
|
+
console.log(`已更新 Jenkins job: ${targetJob}`);
|
|
148
|
+
}
|
|
149
|
+
else {
|
|
150
|
+
await client.createJob(targetFolder, targetName, patchedXml);
|
|
151
|
+
console.log(`已创建 Jenkins job: ${targetJob}`);
|
|
152
|
+
}
|
|
153
|
+
const finalInfo = await client.getJobInfo(targetJob, "name,displayName,url,buildable,color,disabled,nextBuildNumber");
|
|
154
|
+
const finalXml = await client.getJobConfig(targetJob);
|
|
155
|
+
printValidation("回读后的关键配置:", inspectJenkinsConfigXml(finalXml));
|
|
156
|
+
console.log(`Jenkins URL: ${finalInfo.url ?? "(未知)"}`);
|
|
157
|
+
console.log(`buildable: ${finalInfo.buildable}, disabled: ${finalInfo.disabled}, nextBuildNumber: ${finalInfo.nextBuildNumber}`);
|
|
158
|
+
if (options.trigger) {
|
|
159
|
+
const queue = await client.buildWithParameters(targetJob, config.triggerParams ?? {});
|
|
160
|
+
console.log(`已触发构建,队列地址: ${queue.queueUrl ?? "(Jenkins 未返回 Location)"}`);
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
catch (error) {
|
|
164
|
+
process.exitCode = 1;
|
|
165
|
+
console.error(`pipeline sync 执行失败: ${safeErrorMessage(error)}`);
|
|
166
|
+
}
|
|
167
|
+
});
|
|
168
|
+
}
|
|
169
|
+
//# sourceMappingURL=sync.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sync.js","sourceRoot":"","sources":["../../../src/commands/pipeline/sync.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
export interface JenkinsAuthOptions {
|
|
2
|
+
baseUrl: string;
|
|
3
|
+
username: string;
|
|
4
|
+
token: string;
|
|
5
|
+
}
|
|
6
|
+
export interface JenkinsJobInfo {
|
|
7
|
+
name: string;
|
|
8
|
+
displayName?: string;
|
|
9
|
+
url?: string;
|
|
10
|
+
buildable?: boolean;
|
|
11
|
+
color?: string;
|
|
12
|
+
disabled?: boolean;
|
|
13
|
+
nextBuildNumber?: number;
|
|
14
|
+
}
|
|
15
|
+
export interface JenkinsQueueInfo {
|
|
16
|
+
queueUrl?: string;
|
|
17
|
+
location?: string;
|
|
18
|
+
}
|
|
19
|
+
export declare function normalizeJenkinsBaseUrl(baseUrl: string): string;
|
|
20
|
+
export declare function toJenkinsJobPath(fullName: string): string;
|
|
21
|
+
export declare function joinJenkinsFullName(...parts: Array<string | undefined>): string;
|
|
22
|
+
export declare class JenkinsJobClient {
|
|
23
|
+
private readonly baseUrl;
|
|
24
|
+
private readonly username;
|
|
25
|
+
private readonly token;
|
|
26
|
+
private crumbHeader?;
|
|
27
|
+
constructor(options: JenkinsAuthOptions);
|
|
28
|
+
jobExists(fullName: string): Promise<boolean>;
|
|
29
|
+
getJobConfig(fullName: string): Promise<string>;
|
|
30
|
+
createJob(folderFullName: string, jobName: string, configXml: string): Promise<void>;
|
|
31
|
+
updateJobConfig(fullName: string, configXml: string): Promise<void>;
|
|
32
|
+
getJobInfo(fullName: string, tree?: string): Promise<JenkinsJobInfo>;
|
|
33
|
+
buildWithParameters(fullName: string, parameters: Record<string, string | boolean | number>): Promise<JenkinsQueueInfo>;
|
|
34
|
+
private authHeader;
|
|
35
|
+
private request;
|
|
36
|
+
private getCrumbHeader;
|
|
37
|
+
}
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
export function normalizeJenkinsBaseUrl(baseUrl) {
|
|
2
|
+
const trimmed = baseUrl.trim();
|
|
3
|
+
if (!trimmed) {
|
|
4
|
+
throw new Error("Jenkins URL 不能为空。");
|
|
5
|
+
}
|
|
6
|
+
return trimmed.endsWith("/") ? trimmed : `${trimmed}/`;
|
|
7
|
+
}
|
|
8
|
+
export function toJenkinsJobPath(fullName) {
|
|
9
|
+
const parts = fullName
|
|
10
|
+
.split("/")
|
|
11
|
+
.map((item) => item.trim())
|
|
12
|
+
.filter(Boolean);
|
|
13
|
+
if (parts.length === 0) {
|
|
14
|
+
throw new Error("Jenkins job 路径不能为空。");
|
|
15
|
+
}
|
|
16
|
+
return parts.map((item) => `job/${encodeURIComponent(item)}`).join("/");
|
|
17
|
+
}
|
|
18
|
+
export function joinJenkinsFullName(...parts) {
|
|
19
|
+
return parts
|
|
20
|
+
.flatMap((part) => (part ?? "").split("/"))
|
|
21
|
+
.map((item) => item.trim())
|
|
22
|
+
.filter(Boolean)
|
|
23
|
+
.join("/");
|
|
24
|
+
}
|
|
25
|
+
export class JenkinsJobClient {
|
|
26
|
+
baseUrl;
|
|
27
|
+
username;
|
|
28
|
+
token;
|
|
29
|
+
crumbHeader;
|
|
30
|
+
constructor(options) {
|
|
31
|
+
this.baseUrl = normalizeJenkinsBaseUrl(options.baseUrl);
|
|
32
|
+
this.username = options.username;
|
|
33
|
+
this.token = options.token;
|
|
34
|
+
if (!this.username.trim()) {
|
|
35
|
+
throw new Error("Jenkins 用户名不能为空。");
|
|
36
|
+
}
|
|
37
|
+
if (!this.token.trim()) {
|
|
38
|
+
throw new Error("Jenkins Token 不能为空。");
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
async jobExists(fullName) {
|
|
42
|
+
const response = await this.request(`${toJenkinsJobPath(fullName)}/api/json`, {
|
|
43
|
+
method: "GET",
|
|
44
|
+
allowNotFound: true,
|
|
45
|
+
});
|
|
46
|
+
return response.status !== 404;
|
|
47
|
+
}
|
|
48
|
+
async getJobConfig(fullName) {
|
|
49
|
+
const response = await this.request(`${toJenkinsJobPath(fullName)}/config.xml`, { method: "GET" });
|
|
50
|
+
return await response.text();
|
|
51
|
+
}
|
|
52
|
+
async createJob(folderFullName, jobName, configXml) {
|
|
53
|
+
if (!jobName.trim()) {
|
|
54
|
+
throw new Error("目标 job 名不能为空。");
|
|
55
|
+
}
|
|
56
|
+
const folderPath = folderFullName.trim() ? `${toJenkinsJobPath(folderFullName)}/` : "";
|
|
57
|
+
const response = await this.request(`${folderPath}createItem?name=${encodeURIComponent(jobName)}`, {
|
|
58
|
+
method: "POST",
|
|
59
|
+
body: configXml,
|
|
60
|
+
contentType: "application/xml; charset=UTF-8",
|
|
61
|
+
useCrumb: true,
|
|
62
|
+
});
|
|
63
|
+
await response.text();
|
|
64
|
+
}
|
|
65
|
+
async updateJobConfig(fullName, configXml) {
|
|
66
|
+
const response = await this.request(`${toJenkinsJobPath(fullName)}/config.xml`, {
|
|
67
|
+
method: "POST",
|
|
68
|
+
body: configXml,
|
|
69
|
+
contentType: "application/xml; charset=UTF-8",
|
|
70
|
+
useCrumb: true,
|
|
71
|
+
});
|
|
72
|
+
await response.text();
|
|
73
|
+
}
|
|
74
|
+
async getJobInfo(fullName, tree) {
|
|
75
|
+
const suffix = tree ? `?tree=${encodeURIComponent(tree)}` : "";
|
|
76
|
+
const response = await this.request(`${toJenkinsJobPath(fullName)}/api/json${suffix}`, { method: "GET" });
|
|
77
|
+
return (await response.json());
|
|
78
|
+
}
|
|
79
|
+
async buildWithParameters(fullName, parameters) {
|
|
80
|
+
const form = new URLSearchParams();
|
|
81
|
+
for (const [key, value] of Object.entries(parameters)) {
|
|
82
|
+
form.set(key, String(value));
|
|
83
|
+
}
|
|
84
|
+
const response = await this.request(`${toJenkinsJobPath(fullName)}/buildWithParameters`, {
|
|
85
|
+
method: "POST",
|
|
86
|
+
body: form.toString(),
|
|
87
|
+
contentType: "application/x-www-form-urlencoded; charset=UTF-8",
|
|
88
|
+
useCrumb: true,
|
|
89
|
+
});
|
|
90
|
+
await response.text();
|
|
91
|
+
return {
|
|
92
|
+
queueUrl: response.headers.get("location") ?? undefined,
|
|
93
|
+
location: response.headers.get("location") ?? undefined,
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
authHeader() {
|
|
97
|
+
return `Basic ${Buffer.from(`${this.username}:${this.token}`).toString("base64")}`;
|
|
98
|
+
}
|
|
99
|
+
async request(entry, options) {
|
|
100
|
+
const headers = {
|
|
101
|
+
Authorization: this.authHeader(),
|
|
102
|
+
};
|
|
103
|
+
if (options.contentType) {
|
|
104
|
+
headers["Content-Type"] = options.contentType;
|
|
105
|
+
}
|
|
106
|
+
if (options.useCrumb) {
|
|
107
|
+
const crumb = await this.getCrumbHeader();
|
|
108
|
+
if (crumb) {
|
|
109
|
+
headers[crumb.name] = crumb.value;
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
const response = await fetch(new URL(entry, this.baseUrl), {
|
|
113
|
+
method: options.method,
|
|
114
|
+
headers,
|
|
115
|
+
body: options.body,
|
|
116
|
+
});
|
|
117
|
+
if (options.allowNotFound && response.status === 404) {
|
|
118
|
+
return response;
|
|
119
|
+
}
|
|
120
|
+
if (!response.ok) {
|
|
121
|
+
const text = await response.text();
|
|
122
|
+
throw new Error(`Jenkins 请求失败: ${response.status} ${response.statusText}${text ? ` - ${text}` : ""}`);
|
|
123
|
+
}
|
|
124
|
+
return response;
|
|
125
|
+
}
|
|
126
|
+
async getCrumbHeader() {
|
|
127
|
+
if (this.crumbHeader) {
|
|
128
|
+
return this.crumbHeader;
|
|
129
|
+
}
|
|
130
|
+
const response = await fetch(new URL("crumbIssuer/api/json", this.baseUrl), {
|
|
131
|
+
method: "GET",
|
|
132
|
+
headers: {
|
|
133
|
+
Authorization: this.authHeader(),
|
|
134
|
+
},
|
|
135
|
+
});
|
|
136
|
+
if (response.status === 404 || !response.ok) {
|
|
137
|
+
return undefined;
|
|
138
|
+
}
|
|
139
|
+
const data = (await response.json());
|
|
140
|
+
if (!data.crumbRequestField || !data.crumb) {
|
|
141
|
+
return undefined;
|
|
142
|
+
}
|
|
143
|
+
this.crumbHeader = { name: data.crumbRequestField, value: data.crumb };
|
|
144
|
+
return this.crumbHeader;
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
//# sourceMappingURL=jobClient.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"jobClient.js","sourceRoot":"","sources":["../../../src/core/jenkins/jobClient.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
export type JenkinsParameterType = "boolean" | "string" | "persistentString" | "extendedChoice";
|
|
2
|
+
export interface JenkinsParameterSpec {
|
|
3
|
+
name: string;
|
|
4
|
+
type?: JenkinsParameterType;
|
|
5
|
+
description?: string;
|
|
6
|
+
defaultValue?: string | boolean | number;
|
|
7
|
+
value?: string;
|
|
8
|
+
choices?: string[];
|
|
9
|
+
multiSelect?: boolean;
|
|
10
|
+
}
|
|
11
|
+
export interface JenkinsConfigPatchOptions {
|
|
12
|
+
displayName?: string;
|
|
13
|
+
scriptPath?: string;
|
|
14
|
+
scmBranch?: string;
|
|
15
|
+
parameterOverrides?: Record<string, string | boolean | number>;
|
|
16
|
+
parameters?: JenkinsParameterSpec[];
|
|
17
|
+
removeParameters?: string[];
|
|
18
|
+
}
|
|
19
|
+
export interface JenkinsConfigValidation {
|
|
20
|
+
displayName?: string;
|
|
21
|
+
scriptPath?: string;
|
|
22
|
+
scmBranch?: string;
|
|
23
|
+
disabled?: boolean;
|
|
24
|
+
parameters: string[];
|
|
25
|
+
}
|
|
26
|
+
export declare function patchJenkinsConfigXml(xml: string, options: JenkinsConfigPatchOptions): string;
|
|
27
|
+
export declare function inspectJenkinsConfigXml(xml: string): JenkinsConfigValidation;
|
|
@@ -0,0 +1,231 @@
|
|
|
1
|
+
const PARAMETER_DEFINITIONS_OPEN = "<parameterDefinitions>";
|
|
2
|
+
const PARAMETER_DEFINITIONS_CLOSE = "</parameterDefinitions>";
|
|
3
|
+
function escapeXml(value) {
|
|
4
|
+
return value
|
|
5
|
+
.replace(/&/g, "&")
|
|
6
|
+
.replace(/</g, "<")
|
|
7
|
+
.replace(/>/g, ">")
|
|
8
|
+
.replace(/"/g, """)
|
|
9
|
+
.replace(/'/g, "'");
|
|
10
|
+
}
|
|
11
|
+
function toText(value, fallback = "") {
|
|
12
|
+
if (value === undefined) {
|
|
13
|
+
return fallback;
|
|
14
|
+
}
|
|
15
|
+
if (typeof value === "boolean") {
|
|
16
|
+
return value ? "true" : "false";
|
|
17
|
+
}
|
|
18
|
+
return String(value);
|
|
19
|
+
}
|
|
20
|
+
function replaceFirstElementText(xml, tag, value) {
|
|
21
|
+
const pattern = new RegExp(`(<${tag}(?:\\s[^>]*)?>)([\\s\\S]*?)(</${tag}>)`);
|
|
22
|
+
if (!pattern.test(xml)) {
|
|
23
|
+
return xml;
|
|
24
|
+
}
|
|
25
|
+
return xml.replace(pattern, `$1${escapeXml(value)}$3`);
|
|
26
|
+
}
|
|
27
|
+
function setOrInsertDisplayName(xml, displayName) {
|
|
28
|
+
if (/<displayName>/.test(xml)) {
|
|
29
|
+
return replaceFirstElementText(xml, "displayName", displayName);
|
|
30
|
+
}
|
|
31
|
+
return xml.replace(/(<description[\s\S]*?<\/description>)/, `$1\n <displayName>${escapeXml(displayName)}</displayName>`);
|
|
32
|
+
}
|
|
33
|
+
function findParameterBlock(xml, name) {
|
|
34
|
+
const definitionsStart = xml.indexOf(PARAMETER_DEFINITIONS_OPEN);
|
|
35
|
+
const definitionsEnd = xml.indexOf(PARAMETER_DEFINITIONS_CLOSE);
|
|
36
|
+
if (definitionsStart < 0 || definitionsEnd < 0 || definitionsEnd <= definitionsStart) {
|
|
37
|
+
return undefined;
|
|
38
|
+
}
|
|
39
|
+
const bodyStart = definitionsStart + PARAMETER_DEFINITIONS_OPEN.length;
|
|
40
|
+
const body = xml.slice(bodyStart, definitionsEnd);
|
|
41
|
+
const escapedName = name.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
42
|
+
const nameMatch = new RegExp(`<name>${escapedName}</name>`).exec(body);
|
|
43
|
+
if (!nameMatch?.index) {
|
|
44
|
+
return undefined;
|
|
45
|
+
}
|
|
46
|
+
const beforeName = body.slice(0, nameMatch.index);
|
|
47
|
+
const openMatch = /<([^>\s]+)(?:\s[^>]*)?>\s*$/.exec(beforeName);
|
|
48
|
+
if (!openMatch?.index) {
|
|
49
|
+
return undefined;
|
|
50
|
+
}
|
|
51
|
+
const tagName = openMatch[1];
|
|
52
|
+
const blockStartInBody = openMatch.index;
|
|
53
|
+
const closeText = `</${tagName}>`;
|
|
54
|
+
const blockEndInBody = body.indexOf(closeText, nameMatch.index);
|
|
55
|
+
if (blockEndInBody < 0) {
|
|
56
|
+
return undefined;
|
|
57
|
+
}
|
|
58
|
+
const start = bodyStart + blockStartInBody;
|
|
59
|
+
const end = bodyStart + blockEndInBody + closeText.length;
|
|
60
|
+
return { start, end, text: xml.slice(start, end) };
|
|
61
|
+
}
|
|
62
|
+
function replaceElementTextInBlock(block, tag, value) {
|
|
63
|
+
const pattern = new RegExp(`(<${tag}(?:\\s[^>]*)?>)([\\s\\S]*?)(</${tag}>)`);
|
|
64
|
+
if (!pattern.test(block)) {
|
|
65
|
+
return block.replace(/(<\/[^>]+>\s*)$/, ` <${tag}>${escapeXml(value)}</${tag}>\n$1`);
|
|
66
|
+
}
|
|
67
|
+
return block.replace(pattern, `$1${escapeXml(value)}$3`);
|
|
68
|
+
}
|
|
69
|
+
function patchParameterBlock(block, value) {
|
|
70
|
+
if (/<value>/.test(block)) {
|
|
71
|
+
const withValue = replaceElementTextInBlock(block, "value", toText(value));
|
|
72
|
+
return replaceElementTextInBlock(withValue, "defaultValue", toText(value));
|
|
73
|
+
}
|
|
74
|
+
return replaceElementTextInBlock(block, "defaultValue", toText(value));
|
|
75
|
+
}
|
|
76
|
+
function inferParameterType(value) {
|
|
77
|
+
return typeof value === "boolean" ? "boolean" : "string";
|
|
78
|
+
}
|
|
79
|
+
function buildParameterBlock(spec) {
|
|
80
|
+
const type = spec.type ?? inferParameterType(spec.defaultValue);
|
|
81
|
+
const description = escapeXml(spec.description ?? "");
|
|
82
|
+
const defaultValue = escapeXml(toText(spec.defaultValue));
|
|
83
|
+
const name = escapeXml(spec.name);
|
|
84
|
+
if (type === "boolean") {
|
|
85
|
+
return [
|
|
86
|
+
" <hudson.model.BooleanParameterDefinition>",
|
|
87
|
+
` <name>${name}</name>`,
|
|
88
|
+
` <description>${description}</description>`,
|
|
89
|
+
` <defaultValue>${defaultValue || "false"}</defaultValue>`,
|
|
90
|
+
" </hudson.model.BooleanParameterDefinition>",
|
|
91
|
+
].join("\n");
|
|
92
|
+
}
|
|
93
|
+
if (type === "extendedChoice") {
|
|
94
|
+
const value = escapeXml(spec.value ?? spec.choices?.join(",") ?? defaultValue);
|
|
95
|
+
return [
|
|
96
|
+
' <com.cwctravel.hudson.plugins.extended__choice__parameter.ExtendedChoiceParameterDefinition plugin="extended-choice-parameter@382.v5697b_32134e8">',
|
|
97
|
+
` <name>${name}</name>`,
|
|
98
|
+
` <description>${description}</description>`,
|
|
99
|
+
" <quoteValue>false</quoteValue>",
|
|
100
|
+
" <saveJSONParameterToFile>false</saveJSONParameterToFile>",
|
|
101
|
+
" <visibleItemCount>5</visibleItemCount>",
|
|
102
|
+
` <type>${spec.multiSelect ? "PT_MULTI_SELECT" : "PT_SINGLE_SELECT"}</type>`,
|
|
103
|
+
` <value>${value}</value>`,
|
|
104
|
+
` <defaultValue>${defaultValue}</defaultValue>`,
|
|
105
|
+
" <multiSelectDelimiter>,</multiSelectDelimiter>",
|
|
106
|
+
" </com.cwctravel.hudson.plugins.extended__choice__parameter.ExtendedChoiceParameterDefinition>",
|
|
107
|
+
].join("\n");
|
|
108
|
+
}
|
|
109
|
+
if (type === "persistentString") {
|
|
110
|
+
return [
|
|
111
|
+
' <com.gem.persistentparameter.PersistentStringParameterDefinition plugin="persistent-parameter@1.3">',
|
|
112
|
+
` <name>${name}</name>`,
|
|
113
|
+
` <description>${description}</description>`,
|
|
114
|
+
` <defaultValue>${defaultValue}</defaultValue>`,
|
|
115
|
+
" <successfulOnly>false</successfulOnly>",
|
|
116
|
+
" <trim>false</trim>",
|
|
117
|
+
" </com.gem.persistentparameter.PersistentStringParameterDefinition>",
|
|
118
|
+
].join("\n");
|
|
119
|
+
}
|
|
120
|
+
return [
|
|
121
|
+
" <hudson.model.StringParameterDefinition>",
|
|
122
|
+
` <name>${name}</name>`,
|
|
123
|
+
` <description>${description}</description>`,
|
|
124
|
+
` <defaultValue>${defaultValue}</defaultValue>`,
|
|
125
|
+
" <trim>false</trim>",
|
|
126
|
+
" </hudson.model.StringParameterDefinition>",
|
|
127
|
+
].join("\n");
|
|
128
|
+
}
|
|
129
|
+
function upsertParameter(xml, spec) {
|
|
130
|
+
if (!spec.name.trim()) {
|
|
131
|
+
throw new Error("参数名不能为空。");
|
|
132
|
+
}
|
|
133
|
+
const existing = findParameterBlock(xml, spec.name);
|
|
134
|
+
if (existing) {
|
|
135
|
+
let next = existing.text;
|
|
136
|
+
if (spec.description !== undefined) {
|
|
137
|
+
next = replaceElementTextInBlock(next, "description", spec.description);
|
|
138
|
+
}
|
|
139
|
+
if (spec.defaultValue !== undefined) {
|
|
140
|
+
next = patchParameterBlock(next, spec.defaultValue);
|
|
141
|
+
}
|
|
142
|
+
if (spec.value !== undefined) {
|
|
143
|
+
next = replaceElementTextInBlock(next, "value", spec.value);
|
|
144
|
+
}
|
|
145
|
+
return `${xml.slice(0, existing.start)}${next}${xml.slice(existing.end)}`;
|
|
146
|
+
}
|
|
147
|
+
const block = buildParameterBlock(spec);
|
|
148
|
+
const closeIndex = xml.indexOf(PARAMETER_DEFINITIONS_CLOSE);
|
|
149
|
+
if (closeIndex < 0 || xml.indexOf(PARAMETER_DEFINITIONS_OPEN) < 0) {
|
|
150
|
+
throw new Error("config.xml 中未找到 parameterDefinitions,无法新增参数。");
|
|
151
|
+
}
|
|
152
|
+
return `${xml.slice(0, closeIndex)}${block}\n ${xml.slice(closeIndex)}`;
|
|
153
|
+
}
|
|
154
|
+
function extractParameterNames(xml) {
|
|
155
|
+
const names = [];
|
|
156
|
+
const parameterDefinitions = xml.match(/<parameterDefinitions>([\s\S]*?)<\/parameterDefinitions>/)?.[1] ?? "";
|
|
157
|
+
for (const match of parameterDefinitions.matchAll(/<name>([\s\S]*?)<\/name>/g)) {
|
|
158
|
+
names.push(match[1]);
|
|
159
|
+
}
|
|
160
|
+
return names;
|
|
161
|
+
}
|
|
162
|
+
function removeParameter(xml, name) {
|
|
163
|
+
const existing = findParameterBlock(xml, name);
|
|
164
|
+
if (!existing) {
|
|
165
|
+
return xml;
|
|
166
|
+
}
|
|
167
|
+
const leadingWhitespace = xml.slice(0, existing.start).match(/[ \t]*$/)?.[0] ?? "";
|
|
168
|
+
const removalStart = existing.start - leadingWhitespace.length;
|
|
169
|
+
const removalEnd = xml.startsWith("\n", existing.end) ? existing.end + 1 : existing.end;
|
|
170
|
+
return `${xml.slice(0, removalStart)}${xml.slice(removalEnd)}`;
|
|
171
|
+
}
|
|
172
|
+
function patchParameterTracker(xml, additions, removals = []) {
|
|
173
|
+
const pattern = /(<org\.jenkinsci\.plugins\.pipeline\.modeldefinition\.actions\.DeclarativeJobPropertyTrackerAction[\s\S]*?<parameters>)([\s\S]*?)(<\/parameters>)/;
|
|
174
|
+
const current = extractParameterNames(xml);
|
|
175
|
+
const names = [...new Set([...current, ...additions])].filter((name) => !removals.includes(name));
|
|
176
|
+
if (!pattern.test(xml)) {
|
|
177
|
+
return xml;
|
|
178
|
+
}
|
|
179
|
+
const body = names.map((name) => `\n <string>${escapeXml(name)}</string>`).join("");
|
|
180
|
+
return xml.replace(pattern, `$1${body}\n $3`);
|
|
181
|
+
}
|
|
182
|
+
export function patchJenkinsConfigXml(xml, options) {
|
|
183
|
+
let next = xml;
|
|
184
|
+
if (options.displayName !== undefined) {
|
|
185
|
+
next = setOrInsertDisplayName(next, options.displayName);
|
|
186
|
+
}
|
|
187
|
+
if (options.scriptPath !== undefined) {
|
|
188
|
+
next = replaceFirstElementText(next, "scriptPath", options.scriptPath);
|
|
189
|
+
}
|
|
190
|
+
if (options.scmBranch !== undefined) {
|
|
191
|
+
next = next.replace(/(<branches>[\s\S]*?<hudson\.plugins\.git\.BranchSpec>[\s\S]*?<name>)([\s\S]*?)(<\/name>)/, `$1${escapeXml(options.scmBranch)}$3`);
|
|
192
|
+
}
|
|
193
|
+
const removeParameters = [...new Set(options.removeParameters ?? [])].filter(Boolean);
|
|
194
|
+
if (removeParameters.length > 0) {
|
|
195
|
+
for (const name of removeParameters) {
|
|
196
|
+
next = removeParameter(next, name);
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
const changedParameterNames = [];
|
|
200
|
+
for (const [name, value] of Object.entries(options.parameterOverrides ?? {})) {
|
|
201
|
+
const existing = findParameterBlock(next, name);
|
|
202
|
+
if (!existing) {
|
|
203
|
+
throw new Error(`未找到 Jenkins 参数: ${name}`);
|
|
204
|
+
}
|
|
205
|
+
const patched = patchParameterBlock(existing.text, value);
|
|
206
|
+
next = `${next.slice(0, existing.start)}${patched}${next.slice(existing.end)}`;
|
|
207
|
+
changedParameterNames.push(name);
|
|
208
|
+
}
|
|
209
|
+
for (const spec of options.parameters ?? []) {
|
|
210
|
+
next = upsertParameter(next, spec);
|
|
211
|
+
changedParameterNames.push(spec.name);
|
|
212
|
+
}
|
|
213
|
+
if (changedParameterNames.length > 0 || removeParameters.length > 0) {
|
|
214
|
+
next = patchParameterTracker(next, changedParameterNames, removeParameters);
|
|
215
|
+
}
|
|
216
|
+
return next;
|
|
217
|
+
}
|
|
218
|
+
export function inspectJenkinsConfigXml(xml) {
|
|
219
|
+
const displayName = xml.match(/<displayName>([\s\S]*?)<\/displayName>/)?.[1];
|
|
220
|
+
const scriptPath = xml.match(/<scriptPath>([\s\S]*?)<\/scriptPath>/)?.[1];
|
|
221
|
+
const scmBranch = xml.match(/<branches>[\s\S]*?<hudson\.plugins\.git\.BranchSpec>[\s\S]*?<name>([\s\S]*?)<\/name>/)?.[1];
|
|
222
|
+
const disabledText = xml.match(/<disabled>([\s\S]*?)<\/disabled>/)?.[1];
|
|
223
|
+
return {
|
|
224
|
+
displayName,
|
|
225
|
+
scriptPath,
|
|
226
|
+
scmBranch,
|
|
227
|
+
disabled: disabledText === undefined ? undefined : disabledText.trim() === "true",
|
|
228
|
+
parameters: extractParameterNames(xml),
|
|
229
|
+
};
|
|
230
|
+
}
|
|
231
|
+
//# sourceMappingURL=jobConfigXml.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"jobConfigXml.js","sourceRoot":"","sources":["../../../src/core/jenkins/jobConfigXml.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export interface JenkinsCredentialProfile {
|
|
2
|
+
jenkinsUrl: string;
|
|
3
|
+
username: string;
|
|
4
|
+
token: string;
|
|
5
|
+
updatedAt: string;
|
|
6
|
+
}
|
|
7
|
+
export declare function loadJenkinsCredentialProfile(): Promise<JenkinsCredentialProfile | null>;
|
|
8
|
+
export declare function saveJenkinsCredentialProfile(input: {
|
|
9
|
+
jenkinsUrl: string;
|
|
10
|
+
username: string;
|
|
11
|
+
token: string;
|
|
12
|
+
}): Promise<void>;
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import fs from "fs-extra";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import { getConfigDir } from "../platform.js";
|
|
4
|
+
function getCredentialFilePath() {
|
|
5
|
+
return path.join(getConfigDir(), "jenkins-credentials.json");
|
|
6
|
+
}
|
|
7
|
+
export async function loadJenkinsCredentialProfile() {
|
|
8
|
+
const filePath = getCredentialFilePath();
|
|
9
|
+
if (!(await fs.pathExists(filePath))) {
|
|
10
|
+
return null;
|
|
11
|
+
}
|
|
12
|
+
const data = (await fs.readJson(filePath));
|
|
13
|
+
if (!data.jenkinsUrl || !data.username || !data.token) {
|
|
14
|
+
return null;
|
|
15
|
+
}
|
|
16
|
+
return {
|
|
17
|
+
jenkinsUrl: data.jenkinsUrl,
|
|
18
|
+
username: data.username,
|
|
19
|
+
token: data.token,
|
|
20
|
+
updatedAt: data.updatedAt ?? "",
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
export async function saveJenkinsCredentialProfile(input) {
|
|
24
|
+
const filePath = getCredentialFilePath();
|
|
25
|
+
await fs.ensureDir(path.dirname(filePath));
|
|
26
|
+
await fs.writeJson(filePath, {
|
|
27
|
+
jenkinsUrl: input.jenkinsUrl,
|
|
28
|
+
username: input.username,
|
|
29
|
+
token: input.token,
|
|
30
|
+
updatedAt: new Date().toISOString(),
|
|
31
|
+
}, { spaces: 2 });
|
|
32
|
+
}
|
|
33
|
+
//# sourceMappingURL=jenkinsCredentialStore.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"jenkinsCredentialStore.js","sourceRoot":"","sources":["../../../src/core/store/jenkinsCredentialStore.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,UAAU,CAAC;AAC1B,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAS9C,SAAS,qBAAqB;IAC5B,OAAO,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,EAAE,0BAA0B,CAAC,CAAC;AAC/D,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,4BAA4B;IAChD,MAAM,QAAQ,GAAG,qBAAqB,EAAE,CAAC;IACzC,IAAI,CAAC,CAAC,MAAM,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC;QACrC,OAAO,IAAI,CAAC;IACd,CAAC;IACD,MAAM,IAAI,GAAG,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAsC,CAAC;IAChF,IAAI,CAAC,IAAI,CAAC,UAAU,IAAI,CAAC,IAAI,CAAC,QAAQ,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC;QACtD,OAAO,IAAI,CAAC;IACd,CAAC;IACD,OAAO;QACL,UAAU,EAAE,IAAI,CAAC,UAAU;QAC3B,QAAQ,EAAE,IAAI,CAAC,QAAQ;QACvB,KAAK,EAAE,IAAI,CAAC,KAAK;QACjB,SAAS,EAAE,IAAI,CAAC,SAAS,IAAI,EAAE;KAChC,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,4BAA4B,CAAC,KAIlD;IACC,MAAM,QAAQ,GAAG,qBAAqB,EAAE,CAAC;IACzC,MAAM,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC;IAC3C,MAAM,EAAE,CAAC,SAAS,CAChB,QAAQ,EACR;QACE,UAAU,EAAE,KAAK,CAAC,UAAU;QAC5B,QAAQ,EAAE,KAAK,CAAC,QAAQ;QACxB,KAAK,EAAE,KAAK,CAAC,KAAK;QAClB,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;KACpC,EACD,EAAE,MAAM,EAAE,CAAC,EAAE,CACd,CAAC;AACJ,CAAC"}
|