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