@taole/deploy-helper 0.4.1 → 0.5.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/index.mjs +81 -58
- package/lib/pipelineApi.mjs +77 -40
- package/package.json +2 -2
package/index.mjs
CHANGED
|
@@ -7,6 +7,12 @@ import { simpleGit } from 'simple-git';
|
|
|
7
7
|
import { homedir } from 'os'
|
|
8
8
|
import { runPipeline, checkYunxiaoToken, triggerPipeline } from './lib/pipelineApi.mjs';
|
|
9
9
|
import { setDebug, log } from './lib/util.mjs';
|
|
10
|
+
import path from 'path';
|
|
11
|
+
import { fileURLToPath } from 'url';
|
|
12
|
+
|
|
13
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
14
|
+
const __dirname = path.dirname(__filename);
|
|
15
|
+
|
|
10
16
|
|
|
11
17
|
const TEST_SERVER_HOST = "192.168.0.35";
|
|
12
18
|
/**
|
|
@@ -79,10 +85,15 @@ async function getScpClient() {
|
|
|
79
85
|
return scpClient;
|
|
80
86
|
}
|
|
81
87
|
|
|
82
|
-
|
|
88
|
+
async function getVersion() {
|
|
89
|
+
const packageJsonPath = join(__dirname, "package.json");
|
|
90
|
+
const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, "utf-8"));
|
|
91
|
+
return packageJson.version;
|
|
92
|
+
}
|
|
83
93
|
|
|
84
94
|
|
|
85
95
|
async function main() {
|
|
96
|
+
const version = await getVersion();
|
|
86
97
|
|
|
87
98
|
// process.argv.includes("--debug") ||
|
|
88
99
|
// 默认开启debug debug目前只是打印日志的时候额外打印时间
|
|
@@ -100,7 +111,7 @@ async function main() {
|
|
|
100
111
|
}
|
|
101
112
|
|
|
102
113
|
if (command === "help") {
|
|
103
|
-
console.log(`deploy-helper
|
|
114
|
+
console.log(`deploy-helper v${version}`);
|
|
104
115
|
console.log(`usage: deploy-helper [command]`);
|
|
105
116
|
console.log(`command: init 初始化配置`);
|
|
106
117
|
console.log(`command: prod 生产环境部署`);
|
|
@@ -109,11 +120,11 @@ async function main() {
|
|
|
109
120
|
console.log(`command: scp {file} {dest} 复制文件{file}到OfficialSite测试服务器{dest}`);
|
|
110
121
|
console.log(`command: scpevt {file} 复制文件{file}到events测试服务器{file}`);
|
|
111
122
|
console.log(`command: scpevt {file} {dest} 复制文件{file}到events测试服务器{dest}`);
|
|
112
|
-
console.log(`command: pipeline {pipelineName|pipelineId} 触发流水线{pipelineName|pipelineId}`);
|
|
123
|
+
console.log(`command: pipeline {pipelineName|pipelineId} [branch] 触发流水线{pipelineName|pipelineId}, 指定分支(可省略)`);
|
|
113
124
|
process.exit(0);
|
|
114
125
|
}
|
|
115
|
-
log(
|
|
116
|
-
|
|
126
|
+
log(`deploy-helper v${version} start`);
|
|
127
|
+
|
|
117
128
|
// 其他命令
|
|
118
129
|
if (command === "init") {
|
|
119
130
|
await initConfigJson();
|
|
@@ -162,11 +173,12 @@ async function main() {
|
|
|
162
173
|
log(`pipeline参数不能为空`);
|
|
163
174
|
process.exit(1);
|
|
164
175
|
}
|
|
176
|
+
const branch = process.argv[4] || "";
|
|
165
177
|
try {
|
|
166
|
-
await triggerPipeline(pipelineName, true);
|
|
178
|
+
await triggerPipeline(pipelineName, { waitResult: true, branch });
|
|
167
179
|
process.exit(0);
|
|
168
180
|
} catch (error) {
|
|
169
|
-
log(`触发流水线失败:
|
|
181
|
+
log(`触发流水线失败: `, error);
|
|
170
182
|
process.exit(1);
|
|
171
183
|
}
|
|
172
184
|
|
|
@@ -181,12 +193,6 @@ async function main() {
|
|
|
181
193
|
const config = await loadConfig();
|
|
182
194
|
// log(`config`, config);
|
|
183
195
|
|
|
184
|
-
// 检查配置格式
|
|
185
|
-
if (!config.assets || !config.assets.dest || !config.entry || !config.entry.dest) {
|
|
186
|
-
log(`配置格式错误, 请检查deploy.config.js或deploy.config.json`);
|
|
187
|
-
return;
|
|
188
|
-
}
|
|
189
|
-
|
|
190
196
|
const result = hasChangeMe(JSON.stringify(config));
|
|
191
197
|
if (result) {
|
|
192
198
|
log(`配置中存在默认值(CHANGE_ME), 请先修改配置`);
|
|
@@ -194,8 +200,10 @@ async function main() {
|
|
|
194
200
|
}
|
|
195
201
|
|
|
196
202
|
|
|
203
|
+
const needHandleAssets = config.assets && config.assets.dest;
|
|
204
|
+
|
|
197
205
|
// 需要处理entry
|
|
198
|
-
const needHandleEntry = mode === 'prod' || (mode === 'test' && !config.entry.onlyProd);
|
|
206
|
+
const needHandleEntry = config.entry && config.entry.dest && (mode === 'prod' || (mode === 'test' && !config.entry.onlyProd));
|
|
199
207
|
const entryTestBranch = (config.entry && config.entry.testBranch) || "test";
|
|
200
208
|
const entryProdBranch = (config.entry && config.entry.prodBranch) || "master";
|
|
201
209
|
const entryTargetBranch = mode === 'prod' ? entryProdBranch : entryTestBranch;
|
|
@@ -208,24 +216,34 @@ async function main() {
|
|
|
208
216
|
|
|
209
217
|
// 检查项目
|
|
210
218
|
// 1. 检查项目是否存在
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
if (
|
|
214
|
-
|
|
215
|
-
|
|
219
|
+
let assetsDest = null;
|
|
220
|
+
let entryDest = null;
|
|
221
|
+
if (needHandleAssets) {
|
|
222
|
+
assetsDest = join(workDir, config.assets.dest);
|
|
223
|
+
if (!fs.existsSync(assetsDest)) {
|
|
224
|
+
log(`assets.dest路径不存在: ${assetsDest}, 请先创建`);
|
|
225
|
+
process.exit(1);
|
|
226
|
+
}
|
|
216
227
|
}
|
|
217
228
|
// entry.dest
|
|
218
|
-
if (needHandleEntry
|
|
219
|
-
|
|
220
|
-
|
|
229
|
+
if (needHandleEntry) {
|
|
230
|
+
entryDest = join(workDir, config.entry.dest);
|
|
231
|
+
if (!fs.existsSync(entryDest)) {
|
|
232
|
+
log(`entry.dest路径不存在: ${entryDest}, 请先创建`);
|
|
233
|
+
process.exit(1);
|
|
234
|
+
}
|
|
221
235
|
}
|
|
222
236
|
|
|
223
237
|
// 2. 检查项目是否clean
|
|
224
|
-
|
|
225
|
-
let assetsStatus =
|
|
226
|
-
if (
|
|
227
|
-
|
|
228
|
-
|
|
238
|
+
let assetsGit = null;
|
|
239
|
+
let assetsStatus = null;
|
|
240
|
+
if (needHandleAssets) {
|
|
241
|
+
assetsGit = simpleGit(assetsDest);
|
|
242
|
+
assetsStatus = await assetsGit.status();
|
|
243
|
+
if (!assetsStatus.isClean()) {
|
|
244
|
+
log(`${assetsDest}目前有未提交内容, 请先处理`);
|
|
245
|
+
return;
|
|
246
|
+
}
|
|
229
247
|
}
|
|
230
248
|
|
|
231
249
|
let entryGit;
|
|
@@ -255,7 +273,7 @@ async function main() {
|
|
|
255
273
|
|
|
256
274
|
// 3. 检查assets项目分支,并切换至master分支
|
|
257
275
|
// assets项目固定使用master分支
|
|
258
|
-
if (assetsStatus.current !== "master") {
|
|
276
|
+
if (needHandleAssets && assetsStatus.current !== "master") {
|
|
259
277
|
log(`${assetsDest}当前分支不是master, 切换至master分支`);
|
|
260
278
|
await assetsGit.checkout("master");
|
|
261
279
|
log(`${assetsDest}切换至master分支成功`);
|
|
@@ -267,9 +285,11 @@ async function main() {
|
|
|
267
285
|
}
|
|
268
286
|
|
|
269
287
|
// 4. 执行git pull
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
288
|
+
if (assetsGit) {
|
|
289
|
+
log(`${assetsDest}执行git pull`);
|
|
290
|
+
await assetsGit.pull();
|
|
291
|
+
log(`${assetsDest} git pull done`);
|
|
292
|
+
}
|
|
273
293
|
if (entryGit) {
|
|
274
294
|
log(`${entryDest}执行git pull`);
|
|
275
295
|
await entryGit.pull();
|
|
@@ -278,24 +298,26 @@ async function main() {
|
|
|
278
298
|
|
|
279
299
|
// 5. 复制构建产物
|
|
280
300
|
// 5.1 复制assets
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
const
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
fs.
|
|
292
|
-
|
|
293
|
-
|
|
301
|
+
if (needHandleAssets) {
|
|
302
|
+
let assetsFilesCount = 0;
|
|
303
|
+
const assetsFiles = config.assets.files;
|
|
304
|
+
for (const [src, dest] of Object.entries(assetsFiles)) {
|
|
305
|
+
const srcPath = join(workDir, src);
|
|
306
|
+
if (!fs.existsSync(srcPath)) {
|
|
307
|
+
log(`${srcPath}不存在,请确认构建产物是否正确`);
|
|
308
|
+
return;
|
|
309
|
+
}
|
|
310
|
+
const destPath = join(assetsDest, dest);
|
|
311
|
+
if (fs.statSync(srcPath).isDirectory()) {
|
|
312
|
+
fs.cpSync(srcPath, destPath, { recursive: true });
|
|
313
|
+
} else {
|
|
314
|
+
fs.copyFileSync(srcPath, destPath);
|
|
315
|
+
}
|
|
316
|
+
log(`assets copy: ${srcPath} -> ${destPath}`);
|
|
317
|
+
assetsFilesCount++;
|
|
294
318
|
}
|
|
295
|
-
log(`assets copy
|
|
296
|
-
assetsFilesCount++;
|
|
319
|
+
// log(`assets copy done.`);
|
|
297
320
|
}
|
|
298
|
-
// log(`assets copy done.`);
|
|
299
321
|
// 5.2 复制entry
|
|
300
322
|
if (needHandleEntry) {
|
|
301
323
|
const entryFiles = config.entry.files;
|
|
@@ -319,18 +341,19 @@ async function main() {
|
|
|
319
341
|
// 6. 提交
|
|
320
342
|
let canPushAssets = false;
|
|
321
343
|
let canPushEntry = false;
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
344
|
+
if (needHandleAssets) {
|
|
345
|
+
assetsStatus = await assetsGit.status();
|
|
346
|
+
if (!assetsStatus.isClean()) {
|
|
347
|
+
canPushAssets = true;
|
|
348
|
+
await assetsGit.add(".");
|
|
349
|
+
const assetsCommit = `${config.assets.commit || "feat:部署资源文件"} by deploy-helper`;
|
|
350
|
+
const assetsCommitResult = await assetsGit.commit(assetsCommit);
|
|
351
|
+
log(`assets commit: ${assetsCommit}`);
|
|
352
|
+
log(`assets commit: ${JSON.stringify(assetsCommitResult.summary)}`);
|
|
353
|
+
} else {
|
|
354
|
+
log(`${assetsDest} 未发现修改内容,跳过提交`);
|
|
355
|
+
}
|
|
332
356
|
}
|
|
333
|
-
|
|
334
357
|
if (needHandleEntry) {
|
|
335
358
|
entryStatus = await entryGit.status();
|
|
336
359
|
if (!entryStatus.isClean()) {
|
package/lib/pipelineApi.mjs
CHANGED
|
@@ -26,27 +26,27 @@ function getCurrentJob(runDetail) {
|
|
|
26
26
|
const stages = runDetail.stages;
|
|
27
27
|
|
|
28
28
|
// 找到当前阶段
|
|
29
|
-
for(let i = 0; i < stages.length; i++) {
|
|
29
|
+
for (let i = 0; i < stages.length; i++) {
|
|
30
30
|
const stage = stages[i];
|
|
31
31
|
currentStage = stage;
|
|
32
32
|
const stageStatus = stage.stageInfo.status;
|
|
33
|
-
if(stageStatus === "RUNNING" || stageStatus === "WAITING" || stageStatus === "FAIL") {
|
|
33
|
+
if (stageStatus === "INIT" || stageStatus === "RUNNING" || stageStatus === "WAITING" || stageStatus === "FAIL") {
|
|
34
34
|
break;
|
|
35
35
|
}
|
|
36
36
|
}
|
|
37
37
|
|
|
38
|
-
if(currentStage) {
|
|
38
|
+
if (currentStage) {
|
|
39
39
|
const jobs = currentStage.stageInfo.jobs;
|
|
40
|
-
for(let i = 0; i < jobs.length; i++) {
|
|
40
|
+
for (let i = 0; i < jobs.length; i++) {
|
|
41
41
|
const job = jobs[i];
|
|
42
42
|
currentJob = job;
|
|
43
43
|
const jobStatus = job.status;
|
|
44
|
-
if(jobStatus === "RUNNING" || jobStatus === "WAITING" || jobStatus === "FAIL") {
|
|
44
|
+
if (jobStatus === "INIT" || jobStatus === "RUNNING" || jobStatus === "WAITING" || jobStatus === "FAIL") {
|
|
45
45
|
break;
|
|
46
46
|
}
|
|
47
47
|
}
|
|
48
48
|
}
|
|
49
|
-
return {stage: currentStage, job: currentJob};
|
|
49
|
+
return { stage: currentStage, job: currentJob };
|
|
50
50
|
}
|
|
51
51
|
|
|
52
52
|
/**
|
|
@@ -161,9 +161,9 @@ async function waitPipelineRunFinish(pipelineID, runId, interval = 5000) {
|
|
|
161
161
|
let runDetail = await getPipelineRunFunc(organizationId, pipelineID, runId);
|
|
162
162
|
let passFailedCount = 0;
|
|
163
163
|
let passFailedMaxCount = 3;
|
|
164
|
-
while (runDetail.status === "RUNNING" || runDetail.status === "WAITING") {
|
|
164
|
+
while (runDetail.status === "RUNNING" || runDetail.status === "WAITING" || runDetail.status === "INIT") {
|
|
165
165
|
const { stage, job } = getCurrentJob(runDetail);
|
|
166
|
-
log(`流水线执行状态: ${runDetail.status},阶段: ${stage.name},任务: ${job.name}
|
|
166
|
+
log(`流水线执行状态: ${runDetail.status},阶段: ${stage.name},任务: ${job.name},${interval / 1000}秒后再次查询`);
|
|
167
167
|
if (runDetail.status === "WAITING") {
|
|
168
168
|
if (stage && job) {
|
|
169
169
|
log(`尝试自动通过人工卡点`);
|
|
@@ -179,9 +179,8 @@ async function waitPipelineRunFinish(pipelineID, runId, interval = 5000) {
|
|
|
179
179
|
passFailedCount++;
|
|
180
180
|
log(`人工卡点通过失败`, error);
|
|
181
181
|
}
|
|
182
|
-
|
|
183
182
|
}
|
|
184
|
-
if(passFailedCount >= passFailedMaxCount) {
|
|
183
|
+
if (passFailedCount >= passFailedMaxCount) {
|
|
185
184
|
log(`人工卡点通过失败次数超过最大值, 放弃`);
|
|
186
185
|
break;
|
|
187
186
|
}
|
|
@@ -197,33 +196,78 @@ async function waitPipelineRunFinish(pipelineID, runId, interval = 5000) {
|
|
|
197
196
|
return runDetail;
|
|
198
197
|
}
|
|
199
198
|
|
|
199
|
+
/**
|
|
200
|
+
* 获取流水线信息和源码仓库信息, 不指定分支则不返回源码仓库信息
|
|
201
|
+
* @param {*} pipelineName 流水线名称或id
|
|
202
|
+
* @param {*} targetBranch 指定分支, 如果为空,则不指定分支
|
|
203
|
+
* @returns 流水线信息和源码仓库信息, 触发流水线参数
|
|
204
|
+
*/
|
|
205
|
+
async function getPipelineInfoDetail(pipelineName, targetBranch = ""){
|
|
206
|
+
let pipelineID = "";
|
|
207
|
+
let pipelineInfo = null;
|
|
208
|
+
let repoInfo = null;
|
|
209
|
+
let hasDetail = false;
|
|
210
|
+
if (/^\d+$/.test(pipelineName)) {
|
|
211
|
+
pipelineID = pipelineName;
|
|
212
|
+
pipelineInfo = await getPipelineFunc(organizationId, pipelineID);
|
|
213
|
+
pipelineInfo.id = pipelineID;
|
|
214
|
+
hasDetail = true;
|
|
215
|
+
} else {
|
|
216
|
+
const info = await getPipelineInfoByName(pipelineName);
|
|
217
|
+
pipelineInfo = info;
|
|
218
|
+
pipelineID = info.id;
|
|
219
|
+
hasDetail = false;
|
|
220
|
+
}
|
|
221
|
+
// 如果需要指定分支,则需要获取源码仓库信息
|
|
222
|
+
if (targetBranch) {
|
|
223
|
+
if (!hasDetail) {
|
|
224
|
+
pipelineInfo = await getPipelineFunc(organizationId, pipelineID);
|
|
225
|
+
pipelineInfo.id = pipelineID;
|
|
226
|
+
}
|
|
227
|
+
if (pipelineInfo && pipelineInfo.pipelineConfig && Array.isArray(pipelineInfo.pipelineConfig.sources)) {
|
|
228
|
+
repoInfo = pipelineInfo.pipelineConfig.sources[0];
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
if (targetBranch && !repoInfo) {
|
|
233
|
+
throw new Error(`未找到源码仓库信息,请检查流水线配置是否正确`);
|
|
234
|
+
}
|
|
235
|
+
const params = {
|
|
236
|
+
"envs": {
|
|
237
|
+
"Change_Log": "deploy-helper触发", // 此处不可以带空格,否则会报错
|
|
238
|
+
},
|
|
239
|
+
"needCreateBranch": false,
|
|
240
|
+
"comment": "triggered by deploy-helper"
|
|
241
|
+
}
|
|
242
|
+
if (targetBranch && repoInfo) {
|
|
243
|
+
params.runningBranchs = {
|
|
244
|
+
[`${repoInfo.data.repo}`]: targetBranch
|
|
245
|
+
}
|
|
246
|
+
log(`指定分支: ${targetBranch}, 源码仓库: ${repoInfo.data.repo}`);
|
|
247
|
+
}
|
|
248
|
+
const runParams = {
|
|
249
|
+
params: JSON.stringify(params)
|
|
250
|
+
};
|
|
251
|
+
return { pipelineInfo, repoInfo, runParams };
|
|
252
|
+
}
|
|
200
253
|
|
|
201
254
|
/**
|
|
202
255
|
* 触发流水线
|
|
203
256
|
* @param {*} pipelineName 流水线名称或id
|
|
204
257
|
* @param {*} waitResult 是否等待流水线执行完成
|
|
205
258
|
*/
|
|
206
|
-
export async function triggerPipeline(pipelineName,
|
|
259
|
+
export async function triggerPipeline(pipelineName, opts = {}) {
|
|
260
|
+
const { waitResult = false } = opts;
|
|
207
261
|
const yunxiaoToken = getYunxiaoToken({});
|
|
208
262
|
if (!yunxiaoToken) {
|
|
209
263
|
throw new Error(`未设置云效token, 请检查云效token是否正确`);
|
|
210
264
|
}
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
const pipelineInfo = await getPipelineFunc(organizationId, pipelineID);
|
|
216
|
-
name = pipelineInfo.name;
|
|
217
|
-
} else {
|
|
218
|
-
const pipelineInfo = await getPipelineInfoByName(pipelineName);
|
|
219
|
-
pipelineID = pipelineInfo.id;
|
|
220
|
-
name = pipelineInfo.name;
|
|
221
|
-
}
|
|
222
|
-
const runId = await createPipelineRunFunc(organizationId, pipelineID, {});
|
|
223
|
-
const pipelineRunDetailUrl = `https://flow.aliyun.com/pipelines/${pipelineID}/builds/${runId}`;
|
|
224
|
-
log(`流水线${name}[${pipelineID}]触发成功,流水线执行id: ${runId}, 流水线执行详情: ${pipelineRunDetailUrl}`);
|
|
265
|
+
const { pipelineInfo, runParams } = await getPipelineInfoDetail(pipelineName, opts.branch);
|
|
266
|
+
const runId = await createPipelineRunFunc(organizationId, pipelineInfo.id, runParams);
|
|
267
|
+
const pipelineRunDetailUrl = `https://flow.aliyun.com/pipelines/${pipelineInfo.id}/builds/${runId}`;
|
|
268
|
+
log(`流水线${pipelineInfo.name}[${pipelineInfo.id}]触发成功,流水线执行id: ${runId}, 流水线执行详情: ${pipelineRunDetailUrl}`);
|
|
225
269
|
if (waitResult) {
|
|
226
|
-
await waitPipelineRunFinish(
|
|
270
|
+
await waitPipelineRunFinish(pipelineInfo.id, runId);
|
|
227
271
|
}
|
|
228
272
|
}
|
|
229
273
|
|
|
@@ -261,15 +305,10 @@ export function checkYunxiaoToken(config, mode) {
|
|
|
261
305
|
|
|
262
306
|
async function runSinglePipeline(pipeline, index, total) {
|
|
263
307
|
log(`开始处理流水线: ${pipeline.name}, 当前是第${index + 1}个, 总共${total}个`);
|
|
264
|
-
|
|
265
|
-
if (!pipelineId) {
|
|
266
|
-
// 获取流水线信息
|
|
267
|
-
const pipelineInfo = await getPipelineInfoByName(pipeline.name);
|
|
268
|
-
pipelineId = pipelineInfo.id;
|
|
269
|
-
}
|
|
270
|
-
log(`流水线${pipeline.name}的id: ${pipelineId}`);
|
|
308
|
+
const { pipelineInfo, runParams } = await getPipelineInfoDetail(pipeline.id || pipeline.name, pipeline.branch);
|
|
271
309
|
|
|
272
310
|
// 处理分支强推的问题
|
|
311
|
+
// 将要废弃force2Branch这个配置
|
|
273
312
|
const force2Branch = pipeline.force2Branch;
|
|
274
313
|
if (force2Branch && force2Branch.src && force2Branch.dest) {
|
|
275
314
|
let repo = pipeline.repo || "./";
|
|
@@ -296,13 +335,11 @@ async function runSinglePipeline(pipeline, index, total) {
|
|
|
296
335
|
await git.raw("push", "origin", `${force2Branch.src}:${force2Branch.dest}`, "--force");
|
|
297
336
|
log(`仓库${repo}强推${force2Branch.src}到${force2Branch.dest}完成`);
|
|
298
337
|
}
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
if(pipeline.waitResult) {
|
|
305
|
-
await waitPipelineRunFinish(pipelineId, runId);
|
|
338
|
+
const runId = await createPipelineRunFunc(organizationId, pipelineInfo.id, runParams);
|
|
339
|
+
const piplineRunDetailUrl = `https://flow.aliyun.com/pipelines/${pipelineInfo.id}/builds/${runId}`;
|
|
340
|
+
log(`流水线${pipelineInfo.name}触发成功,流水线执行id: ${runId}, 流水线执行详情: ${piplineRunDetailUrl}`);
|
|
341
|
+
if (pipeline.waitResult) {
|
|
342
|
+
await waitPipelineRunFinish(pipelineInfo.id, runId);
|
|
306
343
|
}
|
|
307
344
|
}
|
|
308
345
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@taole/deploy-helper",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.1",
|
|
4
4
|
"description": "脚本部署工具,用于将项目部署到测试环境或生产环境",
|
|
5
5
|
"main": "index.mjs",
|
|
6
6
|
"type": "module",
|
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
"author": "",
|
|
25
25
|
"license": "ISC",
|
|
26
26
|
"dependencies": {
|
|
27
|
-
"alibabacloud-devops-mcp-server": "
|
|
27
|
+
"alibabacloud-devops-mcp-server": "0.1.26",
|
|
28
28
|
"node-scp": "^0.0.25",
|
|
29
29
|
"simple-git": "^3.28.0"
|
|
30
30
|
}
|