@taole/deploy-helper 1.0.0-beta.6 → 1.0.1
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/README.md +8 -8
- package/index.mjs +557 -204
- package/lib/login.mjs +167 -0
- package/lib/offlinePkg.mjs +314 -0
- package/lib/pipelineApi.mjs +364 -365
- package/lib/project.mjs +346 -0
- package/lib/upload.js +49 -0
- package/lib/util.mjs +101 -16
- package/modules/alibabacloud-devops-mcp-server/dist/operations/flow/pipeline.js +8 -1
- package/package.json +36 -31
- package/deploy.mjs +0 -203
- package/deploy2.mjs +0 -275
- package/util.mjs +0 -22
package/lib/project.mjs
ADDED
|
@@ -0,0 +1,346 @@
|
|
|
1
|
+
// 处理项目相关的操作
|
|
2
|
+
import { simpleGit } from "simple-git";
|
|
3
|
+
import path from "path";
|
|
4
|
+
import fs from "fs";
|
|
5
|
+
import archiver from "archiver";
|
|
6
|
+
import { log, getJsonConfig, runCmdAsync } from "./util.mjs";
|
|
7
|
+
import { getCache as getLoginCache } from "./login.mjs";
|
|
8
|
+
|
|
9
|
+
const isDev = false;
|
|
10
|
+
const apiHost = isDev ? "http://localhost:9000" : "https://fapi.tuwan.com";
|
|
11
|
+
|
|
12
|
+
function genArchive(outputPath, dir) {
|
|
13
|
+
return new Promise((resolve, reject) => {
|
|
14
|
+
const output = fs.createWriteStream(outputPath);
|
|
15
|
+
const archive = archiver("zip", {
|
|
16
|
+
zlib: { level: 1 }, // Sets the compression level.
|
|
17
|
+
});
|
|
18
|
+
archive.on("error", reject);
|
|
19
|
+
archive.on("finish", () => {
|
|
20
|
+
// console.log("genArchive finish");
|
|
21
|
+
setTimeout(() => {
|
|
22
|
+
// console.log("genArchive finish true");
|
|
23
|
+
resolve();
|
|
24
|
+
}, 300);
|
|
25
|
+
});
|
|
26
|
+
archive.pipe(output);
|
|
27
|
+
archive.directory(dir, false);
|
|
28
|
+
archive.finalize();
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
async function apiDeployProject(name, version, env, userCache) {
|
|
33
|
+
try {
|
|
34
|
+
const urlPath = `/h5projects/${name}/deploy`;
|
|
35
|
+
const res = await fetch(`${apiHost}${urlPath}`, {
|
|
36
|
+
method: "POST",
|
|
37
|
+
body: JSON.stringify({
|
|
38
|
+
name: name,
|
|
39
|
+
version: version,
|
|
40
|
+
env: env,
|
|
41
|
+
}),
|
|
42
|
+
headers: {
|
|
43
|
+
"Content-Type": "application/json",
|
|
44
|
+
Cookie: `Tuwan_Passport=${userCache.Tuwan_Passport}`,
|
|
45
|
+
},
|
|
46
|
+
});
|
|
47
|
+
const resJson = await res.json();
|
|
48
|
+
if (!res.ok) {
|
|
49
|
+
const error = (resJson && resJson.message) || "部署项目失败";
|
|
50
|
+
throw new Error(error);
|
|
51
|
+
}
|
|
52
|
+
return resJson;
|
|
53
|
+
} catch (error) {
|
|
54
|
+
const errorMessage = error.message || "部署项目失败";
|
|
55
|
+
throw new Error(errorMessage);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
async function apiCreateProject(name, userCache) {
|
|
60
|
+
try {
|
|
61
|
+
const res = await fetch(`${apiHost}/h5projects`, {
|
|
62
|
+
method: "POST",
|
|
63
|
+
body: JSON.stringify({
|
|
64
|
+
name: name,
|
|
65
|
+
}),
|
|
66
|
+
headers: {
|
|
67
|
+
"Content-Type": "application/json",
|
|
68
|
+
Cookie: `Tuwan_Passport=${userCache.Tuwan_Passport}`,
|
|
69
|
+
},
|
|
70
|
+
});
|
|
71
|
+
const resJson = await res.json();
|
|
72
|
+
if (!res.ok) {
|
|
73
|
+
const error = (resJson && resJson.message) || "创建项目失败";
|
|
74
|
+
throw new Error(error);
|
|
75
|
+
}
|
|
76
|
+
if (!resJson || resJson.name !== name) {
|
|
77
|
+
throw new Error(
|
|
78
|
+
`创建项目失败: 项目名称不匹配: ${resJson.name} !== ${name}`
|
|
79
|
+
);
|
|
80
|
+
}
|
|
81
|
+
return resJson;
|
|
82
|
+
} catch (error) {
|
|
83
|
+
throw new Error(`创建项目失败: ${error.message}`);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
async function apiPublishProject(name, version, distZipPath, userCache) {
|
|
88
|
+
const urlPath = `/h5projects/${name}/publish`;
|
|
89
|
+
const formData = new FormData();
|
|
90
|
+
formData.append("updaterUid", userCache.userInfo.uid);
|
|
91
|
+
formData.append("version", version);
|
|
92
|
+
formData.append(
|
|
93
|
+
"file",
|
|
94
|
+
new Blob([fs.readFileSync(distZipPath)], { type: "application/zip" }),
|
|
95
|
+
"dist.zip"
|
|
96
|
+
);
|
|
97
|
+
const res = await fetch(`${apiHost}${urlPath}`, {
|
|
98
|
+
method: "POST",
|
|
99
|
+
body: formData,
|
|
100
|
+
headers: {
|
|
101
|
+
Cookie: `Tuwan_Passport=${userCache.Tuwan_Passport}`,
|
|
102
|
+
},
|
|
103
|
+
});
|
|
104
|
+
const resJson = await res.json();
|
|
105
|
+
if (!res.ok) {
|
|
106
|
+
const error = (resJson && resJson.message) || "更新项目失败";
|
|
107
|
+
throw new Error(error);
|
|
108
|
+
}
|
|
109
|
+
return resJson;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
function patchVersion(version) {
|
|
113
|
+
const versions = version.split(".");
|
|
114
|
+
versions[versions.length - 1] = parseInt(versions[versions.length - 1]) + 1;
|
|
115
|
+
return versions.join(".");
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* 获取最新可以使用的版本号
|
|
120
|
+
*/
|
|
121
|
+
async function apiGetProjectVersion(name, userCache) {
|
|
122
|
+
const urlPath = `/h5projects/${name}/build/lasted`;
|
|
123
|
+
const res = await fetch(`${apiHost}${urlPath}`, {
|
|
124
|
+
headers: {
|
|
125
|
+
Cookie: `Tuwan_Passport=${userCache.Tuwan_Passport}`,
|
|
126
|
+
},
|
|
127
|
+
});
|
|
128
|
+
const resJson = await res.json();
|
|
129
|
+
if (!res.ok) {
|
|
130
|
+
if (res.status === 404) {
|
|
131
|
+
return "0.0.1";
|
|
132
|
+
}
|
|
133
|
+
const error = (resJson && resJson.message) || "获取项目版本失败";
|
|
134
|
+
throw new Error(error);
|
|
135
|
+
}
|
|
136
|
+
const version = resJson.version;
|
|
137
|
+
if (/^\d+\.\d+\.\d+$/.test(version)) {
|
|
138
|
+
return patchVersion(version);
|
|
139
|
+
}
|
|
140
|
+
throw new Error(`获取项目版本失败: ${version}`);
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
/**
|
|
144
|
+
* 创建项目
|
|
145
|
+
*/
|
|
146
|
+
export const cmdProjectCreate = async () => {
|
|
147
|
+
const name = process.argv[3];
|
|
148
|
+
const projectDir = path.join(process.cwd(), name);
|
|
149
|
+
if (!name) {
|
|
150
|
+
log("请输入项目名称");
|
|
151
|
+
process.exit(1);
|
|
152
|
+
}
|
|
153
|
+
if (!/^[a-zA-Z0-9-_]+$/.test(name)) {
|
|
154
|
+
log("项目名称只能包含字母、数字和-_");
|
|
155
|
+
process.exit(1);
|
|
156
|
+
}
|
|
157
|
+
// 不能是纯数字
|
|
158
|
+
if (/^\d+$/.test(name)) {
|
|
159
|
+
log("项目名称不能是纯数字");
|
|
160
|
+
process.exit(1);
|
|
161
|
+
}
|
|
162
|
+
if (fs.existsSync(projectDir)) {
|
|
163
|
+
log(`项目目录${projectDir}已存在`);
|
|
164
|
+
process.exit(1);
|
|
165
|
+
}
|
|
166
|
+
const userCache = await getLoginCache();
|
|
167
|
+
if (!userCache || !userCache.userInfo || !userCache.userInfo.uid) {
|
|
168
|
+
log("请先登录");
|
|
169
|
+
process.exit(1);
|
|
170
|
+
}
|
|
171
|
+
const createResult = await apiCreateProject(name, userCache);
|
|
172
|
+
const repoUrl = createResult.repoUrl;
|
|
173
|
+
log(`获得项目仓库地址: ${repoUrl}`);
|
|
174
|
+
const httpRepoUrl = repoUrl + ".git";
|
|
175
|
+
const sshRepoUrl = httpRepoUrl.replace(
|
|
176
|
+
"https://codeup.aliyun.com/",
|
|
177
|
+
"git@codeup.aliyun.com:"
|
|
178
|
+
);
|
|
179
|
+
// https://codeup.aliyun.com/69b3821af7b43e00d420cb32/Web-Act/demo2-cli.git
|
|
180
|
+
// https://codeup.aliyun.com/69b3821af7b43e00d420cb32/Web-Act/demo2-cli
|
|
181
|
+
// git@codeup.aliyun.com:69b3821af7b43e00d420cb32/Web-Act/demo2-cli.git
|
|
182
|
+
let git = simpleGit(process.cwd());
|
|
183
|
+
let sshFail = false;
|
|
184
|
+
try {
|
|
185
|
+
await git.clone(sshRepoUrl, name);
|
|
186
|
+
} catch (error) {
|
|
187
|
+
log(`使用SSH协议克隆失败, 尝试使用HTTP协议克隆`);
|
|
188
|
+
sshFail = true;
|
|
189
|
+
}
|
|
190
|
+
if (sshFail) {
|
|
191
|
+
try {
|
|
192
|
+
await git.clone(httpRepoUrl, name);
|
|
193
|
+
} catch (error) {
|
|
194
|
+
throw new Error(`克隆仓库失败`);
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
log(`项目创建成功, 项目目录: ${name}`);
|
|
198
|
+
git = simpleGit(projectDir);
|
|
199
|
+
const targetPackageJson = getJsonConfig(projectDir, "package.json");
|
|
200
|
+
targetPackageJson.name = name;
|
|
201
|
+
fs.writeFileSync(
|
|
202
|
+
path.join(projectDir, "package.json"),
|
|
203
|
+
JSON.stringify(targetPackageJson, null, 2)
|
|
204
|
+
);
|
|
205
|
+
log(`项目package.json覆盖成功`);
|
|
206
|
+
await git.add(".");
|
|
207
|
+
await git.commit(`-#DH-07 feat: 项目初始化`);
|
|
208
|
+
log(`请cd至项目目录: ${projectDir} 手动执行: npm install 安装依赖`);
|
|
209
|
+
process.exit(0);
|
|
210
|
+
};
|
|
211
|
+
|
|
212
|
+
/**
|
|
213
|
+
* 更新项目到H5平台
|
|
214
|
+
*/
|
|
215
|
+
|
|
216
|
+
export const cmdProjectPublish = async () => {
|
|
217
|
+
const env = process.argv[3];
|
|
218
|
+
if (!env) {
|
|
219
|
+
log("请输入环境: test, prod");
|
|
220
|
+
process.exit(1);
|
|
221
|
+
}
|
|
222
|
+
if (env !== "test" && env !== "prod") {
|
|
223
|
+
log("环境只能输入test或prod");
|
|
224
|
+
process.exit(1);
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
const git = simpleGit(process.cwd());
|
|
228
|
+
const gitStatus = await git.status();
|
|
229
|
+
if (!gitStatus.isClean()) {
|
|
230
|
+
log("工作区还有未提交的代码,请先提交代码");
|
|
231
|
+
process.exit(1);
|
|
232
|
+
}
|
|
233
|
+
const userCache = await getLoginCache();
|
|
234
|
+
if (!userCache || !userCache.userInfo || !userCache.userInfo.uid) {
|
|
235
|
+
log("请先登录");
|
|
236
|
+
process.exit(1);
|
|
237
|
+
}
|
|
238
|
+
const packageJson = getJsonConfig(process.cwd(), "package.json");
|
|
239
|
+
if (!packageJson || !packageJson.version || !packageJson.name) {
|
|
240
|
+
log("package.json或者其version字段或name字段不存在");
|
|
241
|
+
process.exit(1);
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
const newVersion = await apiGetProjectVersion(packageJson.name, userCache);
|
|
245
|
+
packageJson.version = newVersion;
|
|
246
|
+
fs.writeFileSync(
|
|
247
|
+
path.join(process.cwd(), "package.json"),
|
|
248
|
+
JSON.stringify(packageJson, null, 2)
|
|
249
|
+
);
|
|
250
|
+
log(`更新package.json版本号为: ${newVersion}`);
|
|
251
|
+
await git.add(".");
|
|
252
|
+
await git.commit(`-#DH-07 feat: 更新版本号为: ${newVersion}`);
|
|
253
|
+
await git.push();
|
|
254
|
+
log(`提交代码成功,开始构建项目`);
|
|
255
|
+
|
|
256
|
+
const buildCmd = "npm run build";
|
|
257
|
+
await runCmdAsync(buildCmd);
|
|
258
|
+
log(`构建项目成功,开始打包构建产物`);
|
|
259
|
+
const distPath = path.join(process.cwd(), "dist");
|
|
260
|
+
const distZipPath = path.join(process.cwd(), "dist.zip");
|
|
261
|
+
if (!fs.existsSync(distPath)) {
|
|
262
|
+
log("dist目录不存在");
|
|
263
|
+
process.exit(1);
|
|
264
|
+
}
|
|
265
|
+
// 把dist目录打包为zip包
|
|
266
|
+
if (fs.existsSync(distZipPath)) {
|
|
267
|
+
fs.unlinkSync(distZipPath);
|
|
268
|
+
}
|
|
269
|
+
await genArchive(distZipPath, distPath);
|
|
270
|
+
log(`dist目录打包为zip包: ${distZipPath}, 开始推送构建产物`);
|
|
271
|
+
const _publishResult = await apiPublishProject(
|
|
272
|
+
packageJson.name,
|
|
273
|
+
packageJson.version,
|
|
274
|
+
distZipPath,
|
|
275
|
+
userCache
|
|
276
|
+
);
|
|
277
|
+
log(`构建产物推送成功, 开始部署项目至${env}环境`);
|
|
278
|
+
const _deployResult = await apiDeployProject(
|
|
279
|
+
packageJson.name,
|
|
280
|
+
packageJson.version,
|
|
281
|
+
env,
|
|
282
|
+
userCache
|
|
283
|
+
);
|
|
284
|
+
log(`部署项目至${env}环境成功`);
|
|
285
|
+
process.exit(0);
|
|
286
|
+
};
|
|
287
|
+
|
|
288
|
+
|
|
289
|
+
export const cmdProjectPull = async () => {
|
|
290
|
+
const name = process.argv[3];
|
|
291
|
+
const projectDir = path.join(process.cwd(), name);
|
|
292
|
+
if (!name) {
|
|
293
|
+
log("请输入项目名称");
|
|
294
|
+
process.exit(1);
|
|
295
|
+
}
|
|
296
|
+
if (!/^[a-zA-Z0-9-_]+$/.test(name)) {
|
|
297
|
+
log("项目名称只能包含字母、数字和-_");
|
|
298
|
+
process.exit(1);
|
|
299
|
+
}
|
|
300
|
+
// 不能是纯数字
|
|
301
|
+
if (/^\d+$/.test(name)) {
|
|
302
|
+
log("项目名称不能是纯数字");
|
|
303
|
+
process.exit(1);
|
|
304
|
+
}
|
|
305
|
+
if (fs.existsSync(projectDir)) {
|
|
306
|
+
log(`项目目录${projectDir}已存在`);
|
|
307
|
+
process.exit(1);
|
|
308
|
+
}
|
|
309
|
+
const repoUrl = `https://codeup.aliyun.com/69b3821af7b43e00d420cb32/Web-Act/${name}`;
|
|
310
|
+
log(`项目仓库地址: ${repoUrl}`);
|
|
311
|
+
const httpRepoUrl = repoUrl + ".git";
|
|
312
|
+
const sshRepoUrl = httpRepoUrl.replace(
|
|
313
|
+
"https://codeup.aliyun.com/",
|
|
314
|
+
"git@codeup.aliyun.com:"
|
|
315
|
+
);
|
|
316
|
+
let git = simpleGit(process.cwd());
|
|
317
|
+
let sshFail = false;
|
|
318
|
+
try {
|
|
319
|
+
await git.clone(sshRepoUrl, name);
|
|
320
|
+
} catch (error) {
|
|
321
|
+
log(`使用SSH协议克隆失败, 尝试使用HTTP协议克隆`);
|
|
322
|
+
sshFail = true;
|
|
323
|
+
}
|
|
324
|
+
if (sshFail) {
|
|
325
|
+
try {
|
|
326
|
+
await git.clone(httpRepoUrl, name);
|
|
327
|
+
} catch (error) {
|
|
328
|
+
throw new Error(`克隆仓库失败`);
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
log(`项目拉取成功, 项目目录: ${name}`);
|
|
332
|
+
git = simpleGit(projectDir);
|
|
333
|
+
const targetPackageJson = getJsonConfig(projectDir, "package.json");
|
|
334
|
+
if(targetPackageJson.name !== name){
|
|
335
|
+
targetPackageJson.name = name;
|
|
336
|
+
fs.writeFileSync(
|
|
337
|
+
path.join(projectDir, "package.json"),
|
|
338
|
+
JSON.stringify(targetPackageJson, null, 2)
|
|
339
|
+
);
|
|
340
|
+
log(`项目package.json覆盖成功`);
|
|
341
|
+
await git.add(".");
|
|
342
|
+
await git.commit(`-#DH-07 feat: 项目初始化`);
|
|
343
|
+
}
|
|
344
|
+
log(`请cd至项目目录: ${projectDir} 进行后续开发`);
|
|
345
|
+
process.exit(0);
|
|
346
|
+
}
|
package/lib/upload.js
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import OSS from "ali-oss";
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
function UUIDNOCA() {
|
|
5
|
+
return "xxxxxxxxxxxxxxxxyxxxxxxxxxxxxxxx".replace(/[xy]/g, function (c) {
|
|
6
|
+
var r = (Math.random() * 16) | 0;
|
|
7
|
+
var v = c === "x" ? r : (r & 0x3) | 0x8;
|
|
8
|
+
return v.toString(16);
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
let keyConfig = null;
|
|
13
|
+
async function getKeyConfig(ossToken) {
|
|
14
|
+
if (keyConfig) {
|
|
15
|
+
return keyConfig;
|
|
16
|
+
}
|
|
17
|
+
const reqUrl = `https://u.tuwan.com/Oss/sts?token=${ossToken}`;
|
|
18
|
+
const res = await fetch(reqUrl);
|
|
19
|
+
const resText = await res.text();
|
|
20
|
+
let fmtJson = resText.substring(1, resText.length - 1).replace("'", '"');
|
|
21
|
+
const realData = JSON.parse(fmtJson).data;
|
|
22
|
+
keyConfig = realData;
|
|
23
|
+
return keyConfig;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
let ossClient = null;
|
|
27
|
+
async function getUploadConfig(ossToken) {
|
|
28
|
+
if (ossClient) {
|
|
29
|
+
return ossClient;
|
|
30
|
+
}
|
|
31
|
+
const keyConfig = await getKeyConfig(ossToken);
|
|
32
|
+
ossClient = new OSS({
|
|
33
|
+
endpoint: "oss-cn-qingdao.aliyuncs.com",
|
|
34
|
+
accessKeyId: keyConfig.AccessKeyId,
|
|
35
|
+
accessKeySecret: keyConfig.AccessKeySecret,
|
|
36
|
+
bucket: "tuwanpicshare",
|
|
37
|
+
stsToken: keyConfig.SecurityToken,
|
|
38
|
+
secure: true,
|
|
39
|
+
});
|
|
40
|
+
return ossClient;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
export async function uploadFile(ossToken, filePath, name) {
|
|
44
|
+
const str = filePath;
|
|
45
|
+
const ext = str.substr(str.lastIndexOf(".") + 1);
|
|
46
|
+
const fileName = `offlinepkg/${name || UUIDNOCA()}.${ext}`;
|
|
47
|
+
const ossClient = await getUploadConfig(ossToken);
|
|
48
|
+
return ossClient.put(fileName, filePath);
|
|
49
|
+
}
|
package/lib/util.mjs
CHANGED
|
@@ -1,17 +1,102 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
}
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
1
|
+
import fs from 'fs';
|
|
2
|
+
import { join } from "node:path"
|
|
3
|
+
import { homedir } from "node:os"
|
|
4
|
+
import { exec } from 'child_process';
|
|
5
|
+
|
|
6
|
+
let _isDebug = false;
|
|
7
|
+
export function setDebug(debug) {
|
|
8
|
+
_isDebug = debug;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export function isDebug() {
|
|
12
|
+
return _isDebug;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export function log(...args) {
|
|
16
|
+
if (_isDebug) {
|
|
17
|
+
// 打印时间
|
|
18
|
+
console.log(`[${new Date().toLocaleTimeString()}]`, ...args);
|
|
19
|
+
} else {
|
|
20
|
+
console.log(...args);
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export function getOssToken() {
|
|
25
|
+
let token = "";
|
|
26
|
+
token = process.env.TW_DH_OSS_TOKEN || ""
|
|
27
|
+
if (token) {
|
|
28
|
+
log(`将使用来自环境变量TW_DH_OSS_TOKEN的token`);
|
|
29
|
+
return token;
|
|
30
|
+
}
|
|
31
|
+
const userDeployHelperDir = join(homedir(), "deploy-helper.config.json");
|
|
32
|
+
if (fs.existsSync(userDeployHelperDir)) {
|
|
33
|
+
try {
|
|
34
|
+
const userDeployHelperConfig = JSON.parse(fs.readFileSync(userDeployHelperDir, "utf-8"));
|
|
35
|
+
token = userDeployHelperConfig.ossToken || "";
|
|
36
|
+
} catch (error) {
|
|
37
|
+
console.error(`读取${userDeployHelperDir}配置失败: ${error}`);
|
|
38
|
+
}
|
|
39
|
+
if (token) {
|
|
40
|
+
log(`将使用来自${userDeployHelperDir}的ossToken`);
|
|
41
|
+
return token;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
return token;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* 读取dh用户配置文件deploy-helper.config.json
|
|
49
|
+
* @returns {Object|null} 用户配置
|
|
50
|
+
*/
|
|
51
|
+
export function getUserDeployHelperConfig() {
|
|
52
|
+
const userDeployHelperDir = join(homedir(), "deploy-helper.config.json");
|
|
53
|
+
if (fs.existsSync(userDeployHelperDir)) {
|
|
54
|
+
try {
|
|
55
|
+
const userDeployHelperConfig = JSON.parse(fs.readFileSync(userDeployHelperDir, "utf-8"));
|
|
56
|
+
return userDeployHelperConfig;
|
|
57
|
+
} catch (error) {
|
|
58
|
+
console.error(`读取${userDeployHelperDir}配置失败: ${error}`);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
return null;
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* json配置
|
|
65
|
+
* @param {string} workDir 项目工作目录
|
|
66
|
+
* @returns {Object|null} 配置
|
|
67
|
+
*/
|
|
68
|
+
export function getJsonConfig(workDir, name) {
|
|
69
|
+
const filePath = join(workDir, name);
|
|
70
|
+
if (fs.existsSync(filePath)) {
|
|
71
|
+
try {
|
|
72
|
+
return JSON.parse(fs.readFileSync(filePath, "utf-8"));
|
|
73
|
+
} catch (_error) {
|
|
74
|
+
// pass
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
return null;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* 执行命令
|
|
82
|
+
* @param {*} cmd string 命令
|
|
83
|
+
* @param {*} options { cwd: string, env: object } 可选参数
|
|
84
|
+
* @returns Promise<string> 命令执行结果
|
|
85
|
+
*/
|
|
86
|
+
export async function runCmdAsync(cmd, options) {
|
|
87
|
+
log("执行命令:", cmd);
|
|
88
|
+
return new Promise((resolve, reject) => {
|
|
89
|
+
exec(cmd, options, (error, stdout, stderr) => {
|
|
90
|
+
if (error) {
|
|
91
|
+
reject(error);
|
|
92
|
+
}
|
|
93
|
+
if(stdout){
|
|
94
|
+
console.log(stdout);
|
|
95
|
+
}
|
|
96
|
+
if (stderr) {
|
|
97
|
+
console.error(stderr);
|
|
98
|
+
}
|
|
99
|
+
resolve(stdout);
|
|
100
|
+
});
|
|
101
|
+
});
|
|
17
102
|
}
|
|
@@ -52,7 +52,7 @@ export async function listPipelinesFunc(organizationId, options) {
|
|
|
52
52
|
queryParams.page = options.page;
|
|
53
53
|
}
|
|
54
54
|
const url = utils.buildUrl(baseUrl, queryParams);
|
|
55
|
-
|
|
55
|
+
let response = await utils.yunxiaoRequest(url, {
|
|
56
56
|
method: "GET",
|
|
57
57
|
});
|
|
58
58
|
const pagination = {
|
|
@@ -65,6 +65,13 @@ export async function listPipelinesFunc(organizationId, options) {
|
|
|
65
65
|
};
|
|
66
66
|
let items = [];
|
|
67
67
|
if (Array.isArray(response)) {
|
|
68
|
+
response = response.map((item) => ({
|
|
69
|
+
...item,
|
|
70
|
+
id: item.id || item.pipelineId,
|
|
71
|
+
name: item.name || item.pipelineName,
|
|
72
|
+
creatorAccountId: item.creatorAccountId || item.createAccountId,
|
|
73
|
+
createTime: item.createTime || item.createTime,
|
|
74
|
+
}))
|
|
68
75
|
items = response.map(item => PipelineListItemSchema.parse(item));
|
|
69
76
|
}
|
|
70
77
|
return {
|
package/package.json
CHANGED
|
@@ -1,31 +1,36 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "@taole/deploy-helper",
|
|
3
|
-
"version": "1.0.
|
|
4
|
-
"description": "脚本部署工具,用于将项目部署到测试环境或生产环境",
|
|
5
|
-
"main": "index.mjs",
|
|
6
|
-
"type": "module",
|
|
7
|
-
"
|
|
8
|
-
"
|
|
9
|
-
"
|
|
10
|
-
},
|
|
11
|
-
"
|
|
12
|
-
"
|
|
13
|
-
"
|
|
14
|
-
},
|
|
15
|
-
"
|
|
16
|
-
"
|
|
17
|
-
"
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
"
|
|
21
|
-
"
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
"
|
|
25
|
-
"
|
|
26
|
-
"
|
|
27
|
-
|
|
28
|
-
"
|
|
29
|
-
"
|
|
30
|
-
|
|
31
|
-
|
|
1
|
+
{
|
|
2
|
+
"name": "@taole/deploy-helper",
|
|
3
|
+
"version": "1.0.1",
|
|
4
|
+
"description": "脚本部署工具,用于将项目部署到测试环境或生产环境",
|
|
5
|
+
"main": "index.mjs",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"scripts": {
|
|
8
|
+
"start": "node index.mjs",
|
|
9
|
+
"test": "node test.mjs"
|
|
10
|
+
},
|
|
11
|
+
"bin": {
|
|
12
|
+
"deploy-helper": "index.mjs",
|
|
13
|
+
"dh": "index.mjs"
|
|
14
|
+
},
|
|
15
|
+
"publishConfig": {
|
|
16
|
+
"access": "public",
|
|
17
|
+
"registry": "https://registry.npmjs.org/"
|
|
18
|
+
},
|
|
19
|
+
"files": [
|
|
20
|
+
"index.mjs",
|
|
21
|
+
"lib",
|
|
22
|
+
"modules/alibabacloud-devops-mcp-server/dist"
|
|
23
|
+
],
|
|
24
|
+
"keywords": [],
|
|
25
|
+
"author": "",
|
|
26
|
+
"license": "ISC",
|
|
27
|
+
"dependencies": {
|
|
28
|
+
"ali-oss": "^6.23.0",
|
|
29
|
+
"alibabacloud-devops-mcp-server": "*",
|
|
30
|
+
"archiver": "^7.0.1",
|
|
31
|
+
"form-data": "^4.0.5",
|
|
32
|
+
"md5-file": "^5.0.0",
|
|
33
|
+
"node-scp": "^0.0.25",
|
|
34
|
+
"simple-git": "^3.28.0"
|
|
35
|
+
}
|
|
36
|
+
}
|