@shellus/way 0.6.9 → 0.6.10
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 +3 -1
- package/dist/cli.js +37 -2
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -242,6 +242,8 @@ projects:
|
|
|
242
242
|
|
|
243
243
|
`before_backup` 失败会跳过该项目的 restic 备份并标记项目失败;`after_backup` 只在 restic 成功后执行,失败同样会标记项目失败。`--dry-run` 模式只打印钩子命令,不实际执行。钩子命令按 shell 命令执行,并会收到 `WAY_PROJECT`、`WAY_REMOTE`、`WAY_DIR`、`WAY_DRY_RUN` 环境变量。
|
|
244
244
|
|
|
245
|
+
Linux 上的 hook 达到 `timeout` 后,Way 会终止对应 shell 的完整进程组;进程未在宽限期内退出时会继续强制终止,避免数据库导出、压缩或同步子进程脱离 Way 后持续运行。hook 仍应保持幂等,并自行清理失败时生成的临时文件。
|
|
246
|
+
|
|
245
247
|
**项目级 Uptime Kuma 通知示例**:
|
|
246
248
|
|
|
247
249
|
```yaml
|
|
@@ -460,4 +462,4 @@ way --remote=oss restic restore <snapshot-id> --target /tmp/restore
|
|
|
460
462
|
- 变更规范和测试要求
|
|
461
463
|
- 发布流程
|
|
462
464
|
|
|
463
|
-
|
|
465
|
+
项目维护规则:[AGENTS.md](AGENTS.md)
|
package/dist/cli.js
CHANGED
|
@@ -324,6 +324,7 @@ function groupUptimeKumaResults(projectResults) {
|
|
|
324
324
|
}
|
|
325
325
|
return groupedResults;
|
|
326
326
|
}
|
|
327
|
+
var HOOK_FORCE_KILL_DELAY_MS = 1e3;
|
|
327
328
|
function normalizeHook(hook) {
|
|
328
329
|
if (typeof hook === "string") return { run: hook };
|
|
329
330
|
return hook;
|
|
@@ -346,6 +347,26 @@ function parseTimeout(timeout) {
|
|
|
346
347
|
return value * 60 * 60 * 1e3;
|
|
347
348
|
}
|
|
348
349
|
}
|
|
350
|
+
function isMissingProcessError(error) {
|
|
351
|
+
return error instanceof Error && "code" in error && error.code === "ESRCH";
|
|
352
|
+
}
|
|
353
|
+
function signalProcessGroup(pid, signal) {
|
|
354
|
+
try {
|
|
355
|
+
process.kill(-pid, signal);
|
|
356
|
+
return true;
|
|
357
|
+
} catch (error) {
|
|
358
|
+
if (isMissingProcessError(error)) return false;
|
|
359
|
+
throw error;
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
function hookTimedOut(error) {
|
|
363
|
+
return typeof error === "object" && error !== null && "timedOut" in error && error.timedOut === true;
|
|
364
|
+
}
|
|
365
|
+
async function terminateProcessGroup(pid) {
|
|
366
|
+
if (!signalProcessGroup(pid, "SIGTERM")) return;
|
|
367
|
+
await new Promise((resolve) => setTimeout(resolve, HOOK_FORCE_KILL_DELAY_MS));
|
|
368
|
+
signalProcessGroup(pid, "SIGKILL");
|
|
369
|
+
}
|
|
349
370
|
async function runProjectHooks(hooks, context) {
|
|
350
371
|
if (!hooks?.length) return;
|
|
351
372
|
for (const hook of hooks) {
|
|
@@ -356,10 +377,11 @@ async function runProjectHooks(hooks, context) {
|
|
|
356
377
|
continue;
|
|
357
378
|
}
|
|
358
379
|
console.log(`Running ${context.label} hook for ${context.projectName}: ${normalized.run}`);
|
|
359
|
-
|
|
380
|
+
const subprocess = execaCommand(normalized.run, {
|
|
360
381
|
shell: true,
|
|
361
382
|
stdio: "inherit",
|
|
362
383
|
timeout: parseTimeout(normalized.timeout),
|
|
384
|
+
detached: process.platform !== "win32",
|
|
363
385
|
env: {
|
|
364
386
|
WAY_PROJECT: context.projectName,
|
|
365
387
|
WAY_REMOTE: context.remote,
|
|
@@ -367,6 +389,19 @@ async function runProjectHooks(hooks, context) {
|
|
|
367
389
|
WAY_DRY_RUN: context.dryRun ? "1" : "0"
|
|
368
390
|
}
|
|
369
391
|
});
|
|
392
|
+
const processGroupPid = process.platform === "win32" ? void 0 : subprocess.pid;
|
|
393
|
+
const cleanupOnExit = processGroupPid === void 0 ? void 0 : () => signalProcessGroup(processGroupPid, "SIGTERM");
|
|
394
|
+
if (cleanupOnExit) process.once("exit", cleanupOnExit);
|
|
395
|
+
try {
|
|
396
|
+
await subprocess;
|
|
397
|
+
} catch (error) {
|
|
398
|
+
if (processGroupPid !== void 0 && hookTimedOut(error)) {
|
|
399
|
+
await terminateProcessGroup(processGroupPid);
|
|
400
|
+
}
|
|
401
|
+
throw error;
|
|
402
|
+
} finally {
|
|
403
|
+
if (cleanupOnExit) process.removeListener("exit", cleanupOnExit);
|
|
404
|
+
}
|
|
370
405
|
}
|
|
371
406
|
}
|
|
372
407
|
async function notifyUptimeKuma(result, pushUrl) {
|
|
@@ -611,7 +646,7 @@ async function daemon(options) {
|
|
|
611
646
|
|
|
612
647
|
// src/cli.ts
|
|
613
648
|
var program = new Command();
|
|
614
|
-
program.name("way").version("0.6.
|
|
649
|
+
program.name("way").version("0.6.10").description("\u7B56\u7565\u5907\u4EFD\u5DE5\u5177 - \u57FA\u4E8E restic \u7684\u7B56\u7565\u5C01\u88C5").option("--remote <name>", "\u6307\u5B9A\u4ED3\u5E93", "default").addHelpText("after", `
|
|
615
650
|
\u793A\u4F8B:
|
|
616
651
|
$ way backup \u6267\u884C\u6240\u6709\u9879\u76EE\u5907\u4EFD
|
|
617
652
|
$ way backup data \u53EA\u5907\u4EFD data \u9879\u76EE
|