@ruan-cat/vercel-deploy-tool 1.2.7 → 1.4.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 +162 -84
- package/dist/index.d.ts +28 -1
- package/dist/index.js +162 -84
- package/package.json +8 -6
- package/src/commands/deploy.ts +6 -1
- package/src/config/schema.ts +12 -0
- package/src/core/git-diff-filter.ts +90 -0
- package/src/core/tasks/index.ts +61 -5
package/dist/cli.js
CHANGED
|
@@ -8,7 +8,7 @@ import { Command as Command3 } from "commander";
|
|
|
8
8
|
|
|
9
9
|
// src/commands/deploy.ts
|
|
10
10
|
import { Command } from "commander";
|
|
11
|
-
import { consola as
|
|
11
|
+
import { consola as consola11 } from "consola";
|
|
12
12
|
import { config as dotenvxConfig2 } from "@dotenvx/dotenvx";
|
|
13
13
|
|
|
14
14
|
// src/config/loader.ts
|
|
@@ -60,7 +60,7 @@ async function loadConfig() {
|
|
|
60
60
|
// src/core/tasks/index.ts
|
|
61
61
|
import fs4 from "fs";
|
|
62
62
|
import { resolve as resolve5 } from "path";
|
|
63
|
-
import { consola as
|
|
63
|
+
import { consola as consola10 } from "consola";
|
|
64
64
|
|
|
65
65
|
// src/core/executor.ts
|
|
66
66
|
import task from "tasuku";
|
|
@@ -113,12 +113,60 @@ var VERCEL_NULL_CONFIG = {
|
|
|
113
113
|
var VERCEL_NULL_CONFIG_PATH = "./vercel.null.def.json";
|
|
114
114
|
var VERCEL_OUTPUT_STATIC = ".vercel/output/static";
|
|
115
115
|
|
|
116
|
+
// src/core/git-diff-filter.ts
|
|
117
|
+
import { spawnSync } from "child_process";
|
|
118
|
+
import picomatch from "picomatch";
|
|
119
|
+
import { consola as consola2 } from "consola";
|
|
120
|
+
function getChangedFiles(diffBase) {
|
|
121
|
+
if (!diffBase) {
|
|
122
|
+
consola2.warn("\u672A\u63D0\u4F9B diffBase\uFF0C\u65E0\u6CD5\u68C0\u6D4B\u53D8\u66F4\u6587\u4EF6\uFF0C\u5C06\u964D\u7EA7\u4E3A\u5168\u91CF\u90E8\u7F72");
|
|
123
|
+
return null;
|
|
124
|
+
}
|
|
125
|
+
const result = spawnSync("git", ["diff", "--name-only", diffBase, "HEAD"], {
|
|
126
|
+
encoding: "utf-8"
|
|
127
|
+
});
|
|
128
|
+
if (result.error) {
|
|
129
|
+
consola2.warn(`git \u547D\u4EE4\u4E0D\u53EF\u7528\u6216\u6267\u884C\u5931\u8D25: ${result.error.message}\uFF0C\u5C06\u964D\u7EA7\u4E3A\u5168\u91CF\u90E8\u7F72`);
|
|
130
|
+
return null;
|
|
131
|
+
}
|
|
132
|
+
if (result.status !== 0) {
|
|
133
|
+
consola2.warn(`git diff \u8FD4\u56DE\u975E\u96F6\u9000\u51FA\u7801 ${result.status}\uFF0C\u5C06\u964D\u7EA7\u4E3A\u5168\u91CF\u90E8\u7F72`);
|
|
134
|
+
if (result.stderr?.trim()) {
|
|
135
|
+
consola2.warn(result.stderr.trim());
|
|
136
|
+
}
|
|
137
|
+
return null;
|
|
138
|
+
}
|
|
139
|
+
const output = result.stdout?.trim();
|
|
140
|
+
if (!output) {
|
|
141
|
+
return [];
|
|
142
|
+
}
|
|
143
|
+
return output.split("\n").filter(Boolean);
|
|
144
|
+
}
|
|
145
|
+
function filterTargetsByDiff(targets, changedFiles) {
|
|
146
|
+
const deploy = [];
|
|
147
|
+
const skipped = [];
|
|
148
|
+
for (const target of targets) {
|
|
149
|
+
if (!target.watchPaths || target.watchPaths.length === 0) {
|
|
150
|
+
deploy.push(target);
|
|
151
|
+
continue;
|
|
152
|
+
}
|
|
153
|
+
const isMatch = picomatch(target.watchPaths);
|
|
154
|
+
const hasChange = changedFiles.some((file) => isMatch(file));
|
|
155
|
+
if (hasChange) {
|
|
156
|
+
deploy.push(target);
|
|
157
|
+
} else {
|
|
158
|
+
skipped.push(target);
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
return { deploy, skipped };
|
|
162
|
+
}
|
|
163
|
+
|
|
116
164
|
// src/core/tasks/link.ts
|
|
117
165
|
import fs from "fs";
|
|
118
166
|
import { resolve } from "path";
|
|
119
|
-
import { spawnSync } from "child_process";
|
|
167
|
+
import { spawnSync as spawnSync2 } from "child_process";
|
|
120
168
|
import { concat } from "lodash-es";
|
|
121
|
-
import { consola as
|
|
169
|
+
import { consola as consola3 } from "consola";
|
|
122
170
|
|
|
123
171
|
// src/core/vercel.ts
|
|
124
172
|
function getVercelProjectNameArg(config) {
|
|
@@ -155,7 +203,7 @@ function createLinkTask(config, target) {
|
|
|
155
203
|
const targetPath = resolve(target.targetCWD);
|
|
156
204
|
if (!fs.existsSync(targetPath)) {
|
|
157
205
|
const err = new Error(`\u76EE\u6807\u76EE\u5F55\u4E0D\u5B58\u5728\uFF0C\u8BF7\u5148\u6784\u5EFA: ${target.targetCWD}`);
|
|
158
|
-
|
|
206
|
+
consola3.error(err.message);
|
|
159
207
|
throw err;
|
|
160
208
|
}
|
|
161
209
|
const args = concat(
|
|
@@ -165,13 +213,13 @@ function createLinkTask(config, target) {
|
|
|
165
213
|
getVercelProjectNameArg(config),
|
|
166
214
|
getVercelTokenArg(config)
|
|
167
215
|
);
|
|
168
|
-
|
|
169
|
-
const result =
|
|
216
|
+
consola3.start(`\u5F00\u59CB link \u4EFB\u52A1: ${target.targetCWD}`);
|
|
217
|
+
const result = spawnSync2("vercel", args, createVercelSpawnOptions());
|
|
170
218
|
if (result.error) {
|
|
171
|
-
|
|
219
|
+
consola3.error(`link \u4EFB\u52A1\u5931\u8D25: ${target.targetCWD}`);
|
|
172
220
|
throw result.error;
|
|
173
221
|
}
|
|
174
|
-
|
|
222
|
+
consola3.success(`\u5B8C\u6210 link \u4EFB\u52A1: ${target.targetCWD}`);
|
|
175
223
|
return result.stdout;
|
|
176
224
|
}
|
|
177
225
|
};
|
|
@@ -180,9 +228,9 @@ function createLinkTask(config, target) {
|
|
|
180
228
|
// src/core/tasks/build.ts
|
|
181
229
|
import fs2 from "fs";
|
|
182
230
|
import { resolve as resolve2 } from "path";
|
|
183
|
-
import { spawnSync as
|
|
231
|
+
import { spawnSync as spawnSync3 } from "child_process";
|
|
184
232
|
import { concat as concat2 } from "lodash-es";
|
|
185
|
-
import { consola as
|
|
233
|
+
import { consola as consola4 } from "consola";
|
|
186
234
|
function createBuildTask(config, target) {
|
|
187
235
|
return {
|
|
188
236
|
name: `Build: ${target.targetCWD}`,
|
|
@@ -190,7 +238,7 @@ function createBuildTask(config, target) {
|
|
|
190
238
|
const targetPath = resolve2(target.targetCWD);
|
|
191
239
|
if (!fs2.existsSync(targetPath)) {
|
|
192
240
|
const err = new Error(`\u76EE\u6807\u76EE\u5F55\u4E0D\u5B58\u5728\uFF0C\u8BF7\u5148\u6784\u5EFA: ${target.targetCWD}`);
|
|
193
|
-
|
|
241
|
+
consola4.error(err.message);
|
|
194
242
|
throw err;
|
|
195
243
|
}
|
|
196
244
|
const args = concat2(
|
|
@@ -201,21 +249,21 @@ function createBuildTask(config, target) {
|
|
|
201
249
|
getVercelLocalConfigArg(),
|
|
202
250
|
getVercelTokenArg(config)
|
|
203
251
|
);
|
|
204
|
-
|
|
205
|
-
const result =
|
|
252
|
+
consola4.start(`\u5F00\u59CB build \u4EFB\u52A1: ${target.targetCWD}`);
|
|
253
|
+
const result = spawnSync3("vercel", args, createVercelSpawnOptions());
|
|
206
254
|
if (result.error) {
|
|
207
|
-
|
|
255
|
+
consola4.error(`build \u4EFB\u52A1\u5931\u8D25: ${target.targetCWD}`);
|
|
208
256
|
throw result.error;
|
|
209
257
|
}
|
|
210
|
-
|
|
258
|
+
consola4.success(`\u5B8C\u6210 build \u4EFB\u52A1: ${target.targetCWD}`);
|
|
211
259
|
return result.stdout;
|
|
212
260
|
}
|
|
213
261
|
};
|
|
214
262
|
}
|
|
215
263
|
|
|
216
264
|
// src/core/tasks/after-build.ts
|
|
217
|
-
import { spawnSync as
|
|
218
|
-
import { consola as
|
|
265
|
+
import { spawnSync as spawnSync4 } from "child_process";
|
|
266
|
+
import { consola as consola5 } from "consola";
|
|
219
267
|
import { isUndefined as isUndefined2, isEmpty } from "lodash-es";
|
|
220
268
|
function createAfterBuildTasks(config) {
|
|
221
269
|
const afterBuildTasks = config.afterBuildTasks;
|
|
@@ -224,7 +272,7 @@ function createAfterBuildTasks(config) {
|
|
|
224
272
|
{
|
|
225
273
|
name: "AfterBuild: \u65E0\u4EFB\u52A1",
|
|
226
274
|
fn: async () => {
|
|
227
|
-
|
|
275
|
+
consola5.warn("\u5F53\u524D\u6CA1\u6709\u6709\u610F\u4E49\u7684 afterBuildTasks \u4EFB\u52A1\u914D\u7F6E");
|
|
228
276
|
return void 0;
|
|
229
277
|
}
|
|
230
278
|
}
|
|
@@ -233,40 +281,40 @@ function createAfterBuildTasks(config) {
|
|
|
233
281
|
return afterBuildTasks.map((command) => ({
|
|
234
282
|
name: `AfterBuild: ${command}`,
|
|
235
283
|
fn: async () => {
|
|
236
|
-
|
|
237
|
-
const result =
|
|
284
|
+
consola5.start(`\u5F00\u59CB afterBuild \u4EFB\u52A1: ${command}`);
|
|
285
|
+
const result = spawnSync4(command, [], {
|
|
238
286
|
encoding: "utf-8",
|
|
239
287
|
stdio: "inherit",
|
|
240
288
|
shell: true
|
|
241
289
|
});
|
|
242
290
|
if (result.error) {
|
|
243
|
-
|
|
291
|
+
consola5.error(`afterBuild \u4EFB\u52A1\u5931\u8D25: ${command}`);
|
|
244
292
|
throw result.error;
|
|
245
293
|
}
|
|
246
|
-
|
|
294
|
+
consola5.success(`\u5B8C\u6210 afterBuild \u4EFB\u52A1: ${command}`);
|
|
247
295
|
return result.stdout;
|
|
248
296
|
}
|
|
249
297
|
}));
|
|
250
298
|
}
|
|
251
299
|
|
|
252
300
|
// src/core/tasks/user-commands.ts
|
|
253
|
-
import { spawnSync as
|
|
254
|
-
import { consola as
|
|
301
|
+
import { spawnSync as spawnSync5 } from "child_process";
|
|
302
|
+
import { consola as consola6 } from "consola";
|
|
255
303
|
function createUserCommandTasks(target) {
|
|
256
304
|
return target.userCommands.map((command) => ({
|
|
257
305
|
name: `UserCommand: ${command}`,
|
|
258
306
|
fn: async () => {
|
|
259
|
-
|
|
260
|
-
const result =
|
|
307
|
+
consola6.start(`\u5F00\u59CB\u7528\u6237\u547D\u4EE4\u4EFB\u52A1: ${command}`);
|
|
308
|
+
const result = spawnSync5(command, [], {
|
|
261
309
|
encoding: "utf-8",
|
|
262
310
|
stdio: "inherit",
|
|
263
311
|
shell: true
|
|
264
312
|
});
|
|
265
313
|
if (result.error) {
|
|
266
|
-
|
|
314
|
+
consola6.error(`\u7528\u6237\u547D\u4EE4\u4EFB\u52A1\u5931\u8D25: ${command}`);
|
|
267
315
|
throw result.error;
|
|
268
316
|
}
|
|
269
|
-
|
|
317
|
+
consola6.success(`\u5B8C\u6210\u7528\u6237\u547D\u4EE4\u4EFB\u52A1: ${command}`);
|
|
270
318
|
return result.stdout;
|
|
271
319
|
}
|
|
272
320
|
}));
|
|
@@ -275,7 +323,7 @@ function createUserCommandTasks(target) {
|
|
|
275
323
|
// src/core/tasks/copy-dist.ts
|
|
276
324
|
import { resolve as resolve3 } from "path";
|
|
277
325
|
import { rmSync, mkdirSync, cpSync } from "fs";
|
|
278
|
-
import { consola as
|
|
326
|
+
import { consola as consola7 } from "consola";
|
|
279
327
|
function createCopyDistTasks(target) {
|
|
280
328
|
const targetCWD = target.targetCWD;
|
|
281
329
|
const outputDirectory = target.outputDirectory;
|
|
@@ -288,27 +336,27 @@ function createCopyDistTasks(target) {
|
|
|
288
336
|
{
|
|
289
337
|
name: `\u5220\u9664\u76EE\u5F55: ${pathVercelOutputStatic}`,
|
|
290
338
|
fn: async () => {
|
|
291
|
-
|
|
339
|
+
consola7.start(`\u5F00\u59CB\u5220\u9664\u6587\u4EF6\u4EFB\u52A1: ${pathVercelOutputStatic}`);
|
|
292
340
|
rmSync(pathVercelOutputStatic, { recursive: true, force: true });
|
|
293
|
-
|
|
341
|
+
consola7.success(`\u5220\u9664\u8BE5\u8DEF\u5F84\u7684\u6587\u4EF6: ${pathVercelOutputStatic}`);
|
|
294
342
|
}
|
|
295
343
|
},
|
|
296
344
|
{
|
|
297
345
|
name: `\u521B\u5EFA\u76EE\u5F55: ${pathVercelOutputStatic}`,
|
|
298
346
|
fn: async () => {
|
|
299
|
-
|
|
347
|
+
consola7.start(`\u5F00\u59CB\u521B\u5EFA\u6587\u4EF6\u5939\u4EFB\u52A1: ${pathVercelOutputStatic}`);
|
|
300
348
|
mkdirSync(pathVercelOutputStatic, { recursive: true });
|
|
301
|
-
|
|
349
|
+
consola7.success(`\u521B\u5EFA\u7684\u65B0\u76EE\u5F55\u4E3A: ${pathVercelOutputStatic}`);
|
|
302
350
|
}
|
|
303
351
|
},
|
|
304
352
|
{
|
|
305
353
|
name: `\u590D\u5236\u6587\u4EF6: ${pathOutputDirectory} -> ${pathVercelOutputStatic}`,
|
|
306
354
|
fn: async () => {
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
355
|
+
consola7.start(`\u5F00\u59CB\u6587\u4EF6\u590D\u5236\u4EFB\u52A1`);
|
|
356
|
+
consola7.info(`\u4ECE ${pathOutputDirectory} \u5F00\u59CB`);
|
|
357
|
+
consola7.info(`\u590D\u5236\u5230 ${pathVercelOutputStatic} \u5185`);
|
|
310
358
|
cpSync(pathOutputDirectory, pathVercelOutputStatic, { recursive: true });
|
|
311
|
-
|
|
359
|
+
consola7.success(`\u5B8C\u6210\u6587\u4EF6\u590D\u5236\u4EFB\u52A1`);
|
|
312
360
|
}
|
|
313
361
|
}
|
|
314
362
|
];
|
|
@@ -317,9 +365,9 @@ function createCopyDistTasks(target) {
|
|
|
317
365
|
// src/core/tasks/deploy.ts
|
|
318
366
|
import fs3 from "fs";
|
|
319
367
|
import { resolve as resolve4 } from "path";
|
|
320
|
-
import { spawnSync as
|
|
368
|
+
import { spawnSync as spawnSync6 } from "child_process";
|
|
321
369
|
import { concat as concat3 } from "lodash-es";
|
|
322
|
-
import { consola as
|
|
370
|
+
import { consola as consola8 } from "consola";
|
|
323
371
|
function createDeployTask(config, target) {
|
|
324
372
|
return {
|
|
325
373
|
name: `Deploy: ${target.targetCWD}`,
|
|
@@ -327,7 +375,7 @@ function createDeployTask(config, target) {
|
|
|
327
375
|
const targetPath = resolve4(target.targetCWD);
|
|
328
376
|
if (!fs3.existsSync(targetPath)) {
|
|
329
377
|
const err = new Error(`\u76EE\u6807\u76EE\u5F55\u4E0D\u5B58\u5728\uFF0C\u8BF7\u5148\u6784\u5EFA: ${target.targetCWD}`);
|
|
330
|
-
|
|
378
|
+
consola8.error(err.message);
|
|
331
379
|
throw err;
|
|
332
380
|
}
|
|
333
381
|
const args = concat3(
|
|
@@ -338,38 +386,38 @@ function createDeployTask(config, target) {
|
|
|
338
386
|
getTargetCWDArg(target),
|
|
339
387
|
getVercelTokenArg(config)
|
|
340
388
|
);
|
|
341
|
-
|
|
342
|
-
const result =
|
|
389
|
+
consola8.start(`\u5F00\u59CB\u90E8\u7F72\u4EFB\u52A1: ${target.targetCWD}`);
|
|
390
|
+
const result = spawnSync6("vercel", args, createVercelSpawnOptions("pipe"));
|
|
343
391
|
if (result.error) {
|
|
344
|
-
|
|
345
|
-
|
|
392
|
+
consola8.error(`\u90E8\u7F72\u5931\u8D25\u4E86: ${target.targetCWD}`);
|
|
393
|
+
consola8.error(result.error);
|
|
346
394
|
throw result.error;
|
|
347
395
|
}
|
|
348
396
|
const vercelUrl = result.stdout.toString().trim();
|
|
349
|
-
|
|
350
|
-
|
|
397
|
+
consola8.success(`\u5B8C\u6210\u90E8\u7F72\u4EFB\u52A1\uFF0C\u751F\u6210\u7684url\u4E3A:`);
|
|
398
|
+
consola8.box(vercelUrl);
|
|
351
399
|
return vercelUrl;
|
|
352
400
|
}
|
|
353
401
|
};
|
|
354
402
|
}
|
|
355
403
|
|
|
356
404
|
// src/core/tasks/alias.ts
|
|
357
|
-
import { spawnSync as
|
|
405
|
+
import { spawnSync as spawnSync7 } from "child_process";
|
|
358
406
|
import { concat as concat4 } from "lodash-es";
|
|
359
|
-
import { consola as
|
|
407
|
+
import { consola as consola9 } from "consola";
|
|
360
408
|
function createAliasTask(config, vercelUrl, userUrl) {
|
|
361
409
|
return {
|
|
362
410
|
name: `Alias: ${userUrl}`,
|
|
363
411
|
fn: async () => {
|
|
364
412
|
const args = concat4(["alias", "set", vercelUrl, userUrl], getVercelTokenArg(config), getVercelScopeArg(config));
|
|
365
|
-
|
|
366
|
-
const result =
|
|
413
|
+
consola9.start(`\u5F00\u59CB\u522B\u540D\u4EFB\u52A1: ${userUrl}`);
|
|
414
|
+
const result = spawnSync7("vercel", args, createVercelSpawnOptions());
|
|
367
415
|
if (result.error) {
|
|
368
|
-
|
|
416
|
+
consola9.error(`\u522B\u540D\u4EFB\u52A1\u5931\u8D25: ${userUrl}`);
|
|
369
417
|
throw result.error;
|
|
370
418
|
}
|
|
371
|
-
|
|
372
|
-
|
|
419
|
+
consola9.success(`\u5B8C\u6210\u522B\u540D\u4EFB\u52A1\uFF0C\u53EF\u7528\u7684\u522B\u540D\u5730\u5740\u4E3A:`);
|
|
420
|
+
consola9.box(`https://${userUrl}`);
|
|
373
421
|
return result.stdout;
|
|
374
422
|
}
|
|
375
423
|
};
|
|
@@ -378,32 +426,59 @@ function createAliasTask(config, vercelUrl, userUrl) {
|
|
|
378
426
|
// src/core/tasks/index.ts
|
|
379
427
|
async function generateVercelNullConfig() {
|
|
380
428
|
fs4.writeFileSync(VERCEL_NULL_CONFIG_PATH, JSON.stringify(VERCEL_NULL_CONFIG, null, 2));
|
|
381
|
-
|
|
429
|
+
consola10.success(`\u751F\u6210 Vercel \u7A7A\u914D\u7F6E\u6587\u4EF6: ${VERCEL_NULL_CONFIG_PATH}`);
|
|
382
430
|
}
|
|
383
|
-
async function executeDeploymentWorkflow(config) {
|
|
431
|
+
async function executeDeploymentWorkflow(config, options) {
|
|
384
432
|
await generateVercelNullConfig();
|
|
385
433
|
const { deployTargets } = config;
|
|
386
434
|
const availableTargets = deployTargets.filter((target) => {
|
|
387
435
|
const targetPath = resolve5(target.targetCWD);
|
|
388
436
|
if (!fs4.existsSync(targetPath)) {
|
|
389
|
-
|
|
437
|
+
consola10.warn(`\u76EE\u6807\u76EE\u5F55\u4E0D\u5B58\u5728\uFF0C\u5DF2\u8DF3\u8FC7: ${target.targetCWD}`);
|
|
390
438
|
return false;
|
|
391
439
|
}
|
|
392
440
|
return true;
|
|
393
441
|
});
|
|
394
442
|
if (availableTargets.length === 0) {
|
|
395
|
-
|
|
443
|
+
consola10.error("\u6CA1\u6709\u53EF\u7528\u7684\u90E8\u7F72\u76EE\u6807\uFF0C\u8BF7\u5148\u6784\u5EFA\u4EA7\u7269");
|
|
396
444
|
return;
|
|
397
445
|
}
|
|
398
446
|
await task("Vercel \u90E8\u7F72\u5DE5\u4F5C\u6D41", async ({ task: task2 }) => {
|
|
447
|
+
const { result: finalTargets } = await task2("0. \u68C0\u6D4B\u53D8\u66F4\u8303\u56F4", async ({ setTitle }) => {
|
|
448
|
+
if (options?.forceAll) {
|
|
449
|
+
setTitle("0. \u5F3A\u5236\u5168\u91CF\u90E8\u7F72\uFF08--force-all\uFF09");
|
|
450
|
+
return availableTargets;
|
|
451
|
+
}
|
|
452
|
+
if (!options?.diffBase) {
|
|
453
|
+
setTitle("0. \u5168\u91CF\u90E8\u7F72\uFF08\u672A\u6307\u5B9A --diff-base\uFF09");
|
|
454
|
+
return availableTargets;
|
|
455
|
+
}
|
|
456
|
+
const changedFiles = getChangedFiles(options.diffBase);
|
|
457
|
+
if (changedFiles === null) {
|
|
458
|
+
setTitle("0. Git \u4E0D\u53EF\u7528\uFF0C\u5DF2\u964D\u7EA7\u4E3A\u5168\u91CF\u90E8\u7F72");
|
|
459
|
+
return availableTargets;
|
|
460
|
+
}
|
|
461
|
+
if (changedFiles.length === 0) {
|
|
462
|
+
setTitle("0. \u65E0\u6587\u4EF6\u53D8\u66F4\uFF0C\u8DF3\u8FC7\u6240\u6709\u90E8\u7F72");
|
|
463
|
+
return [];
|
|
464
|
+
}
|
|
465
|
+
const { deploy, skipped } = filterTargetsByDiff(availableTargets, changedFiles);
|
|
466
|
+
skipped.forEach((t) => consola10.info(`\u8DF3\u8FC7\u672A\u53D8\u66F4\u76EE\u6807: ${t.targetCWD}`));
|
|
467
|
+
setTitle(`0. \u7CBE\u786E\u90E8\u7F72: ${deploy.length} / ${availableTargets.length} \u4E2A\u76EE\u6807`);
|
|
468
|
+
return deploy;
|
|
469
|
+
});
|
|
470
|
+
if (finalTargets.length === 0) {
|
|
471
|
+
consola10.success("\u6240\u6709\u76EE\u6807\u5747\u65E0\u53D8\u66F4\uFF0C\u65E0\u9700\u90E8\u7F72");
|
|
472
|
+
return;
|
|
473
|
+
}
|
|
399
474
|
await task2("1. Link \u9879\u76EE", async () => {
|
|
400
|
-
const linkTasks =
|
|
475
|
+
const linkTasks = finalTargets.map((target) => createLinkTask(config, target));
|
|
401
476
|
await task2.group((task3) => linkTasks.map((t) => task3(t.name, t.fn)));
|
|
402
477
|
});
|
|
403
478
|
await task2("2. \u6784\u5EFA\u9879\u76EE", async () => {
|
|
404
|
-
const buildTasks =
|
|
479
|
+
const buildTasks = finalTargets.filter(isNeedVercelBuild).map((target) => createBuildTask(config, target));
|
|
405
480
|
if (buildTasks.length === 0) {
|
|
406
|
-
|
|
481
|
+
consola10.warn("\u6CA1\u6709\u9700\u8981\u6267\u884C build \u7684\u76EE\u6807");
|
|
407
482
|
return;
|
|
408
483
|
}
|
|
409
484
|
await task2.group((task3) => buildTasks.map((t) => task3(t.name, t.fn)));
|
|
@@ -413,11 +488,11 @@ async function executeDeploymentWorkflow(config) {
|
|
|
413
488
|
await executeSequential("AfterBuild", afterBuildTasks);
|
|
414
489
|
});
|
|
415
490
|
await task2("4. \u6267\u884C\u7528\u6237\u547D\u4EE4\u4E0E\u6587\u4EF6\u590D\u5236", async () => {
|
|
416
|
-
const targetTasks =
|
|
491
|
+
const targetTasks = finalTargets.map((target) => ({
|
|
417
492
|
name: `\u5904\u7406\u76EE\u6807: ${target.targetCWD}`,
|
|
418
493
|
fn: async () => {
|
|
419
494
|
if (!isDeployTargetWithUserCommands(target)) {
|
|
420
|
-
|
|
495
|
+
consola10.warn(`\u76EE\u6807 ${target.targetCWD} \u4E0D\u5C5E\u4E8E userCommands \u7C7B\u578B`);
|
|
421
496
|
return;
|
|
422
497
|
}
|
|
423
498
|
const userCommandTasks = createUserCommandTasks(target);
|
|
@@ -426,14 +501,14 @@ async function executeDeploymentWorkflow(config) {
|
|
|
426
501
|
const copyDistTasks = createCopyDistTasks(target);
|
|
427
502
|
await executeSequential(`CopyDist: ${target.targetCWD}`, copyDistTasks);
|
|
428
503
|
} else {
|
|
429
|
-
|
|
504
|
+
consola10.warn(`\u76EE\u6807 ${target.targetCWD} \u4E0D\u9700\u8981\u590D\u5236\u6587\u4EF6`);
|
|
430
505
|
}
|
|
431
506
|
}
|
|
432
507
|
}));
|
|
433
508
|
await task2.group((task3) => targetTasks.map((t) => task3(t.name, t.fn)));
|
|
434
509
|
});
|
|
435
510
|
await task2("5. \u90E8\u7F72\u4E0E\u8BBE\u7F6E\u522B\u540D", async () => {
|
|
436
|
-
const deployAliasTasks =
|
|
511
|
+
const deployAliasTasks = finalTargets.map((target) => ({
|
|
437
512
|
name: `\u90E8\u7F72\u4E0E\u522B\u540D: ${target.targetCWD}`,
|
|
438
513
|
fn: async () => {
|
|
439
514
|
const deployTask = createDeployTask(config, target);
|
|
@@ -443,34 +518,37 @@ async function executeDeploymentWorkflow(config) {
|
|
|
443
518
|
const aliasTasks = target.url.map((userUrl) => createAliasTask(config, vercelUrl, userUrl));
|
|
444
519
|
await task2.group((task3) => aliasTasks.map((t) => task3(t.name, t.fn)));
|
|
445
520
|
} else {
|
|
446
|
-
|
|
521
|
+
consola10.warn(`\u76EE\u6807 ${target.targetCWD} \u6CA1\u6709\u914D\u7F6E\u522B\u540D`);
|
|
447
522
|
}
|
|
448
523
|
}
|
|
449
524
|
}));
|
|
450
525
|
await task2.group((task3) => deployAliasTasks.map((t) => task3(t.name, t.fn)));
|
|
451
526
|
});
|
|
452
527
|
});
|
|
453
|
-
|
|
528
|
+
consola10.success("\u{1F389} Vercel \u90E8\u7F72\u5DE5\u4F5C\u6D41\u5B8C\u6210\uFF01");
|
|
454
529
|
}
|
|
455
530
|
|
|
456
531
|
// src/commands/deploy.ts
|
|
457
532
|
function createDeployCommand() {
|
|
458
533
|
const command = new Command("deploy");
|
|
459
|
-
command.description("\u90E8\u7F72\u9879\u76EE\u5230 Vercel").option("--env-path <path>", "\u6307\u5B9A dotenv \u6587\u4EF6\u8DEF\u5F84\uFF0C\u7528\u4E8E\u8986\u76D6\u9ED8\u8BA4\u73AF\u5883\u53D8\u91CF").action(async (options) => {
|
|
534
|
+
command.description("\u90E8\u7F72\u9879\u76EE\u5230 Vercel").option("--env-path <path>", "\u6307\u5B9A dotenv \u6587\u4EF6\u8DEF\u5F84\uFF0C\u7528\u4E8E\u8986\u76D6\u9ED8\u8BA4\u73AF\u5883\u53D8\u91CF").option("--diff-base <ref>", "Git ref\uFF0C\u4E0E HEAD \u5BF9\u6BD4\u68C0\u6D4B\u53D8\u66F4\u6587\u4EF6\uFF0C\u4EC5\u90E8\u7F72\u6709\u53D8\u66F4\u7684\u76EE\u6807").option("--force-all", "\u5F3A\u5236\u90E8\u7F72\u6240\u6709\u76EE\u6807\uFF0C\u5FFD\u7565 watchPaths \u8FC7\u6EE4\uFF08\u4F18\u5148\u7EA7\u9AD8\u4E8E --diff-base\uFF09").action(async (options) => {
|
|
460
535
|
try {
|
|
461
536
|
if (options?.envPath) {
|
|
462
537
|
process.env.VERCEL_DEPLOY_TOOL_ENV_PATH = options.envPath;
|
|
463
538
|
dotenvxConfig2({ path: options.envPath });
|
|
464
|
-
|
|
539
|
+
consola11.info(`\u5DF2\u4ECE --env-path \u52A0\u8F7D\u73AF\u5883\u53D8\u91CF: ${options.envPath}`);
|
|
465
540
|
}
|
|
466
|
-
|
|
541
|
+
consola11.start("\u5F00\u59CB\u52A0\u8F7D\u914D\u7F6E...");
|
|
467
542
|
const config = await loadConfig();
|
|
468
|
-
|
|
469
|
-
await executeDeploymentWorkflow(config
|
|
470
|
-
|
|
543
|
+
consola11.start("\u5F00\u59CB\u6267\u884C\u90E8\u7F72\u5DE5\u4F5C\u6D41...");
|
|
544
|
+
await executeDeploymentWorkflow(config, {
|
|
545
|
+
diffBase: options?.diffBase,
|
|
546
|
+
forceAll: options?.forceAll
|
|
547
|
+
});
|
|
548
|
+
consola11.success("\u90E8\u7F72\u5B8C\u6210\uFF01");
|
|
471
549
|
} catch (error) {
|
|
472
|
-
|
|
473
|
-
|
|
550
|
+
consola11.error("\u90E8\u7F72\u5931\u8D25:");
|
|
551
|
+
consola11.error(error);
|
|
474
552
|
process.exit(1);
|
|
475
553
|
}
|
|
476
554
|
});
|
|
@@ -482,7 +560,7 @@ import { Command as Command2 } from "commander";
|
|
|
482
560
|
import { readFileSync, writeFileSync, existsSync } from "fs";
|
|
483
561
|
import { join, dirname } from "path";
|
|
484
562
|
import { fileURLToPath } from "url";
|
|
485
|
-
import { consola as
|
|
563
|
+
import { consola as consola12 } from "consola";
|
|
486
564
|
var __filename2 = fileURLToPath(import.meta.url);
|
|
487
565
|
var __dirname2 = dirname(__filename2);
|
|
488
566
|
function createInitCommand() {
|
|
@@ -492,19 +570,19 @@ function createInitCommand() {
|
|
|
492
570
|
const configFile = "vercel-deploy-tool.config.ts";
|
|
493
571
|
const targetPath = join(cwd, configFile);
|
|
494
572
|
if (existsSync(targetPath) && !options.force) {
|
|
495
|
-
|
|
496
|
-
|
|
573
|
+
consola12.warn(`\u914D\u7F6E\u6587\u4EF6\u5DF2\u5B58\u5728: ${configFile}`);
|
|
574
|
+
consola12.info("\u4F7F\u7528 --force \u9009\u9879\u53EF\u4EE5\u8986\u76D6");
|
|
497
575
|
return;
|
|
498
576
|
}
|
|
499
577
|
const templatePath = join(__dirname2, "..", "templates", configFile);
|
|
500
578
|
if (!existsSync(templatePath)) {
|
|
501
|
-
|
|
502
|
-
|
|
579
|
+
consola12.error(`\u6A21\u677F\u6587\u4EF6\u4E0D\u5B58\u5728: ${templatePath}`);
|
|
580
|
+
consola12.error("\u8BF7\u786E\u4FDD @ruan-cat/vercel-deploy-tool \u5305\u5DF2\u6B63\u786E\u5B89\u88C5");
|
|
503
581
|
process.exit(1);
|
|
504
582
|
}
|
|
505
583
|
const content = readFileSync(templatePath, "utf-8");
|
|
506
584
|
writeFileSync(targetPath, content, "utf-8");
|
|
507
|
-
|
|
585
|
+
consola12.success(`\u5DF2\u521B\u5EFA\u914D\u7F6E\u6587\u4EF6: ${configFile}`);
|
|
508
586
|
const pkgPath = join(cwd, "package.json");
|
|
509
587
|
if (existsSync(pkgPath)) {
|
|
510
588
|
try {
|
|
@@ -512,12 +590,12 @@ function createInitCommand() {
|
|
|
512
590
|
if (!pkg.scripts) pkg.scripts = {};
|
|
513
591
|
pkg.scripts["deploy-vercel"] = "vercel-deploy-tool deploy";
|
|
514
592
|
writeFileSync(pkgPath, JSON.stringify(pkg, null, 2) + "\n", "utf-8");
|
|
515
|
-
|
|
593
|
+
consola12.success('\u5DF2\u6DFB\u52A0\u811A\u672C: "deploy-vercel"');
|
|
516
594
|
} catch (error) {
|
|
517
|
-
|
|
595
|
+
consola12.warn("\u66F4\u65B0 package.json \u5931\u8D25:", error);
|
|
518
596
|
}
|
|
519
597
|
}
|
|
520
|
-
|
|
598
|
+
consola12.box(`\u{1F389} \u521D\u59CB\u5316\u5B8C\u6210\uFF01
|
|
521
599
|
|
|
522
600
|
\u521B\u5EFA\u7684\u6587\u4EF6:
|
|
523
601
|
\u2022 ${configFile} - Vercel \u90E8\u7F72\u914D\u7F6E\u6587\u4EF6
|
package/dist/index.d.ts
CHANGED
|
@@ -24,6 +24,17 @@ interface DeployTargetBase {
|
|
|
24
24
|
* @default true
|
|
25
25
|
*/
|
|
26
26
|
isNeedVercelBuild?: boolean;
|
|
27
|
+
/**
|
|
28
|
+
* 监控路径(glob 模式)
|
|
29
|
+
* @description
|
|
30
|
+
* 配置后,部署前会通过 git diff 检测这些路径是否有变更。
|
|
31
|
+
* 仅在有变更时才部署该目标。未配置则始终部署(向后兼容)。
|
|
32
|
+
*
|
|
33
|
+
* 路径相对于 monorepo 根目录,使用 glob 语法。
|
|
34
|
+
* @example ["packages/utils/**"]
|
|
35
|
+
* @example ["packages/utils/src/docs/**", "packages/utils/src/.vitepress/**"]
|
|
36
|
+
*/
|
|
37
|
+
watchPaths?: string[];
|
|
27
38
|
}
|
|
28
39
|
/**
|
|
29
40
|
* 带有用户命令的配置
|
|
@@ -138,6 +149,22 @@ declare function loadConfig(): Promise<VercelDeployConfig>;
|
|
|
138
149
|
*/
|
|
139
150
|
declare function getConfig(): Promise<VercelDeployConfig>;
|
|
140
151
|
|
|
152
|
+
/** 部署工作流的可选参数 */
|
|
153
|
+
interface DeploymentWorkflowOptions {
|
|
154
|
+
/**
|
|
155
|
+
* Git ref,与 HEAD 对比检测变更文件
|
|
156
|
+
* @description
|
|
157
|
+
* 提供后,会通过 git diff 过滤出只有 watchPaths 匹配的目标才被部署。
|
|
158
|
+
* 未提供则不做过滤,全量部署。
|
|
159
|
+
*/
|
|
160
|
+
diffBase?: string;
|
|
161
|
+
/**
|
|
162
|
+
* 强制部署所有目标
|
|
163
|
+
* @description
|
|
164
|
+
* 为 true 时忽略 watchPaths 过滤,即使提供了 diffBase 也全量部署。
|
|
165
|
+
*/
|
|
166
|
+
forceAll?: boolean;
|
|
167
|
+
}
|
|
141
168
|
/**
|
|
142
169
|
* 执行 Vercel 部署工作流
|
|
143
170
|
* @description
|
|
@@ -150,7 +177,7 @@ declare function getConfig(): Promise<VercelDeployConfig>;
|
|
|
150
177
|
* 4. UserCommands + CopyDist 阶段(并行目标,串行步骤)
|
|
151
178
|
* 5. Deploy + Alias 阶段(并行目标,串行步骤)
|
|
152
179
|
*/
|
|
153
|
-
declare function executeDeploymentWorkflow(config: VercelDeployConfig): Promise<void>;
|
|
180
|
+
declare function executeDeploymentWorkflow(config: VercelDeployConfig, options?: DeploymentWorkflowOptions): Promise<void>;
|
|
154
181
|
|
|
155
182
|
/**
|
|
156
183
|
* Vercel 的空配置
|