paratix 0.16.1 → 0.17.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/{chunk-KC7XBI77.js → chunk-NXU7K6HY.js} +60 -8
- package/dist/cli.js +2 -2
- package/dist/{index-jbXRUlJ6.d.ts → index-CGYwJDTf.d.ts} +23 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +1 -1
- package/dist/modules/index.d.ts +1 -1
- package/dist/modules/index.js +1 -1
- package/llm-guide.md +51 -13
- package/package.json +1 -1
|
@@ -104,6 +104,7 @@ function shellQuote(s) {
|
|
|
104
104
|
return `'${s.replaceAll("'", "'\\''")}'`;
|
|
105
105
|
}
|
|
106
106
|
var DEFAULT_MAX_OUTPUT_BYTES = Number("1048576");
|
|
107
|
+
var CAPTURE_TRUNCATION_MARKER = "\n[output truncated]";
|
|
107
108
|
var CommandError = class _CommandError extends Error {
|
|
108
109
|
/** Full, untruncated standard error of the failed command. */
|
|
109
110
|
fullStderr;
|
|
@@ -1367,6 +1368,17 @@ async function setVersionedFlag(ssh2, flagName, flagPrefix) {
|
|
|
1367
1368
|
if (result.code === 0) return null;
|
|
1368
1369
|
return failedCommand(`[moduleHelpers] failed to persist versioned flag ${flagName}`, result);
|
|
1369
1370
|
}
|
|
1371
|
+
async function setFlag(ssh2, flagName) {
|
|
1372
|
+
validateFlagName(flagName, "flagName");
|
|
1373
|
+
const ensureFailure = await ensureFlagsDirectory(ssh2);
|
|
1374
|
+
if (ensureFailure) return ensureFailure;
|
|
1375
|
+
const result = await ssh2.exec(`touch ${FLAGS_DIRECTORY}/${shellQuote(flagName)}`, {
|
|
1376
|
+
ignoreExitCode: true,
|
|
1377
|
+
silent: true
|
|
1378
|
+
});
|
|
1379
|
+
if (result.code === 0) return null;
|
|
1380
|
+
return failedCommand(`[moduleHelpers] failed to persist flag ${flagName}`, result);
|
|
1381
|
+
}
|
|
1370
1382
|
async function applyWithFlagLock(ssh2, parameters) {
|
|
1371
1383
|
validateFlagName(parameters.flagName, "flagName");
|
|
1372
1384
|
const lockName = flagLockName(parameters.flagName);
|
|
@@ -1473,6 +1485,19 @@ async function tryApplyWithFlagLock(ssh2, parameters) {
|
|
|
1473
1485
|
return tryApplyWithFlagLock(ssh2, parameters);
|
|
1474
1486
|
}
|
|
1475
1487
|
|
|
1488
|
+
// src/modules/packageUpgradeSummary.ts
|
|
1489
|
+
var APT_UPGRADE_SUMMARY_PATTERN = new RegExp("^(?<upgraded>\\d+) upgraded, ", "mv");
|
|
1490
|
+
var UNKNOWN_UPGRADE_OUTCOME_DETAIL = "upgrade completed, package count unavailable";
|
|
1491
|
+
function describeAptUpgradeOutcome(stdout) {
|
|
1492
|
+
if (stdout.endsWith(CAPTURE_TRUNCATION_MARKER)) return UNKNOWN_UPGRADE_OUTCOME_DETAIL;
|
|
1493
|
+
const captured = APT_UPGRADE_SUMMARY_PATTERN.exec(stdout)?.groups?.upgraded;
|
|
1494
|
+
if (captured == null || captured === "") return UNKNOWN_UPGRADE_OUTCOME_DETAIL;
|
|
1495
|
+
const upgraded = Number(captured);
|
|
1496
|
+
if (!Number.isSafeInteger(upgraded)) return UNKNOWN_UPGRADE_OUTCOME_DETAIL;
|
|
1497
|
+
if (upgraded === 0) return "no packages upgraded";
|
|
1498
|
+
return upgraded === 1 ? "1 package upgraded" : `${upgraded} packages upgraded`;
|
|
1499
|
+
}
|
|
1500
|
+
|
|
1476
1501
|
// src/modules/remoteFileChecks.ts
|
|
1477
1502
|
import { posix as posix3 } from "path";
|
|
1478
1503
|
async function isRegularFileWithoutSymlink(ssh2, remotePath) {
|
|
@@ -1945,6 +1970,12 @@ var apt = {
|
|
|
1945
1970
|
* The pipeline is split into three separate SSH commands so that each step
|
|
1946
1971
|
* gets its own timeout window and produces a precise failure label.
|
|
1947
1972
|
*
|
|
1973
|
+
* The marker is written with `setFlag`: the flag name carries only the
|
|
1974
|
+
* date and no call-site identity, so an evicting prefix would be
|
|
1975
|
+
* host-global and two `apt.distUpgrade` calls with different dates would
|
|
1976
|
+
* delete each other's marker on every run. Retired markers are therefore
|
|
1977
|
+
* not pruned, and re-using an earlier date is skipped rather than re-run.
|
|
1978
|
+
*
|
|
1948
1979
|
* @param date - A date string used as the idempotency key (e.g. `"2024-01-15"`).
|
|
1949
1980
|
* @param options - Optional per-call overrides (e.g. SSH command `timeout`).
|
|
1950
1981
|
* The same `timeout` is applied to every step of the dist-upgrade pipeline.
|
|
@@ -1977,9 +2008,9 @@ var apt = {
|
|
|
1977
2008
|
);
|
|
1978
2009
|
if (upgrade.code !== 0)
|
|
1979
2010
|
return failedCommand("[apt.distUpgrade] apt-get dist-upgrade failed", upgrade);
|
|
1980
|
-
const flagFailure = await
|
|
2011
|
+
const flagFailure = await setFlag(ssh2, flagName);
|
|
1981
2012
|
if (flagFailure) return flagFailure;
|
|
1982
|
-
return { status: "changed" };
|
|
2013
|
+
return { detail: describeAptUpgradeOutcome(upgrade.stdout), status: "changed" };
|
|
1983
2014
|
},
|
|
1984
2015
|
flagName
|
|
1985
2016
|
});
|
|
@@ -10715,6 +10746,7 @@ async function runVersionedInstall(parameters) {
|
|
|
10715
10746
|
|
|
10716
10747
|
// src/modules/package.ts
|
|
10717
10748
|
var EXEC_OPTS12 = { ignoreExitCode: true, silent: true };
|
|
10749
|
+
var PACKAGE_INDEX_REFRESHED_DETAIL = "marker was missing, package index refreshed";
|
|
10718
10750
|
function execOptions(options) {
|
|
10719
10751
|
if (options?.timeout === void 0) return EXEC_OPTS12;
|
|
10720
10752
|
return { ...EXEC_OPTS12, timeout: options.timeout };
|
|
@@ -10946,7 +10978,16 @@ var pkg = {
|
|
|
10946
10978
|
* A flag file at `${FLAGS_DIRECTORY}/package-update-<date>` is created after
|
|
10947
10979
|
* a successful run. On the next run the flag is detected and the module
|
|
10948
10980
|
* reports `"ok"` without running the update again. Changing `date` to a new
|
|
10949
|
-
* value
|
|
10981
|
+
* value selects a new flag file, so the update runs once more.
|
|
10982
|
+
*
|
|
10983
|
+
* The marker is written with `setFlag`, not `setVersionedFlag`: the flag
|
|
10984
|
+
* name carries no call-site identity, only the date. An evicting prefix
|
|
10985
|
+
* would therefore be host-global, and two `package.update` calls with
|
|
10986
|
+
* different dates would delete each other's marker on every run so that
|
|
10987
|
+
* neither could ever converge. Two consequences are accepted deliberately:
|
|
10988
|
+
* markers for retired dates are not pruned (one empty file per distinct
|
|
10989
|
+
* date), and re-using an earlier date is skipped rather than re-run,
|
|
10990
|
+
* because that marker still exists.
|
|
10950
10991
|
*
|
|
10951
10992
|
* @param date - A date string used as the idempotency key (e.g. `"2024-01-15"`).
|
|
10952
10993
|
* @param options - Optional per-call overrides (e.g. SSH command `timeout`).
|
|
@@ -10968,9 +11009,9 @@ var pkg = {
|
|
|
10968
11009
|
if (result.code !== 0) {
|
|
10969
11010
|
return failedCommand(`[package.update: ${date}] package index refresh failed`, result);
|
|
10970
11011
|
}
|
|
10971
|
-
const flagFailure = await
|
|
11012
|
+
const flagFailure = await setFlag(ssh2, flagName);
|
|
10972
11013
|
if (flagFailure) return flagFailure;
|
|
10973
|
-
return { status: "changed" };
|
|
11014
|
+
return { detail: PACKAGE_INDEX_REFRESHED_DETAIL, status: "changed" };
|
|
10974
11015
|
},
|
|
10975
11016
|
async check(ssh2) {
|
|
10976
11017
|
if (!ssh2) return NEEDS_APPLY;
|
|
@@ -10985,7 +11026,13 @@ var pkg = {
|
|
|
10985
11026
|
* A flag file at `${FLAGS_DIRECTORY}/package-upgrade-<date>` is created after
|
|
10986
11027
|
* a successful run. On the next run the flag is detected and the module
|
|
10987
11028
|
* reports `"ok"` without running the upgrade again. Changing `date` to a new
|
|
10988
|
-
* value
|
|
11029
|
+
* value selects a new flag file, so the upgrade runs once more.
|
|
11030
|
+
*
|
|
11031
|
+
* The marker is written with `setFlag` for the same reason as in
|
|
11032
|
+
* `pkg.update`: the flag name carries only the date, so an
|
|
11033
|
+
* evicting prefix would be host-global and sibling calls could never
|
|
11034
|
+
* converge. Retired markers are therefore not pruned, and re-using an
|
|
11035
|
+
* earlier date is skipped rather than re-run.
|
|
10989
11036
|
*
|
|
10990
11037
|
* On apt systems this runs `dpkg --configure -a`, `apt-get update`, and
|
|
10991
11038
|
* `apt-get upgrade -y` as three separate commands (each subject to its own
|
|
@@ -11011,15 +11058,20 @@ var pkg = {
|
|
|
11011
11058
|
const pm = await detectPackageManager(ssh2);
|
|
11012
11059
|
if (!pm) return missingPackageManager(`package.upgrade: ${date}`);
|
|
11013
11060
|
const pipelineOptions = execOptions(options);
|
|
11061
|
+
let lastStdout = "";
|
|
11014
11062
|
for (const command2 of UPGRADE_COMMANDS[pm]) {
|
|
11015
11063
|
const result = await ssh2.exec(command2, pipelineOptions);
|
|
11016
11064
|
if (result.code !== 0) {
|
|
11017
11065
|
return failedCommand(`[package.upgrade: ${date}] package upgrade failed`, result);
|
|
11018
11066
|
}
|
|
11067
|
+
lastStdout = result.stdout;
|
|
11019
11068
|
}
|
|
11020
|
-
const flagFailure = await
|
|
11069
|
+
const flagFailure = await setFlag(ssh2, flagName);
|
|
11021
11070
|
if (flagFailure) return flagFailure;
|
|
11022
|
-
return {
|
|
11071
|
+
return {
|
|
11072
|
+
detail: pm === "apt" ? describeAptUpgradeOutcome(lastStdout) : UNKNOWN_UPGRADE_OUTCOME_DETAIL,
|
|
11073
|
+
status: "changed"
|
|
11074
|
+
};
|
|
11023
11075
|
},
|
|
11024
11076
|
async check(ssh2) {
|
|
11025
11077
|
if (!ssh2) return NEEDS_APPLY;
|
package/dist/cli.js
CHANGED
|
@@ -6262,7 +6262,7 @@ async function runApplyCommand(file, options, run = runPlaybook) {
|
|
|
6262
6262
|
if (options.diff && !options.dryRun) {
|
|
6263
6263
|
throw new CliUsageError("--diff requires --dry-run");
|
|
6264
6264
|
}
|
|
6265
|
-
printCliHeader("0.
|
|
6265
|
+
printCliHeader("0.17.0-a7265db");
|
|
6266
6266
|
const environmentOverrides = applyCliEnvironmentOverrides(options.env, {
|
|
6267
6267
|
firstRun: options.firstRun
|
|
6268
6268
|
});
|
|
@@ -6300,7 +6300,7 @@ function renderSubcommandOptionsHelp(command) {
|
|
|
6300
6300
|
return ["", `Options for "paratix ${command.name()} <file>":`, ...rows].join("\n");
|
|
6301
6301
|
}
|
|
6302
6302
|
var program = new Command();
|
|
6303
|
-
program.name("paratix").description("Idempotent VPS setup tool in TypeScript").version("0.
|
|
6303
|
+
program.name("paratix").description("Idempotent VPS setup tool in TypeScript").version("0.17.0-a7265db");
|
|
6304
6304
|
var applyCommand = program.command("apply <file>").description("Apply a server definition").option(
|
|
6305
6305
|
"--diff",
|
|
6306
6306
|
"When combined with --dry-run, show a unified diff per module that would change.",
|
|
@@ -429,7 +429,16 @@ declare const pkg: {
|
|
|
429
429
|
* A flag file at `${FLAGS_DIRECTORY}/package-update-<date>` is created after
|
|
430
430
|
* a successful run. On the next run the flag is detected and the module
|
|
431
431
|
* reports `"ok"` without running the update again. Changing `date` to a new
|
|
432
|
-
* value
|
|
432
|
+
* value selects a new flag file, so the update runs once more.
|
|
433
|
+
*
|
|
434
|
+
* The marker is written with `setFlag`, not `setVersionedFlag`: the flag
|
|
435
|
+
* name carries no call-site identity, only the date. An evicting prefix
|
|
436
|
+
* would therefore be host-global, and two `package.update` calls with
|
|
437
|
+
* different dates would delete each other's marker on every run so that
|
|
438
|
+
* neither could ever converge. Two consequences are accepted deliberately:
|
|
439
|
+
* markers for retired dates are not pruned (one empty file per distinct
|
|
440
|
+
* date), and re-using an earlier date is skipped rather than re-run,
|
|
441
|
+
* because that marker still exists.
|
|
433
442
|
*
|
|
434
443
|
* @param date - A date string used as the idempotency key (e.g. `"2024-01-15"`).
|
|
435
444
|
* @param options - Optional per-call overrides (e.g. SSH command `timeout`).
|
|
@@ -446,7 +455,13 @@ declare const pkg: {
|
|
|
446
455
|
* A flag file at `${FLAGS_DIRECTORY}/package-upgrade-<date>` is created after
|
|
447
456
|
* a successful run. On the next run the flag is detected and the module
|
|
448
457
|
* reports `"ok"` without running the upgrade again. Changing `date` to a new
|
|
449
|
-
* value
|
|
458
|
+
* value selects a new flag file, so the upgrade runs once more.
|
|
459
|
+
*
|
|
460
|
+
* The marker is written with `setFlag` for the same reason as in
|
|
461
|
+
* `pkg.update`: the flag name carries only the date, so an
|
|
462
|
+
* evicting prefix would be host-global and sibling calls could never
|
|
463
|
+
* converge. Retired markers are therefore not pruned, and re-using an
|
|
464
|
+
* earlier date is skipped rather than re-run.
|
|
450
465
|
*
|
|
451
466
|
* On apt systems this runs `dpkg --configure -a`, `apt-get update`, and
|
|
452
467
|
* `apt-get upgrade -y` as three separate commands (each subject to its own
|
|
@@ -504,6 +519,12 @@ declare const apt: {
|
|
|
504
519
|
* The pipeline is split into three separate SSH commands so that each step
|
|
505
520
|
* gets its own timeout window and produces a precise failure label.
|
|
506
521
|
*
|
|
522
|
+
* The marker is written with `setFlag`: the flag name carries only the
|
|
523
|
+
* date and no call-site identity, so an evicting prefix would be
|
|
524
|
+
* host-global and two `apt.distUpgrade` calls with different dates would
|
|
525
|
+
* delete each other's marker on every run. Retired markers are therefore
|
|
526
|
+
* not pruned, and re-using an earlier date is skipped rather than re-run.
|
|
527
|
+
*
|
|
507
528
|
* @param date - A date string used as the idempotency key (e.g. `"2024-01-15"`).
|
|
508
529
|
* @param options - Optional per-call overrides (e.g. SSH command `timeout`).
|
|
509
530
|
* The same `timeout` is applied to every step of the dist-upgrade pipeline.
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { E as Environment, M as Module, a as ModuleMetaEntry, b as MetaEnvironmentValue, c as EnvironmentMetaEntry, S as SshdPortMetaEntry, d as SystemHostMetaEntry, e as SystemRebootMetaEntry, f as ModuleResult, g as ExecResult, h as ModuleStatus, i as SshConnection, O as OrchestrationStep, j as ShutdownSignal, k as ServerDefinition } from './index-
|
|
2
|
-
export { l as EnvironmentValue, m as ExecOptions, N as NEEDS_APPLY, n as SshConfig, o as apt, p as archive, q as command, r as compose, s as cron, t as download, u as file, v as git, w as group, x as hostname, y as mount, z as net, A as op, B as package, C as quadlet, D as releaseUpgrade, F as rsync, G as script, H as service, I as ssh, J as sshd, K as swap, L as sysctl, P as system, Q as systemd, R as timer, T as ufw, U as user } from './index-
|
|
1
|
+
import { E as Environment, M as Module, a as ModuleMetaEntry, b as MetaEnvironmentValue, c as EnvironmentMetaEntry, S as SshdPortMetaEntry, d as SystemHostMetaEntry, e as SystemRebootMetaEntry, f as ModuleResult, g as ExecResult, h as ModuleStatus, i as SshConnection, O as OrchestrationStep, j as ShutdownSignal, k as ServerDefinition } from './index-CGYwJDTf.js';
|
|
2
|
+
export { l as EnvironmentValue, m as ExecOptions, N as NEEDS_APPLY, n as SshConfig, o as apt, p as archive, q as command, r as compose, s as cron, t as download, u as file, v as git, w as group, x as hostname, y as mount, z as net, A as op, B as package, C as quadlet, D as releaseUpgrade, F as rsync, G as script, H as service, I as ssh, J as sshd, K as swap, L as sysctl, P as system, Q as systemd, R as timer, T as ufw, U as user } from './index-CGYwJDTf.js';
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* Fail the run if a condition on the current env is not satisfied.
|
package/dist/index.js
CHANGED
package/dist/modules/index.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export { V as PackageSpec, W as UpgradeOptions, o as apt, p as archive, q as command, r as compose, s as cron, t as download, u as file, v as git, w as group, x as hostname, y as mount, z as net, A as op, B as package, C as quadlet, D as releaseUpgrade, F as rsync, G as script, H as service, I as ssh, J as sshd, K as swap, L as sysctl, P as system, Q as systemd, R as timer, T as ufw, U as user } from '../index-
|
|
1
|
+
export { V as PackageSpec, W as UpgradeOptions, o as apt, p as archive, q as command, r as compose, s as cron, t as download, u as file, v as git, w as group, x as hostname, y as mount, z as net, A as op, B as package, C as quadlet, D as releaseUpgrade, F as rsync, G as script, H as service, I as ssh, J as sshd, K as swap, L as sysctl, P as system, Q as systemd, R as timer, T as ufw, U as user } from '../index-CGYwJDTf.js';
|
package/dist/modules/index.js
CHANGED
package/llm-guide.md
CHANGED
|
@@ -142,12 +142,12 @@ export default server({
|
|
|
142
142
|
|
|
143
143
|
### `apt`
|
|
144
144
|
|
|
145
|
-
| Method | Signature | Idempotent
|
|
146
|
-
| ----------------- | ---------------------------------------------------------------------------------------- |
|
|
147
|
-
| `apt.debconf` | `(packageName: string, selections: Record<string, string>): Module` | Yes
|
|
148
|
-
| `apt.distUpgrade` | `(date: string, options?: UpgradeOptions): Module` | Yes (
|
|
149
|
-
| `apt.key` | `(name: string, url: string, options: { fingerprint: string }): Module` | Yes
|
|
150
|
-
| `apt.repository` | `(nameOrPpa: string, source?: string, options?: { signedBy?: false \| string }): Module` | Yes
|
|
145
|
+
| Method | Signature | Idempotent |
|
|
146
|
+
| ----------------- | ---------------------------------------------------------------------------------------- | ---------------- |
|
|
147
|
+
| `apt.debconf` | `(packageName: string, selections: Record<string, string>): Module` | Yes |
|
|
148
|
+
| `apt.distUpgrade` | `(date: string, options?: UpgradeOptions): Module` | Yes (dated flag) |
|
|
149
|
+
| `apt.key` | `(name: string, url: string, options: { fingerprint: string }): Module` | Yes |
|
|
150
|
+
| `apt.repository` | `(nameOrPpa: string, source?: string, options?: { signedBy?: false \| string }): Module` | Yes |
|
|
151
151
|
|
|
152
152
|
### `archive`
|
|
153
153
|
|
|
@@ -288,12 +288,12 @@ that are expected to respond more slowly.
|
|
|
288
288
|
|
|
289
289
|
Import with renaming: `import { package as pkg } from "paratix/modules"`. The word `package` is reserved in JavaScript, so you must alias it.
|
|
290
290
|
|
|
291
|
-
| Method | Signature | Idempotent
|
|
292
|
-
| ------------------- | --------------------------------------------------------------------------------- |
|
|
293
|
-
| `package.installed` | `(...packagesAndOptions: Array<string \| PackageSpec \| UpgradeOptions>): Module` | Yes
|
|
294
|
-
| `package.absent` | `(...packagesAndOptions: Array<string \| PackageSpec \| UpgradeOptions>): Module` | Yes
|
|
295
|
-
| `package.update` | `(date: string, options?: UpgradeOptions): Module` | Yes (
|
|
296
|
-
| `package.upgrade` | `(date: string, options?: UpgradeOptions): Module` | Yes (
|
|
291
|
+
| Method | Signature | Idempotent |
|
|
292
|
+
| ------------------- | --------------------------------------------------------------------------------- | ---------------- |
|
|
293
|
+
| `package.installed` | `(...packagesAndOptions: Array<string \| PackageSpec \| UpgradeOptions>): Module` | Yes |
|
|
294
|
+
| `package.absent` | `(...packagesAndOptions: Array<string \| PackageSpec \| UpgradeOptions>): Module` | Yes |
|
|
295
|
+
| `package.update` | `(date: string, options?: UpgradeOptions): Module` | Yes (dated flag) |
|
|
296
|
+
| `package.upgrade` | `(date: string, options?: UpgradeOptions): Module` | Yes (dated flag) |
|
|
297
297
|
|
|
298
298
|
#### `UpgradeOptions`
|
|
299
299
|
|
|
@@ -542,6 +542,7 @@ function myCustomModule(configPath: string, content: string): Module {
|
|
|
542
542
|
- Prefer `failedCommand("...", result)` when you used `ssh.exec(..., { ignoreExitCode: true })` and want stdout/stderr preserved for central runner output.
|
|
543
543
|
- Return `NEEDS_APPLY` (the exported constant), never the string literal `"needs-apply"`.
|
|
544
544
|
- `ModuleResult.status` must be one of: `"changed"`, `"failed"`, `"ok"`, `"skipped"`.
|
|
545
|
+
- Optionally return `ModuleResult.detail` with a short single-line reason; the runner appends it to the step line. Use it to say what a `changed` step actually did, and leave it unset when the step did no work. See [Status Detail on Changed Steps](#status-detail-on-changed-steps).
|
|
545
546
|
- Use typed `meta` entries in the return value, not loose objects.
|
|
546
547
|
- For normal downstream environment propagation, use `meta.env(name, value)`.
|
|
547
548
|
- `meta.env(...)` accepts strings, numbers, booleans, sync lazy functions, and async lazy functions.
|
|
@@ -782,6 +783,43 @@ async check(ssh) {
|
|
|
782
783
|
}
|
|
783
784
|
```
|
|
784
785
|
|
|
786
|
+
## Status Detail on Changed Steps
|
|
787
|
+
|
|
788
|
+
A module may return a short `detail` next to its status. The runner appends it to
|
|
789
|
+
the step line, both for top-level modules and for steps inside a recipe:
|
|
790
|
+
|
|
791
|
+
```
|
|
792
|
+
· · ↺ package.upgrade: 2026-03-01 changed no packages upgraded 4.1s
|
|
793
|
+
```
|
|
794
|
+
|
|
795
|
+
The dated-flag modules use this to say **why** they ran. Their step name already
|
|
796
|
+
carries the date, so the detail reports the outcome instead of repeating the key.
|
|
797
|
+
This matters most for the upgrade modules: they report `changed` whenever their
|
|
798
|
+
dated marker is absent, even when the package manager upgraded nothing.
|
|
799
|
+
|
|
800
|
+
| Module | Detail on `changed` |
|
|
801
|
+
| ----------------- | ----------------------------------------------------------------------- |
|
|
802
|
+
| `package.update` | `marker was missing, package index refreshed` |
|
|
803
|
+
| `package.upgrade` | `12 packages upgraded`, `1 package upgraded`, or `no packages upgraded` |
|
|
804
|
+
| `apt.distUpgrade` | same forms as `package.upgrade` |
|
|
805
|
+
|
|
806
|
+
Rules:
|
|
807
|
+
|
|
808
|
+
- The count is parsed from apt's upgrade summary. `package.upgrade` also serves
|
|
809
|
+
`dnf`, `yum` and `apk`, whose summaries differ; those report
|
|
810
|
+
`upgrade completed, package count unavailable`.
|
|
811
|
+
- The same fallback applies when the summary line is missing from the output, or
|
|
812
|
+
when the captured output was truncated at `maxOutputBytes`. apt prints its
|
|
813
|
+
summary last, so a truncated capture loses exactly that line, and reporting no
|
|
814
|
+
count is preferred over reporting a wrong one.
|
|
815
|
+
- A step that did no work carries no detail: the flag-already-exists path returns
|
|
816
|
+
a plain `ok`, and failures report through the normal error path.
|
|
817
|
+
- Dry runs keep the generic `changed (dry-run)` suffix. The detail is produced by
|
|
818
|
+
`apply`, which does not run in dry-run mode.
|
|
819
|
+
|
|
820
|
+
Custom modules may return `detail` the same way; see
|
|
821
|
+
[Key rules for custom modules](#key-rules-for-custom-modules).
|
|
822
|
+
|
|
785
823
|
## Dry-Run Diff Output (`--diff`)
|
|
786
824
|
|
|
787
825
|
Paratix runs a playbook in dry-run mode via `paratix apply <file> --dry-run`, which
|
|
@@ -885,7 +923,7 @@ The diff string is plain text — no ANSI codes. The output layer applies colors
|
|
|
885
923
|
5. Use `{{KEY|shell}}` or `{{KEY|raw}}` placeholders in `.tmpl` files — strict mode is on by default and bare `{{KEY}}` will throw. Provide values via `env` in `server()`.
|
|
886
924
|
6. Use `service.restart()` and `service.reload()` as `signals` in recipes, not directly in `run`.
|
|
887
925
|
7. Use `signals.flush()` only as an explicit checkpoint when staged flows require an early signal flush.
|
|
888
|
-
8. Always pass a date string to `package.upgrade()` and `package.update()` -- it is the idempotency key.
|
|
926
|
+
8. Always pass a date string to `package.upgrade()` and `package.update()` -- it is the idempotency key. Each distinct date keeps its own flag file, so several calls with different dates coexist; a date that was already applied stays applied and is not re-run. Read the step's [status detail](#status-detail-on-changed-steps) to tell a real upgrade from a step that only wrote its marker.
|
|
889
927
|
9. Specify `ssh.ports` as an array -- the runner tries each port in order.
|
|
890
928
|
10. Custom modules must implement both `check` and `apply`, both async.
|
|
891
929
|
11. Use `shellQuote()` when interpolating dynamic values into shell commands.
|