toolroll 0.8.0 → 0.8.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.
@@ -2,6 +2,7 @@ import type { DatabaseSync } from "node:sqlite";
2
2
  import { type SupervisorRunner } from "./daemon.js";
3
3
  export declare const PROVENANCE_REPOSITORY = "https://github.com/ap9000/toolroll";
4
4
  export declare const PROVENANCE_WORKFLOW = ".github/workflows/publish.yml";
5
+ export declare const PROVENANCE_ISSUER = "https://token.actions.githubusercontent.com";
5
6
  /** The steps a person sees, in order. */
6
7
  export declare const UPDATE_STEPS: readonly ["verifying", "draining", "backing-up", "rehearsing", "switching", "restarting", "health"];
7
8
  export type UpdateStep = typeof UPDATE_STEPS[number];
@@ -66,6 +67,11 @@ export type RuntimeUpdateJournal = {
66
67
  unit: string;
67
68
  pids: number[];
68
69
  };
70
+ /** Each repo's watch daemon that runs this version, recorded the same way: stopped, switched and restarted with the service. */
71
+ watches?: {
72
+ unit: string;
73
+ pids: number[];
74
+ }[];
69
75
  /** Recorded before each change so a resumed or failed run knows what to put back. */
70
76
  switched?: {
71
77
  links: {
@@ -76,10 +82,16 @@ export type RuntimeUpdateJournal = {
76
82
  path: string;
77
83
  saved: string;
78
84
  } | null;
85
+ watches?: {
86
+ path: string;
87
+ saved: string;
88
+ }[];
79
89
  databaseRestored?: boolean;
80
90
  };
81
91
  /** What the live database held when a failed run restored its backup: nothing written is lost. */
82
92
  keptAside?: string;
93
+ /** The live database could not be read, so it was moved aside whole rather than copied. */
94
+ keptAsideUnreadable?: boolean;
83
95
  /** The restore put the backup back: a retried restore never puts it back again (what was written since belongs to
84
96
  * the restored version and would be lost), and it keeps a fresh copy aside before every attempt until then. */
85
97
  restoredDatabase?: boolean;
@@ -107,6 +119,14 @@ export type UpdateSystem = {
107
119
  commands: (from: RuntimeRef) => string[];
108
120
  /** The background service's definition, when one runs `from`. */
109
121
  serviceUnit: (from: RuntimeRef) => string | null;
122
+ /** Every repo's watch daemon definition that runs `from`. */
123
+ watchUnits: (from: RuntimeRef) => string[];
124
+ /** npm's own Sigstore verifier: the bundle's certificate chains to Sigstore, its signature is in the transparency
125
+ * log, and the certificate names exactly this identity. */
126
+ sigstore: (bundle: unknown, identity: {
127
+ issuer: string;
128
+ identity: string;
129
+ }) => Promise<void>;
110
130
  /** The processes the service runs now. */
111
131
  servicePids: (unit: string) => Promise<number[]>;
112
132
  /** Unload the service; resolves once launchd no longer has it. */
@@ -128,16 +148,23 @@ export type UpdateOutcome = {
128
148
  journal: RuntimeUpdateJournal | null;
129
149
  };
130
150
  export declare const runtimeUpdateTerminal: (phase: RuntimePhase) => boolean;
131
- export declare function readRuntimeUpdate(stateDir: string): RuntimeUpdateJournal | null;
151
+ export declare function readRuntimeUpdate(stateDir: string, file?: string): RuntimeUpdateJournal | null;
152
+ /** The update `--rollback` returns from: the last one that completed, whatever was attempted since. */
153
+ export declare function lastCompletedUpdate(stateDir: string): RuntimeUpdateJournal | null;
132
154
  /** Running work by name, for a refusal a person can act on. */
133
155
  export declare function runningWorkWords(db: DatabaseSync): string | null;
134
- /** The npm provenance statement for exactly these bytes must name the
135
- * Toolroll repository and its publish workflow. Anything else is refused.
136
- * npm's own check (UpdateSystem.install) verifies the statement's signature. */
137
- export declare function checkProvenance(attestations: unknown, version: string, sha512Hex: string): {
156
+ export type Provenance = {
138
157
  repository: string;
139
158
  workflow: string;
159
+ issuer: string;
160
+ identity: string;
161
+ bundle: unknown;
140
162
  };
163
+ /** The npm provenance for exactly these bytes of Toolroll itself must be signed by a certificate that names the
164
+ * Toolroll repository, its publish workflow and GitHub Actions as the issuer. The statement's own claims name
165
+ * nobody: only the certificate, whose key must have signed the statement. Sigstore's chain and transparency log are
166
+ * then checked by npm's own verifier (UpdateSystem.sigstore) for the identity returned here. */
167
+ export declare function checkProvenance(attestations: unknown, version: string, sha512Hex: string): Provenance;
141
168
  /** Headlines of this version's changelog section: its bold lead phrases. */
142
169
  export declare function releaseNotes(changelog: string, version: string): string[];
143
170
  /** Every rename here: what is renamed is flushed first (a file itself, a link
@@ -184,7 +211,7 @@ export declare function startRuntimeRollback(o: {
184
211
  export declare function resumeRuntimeUpdate(stateDir: string, system: UpdateSystem, id?: string): Promise<UpdateOutcome>;
185
212
  /** A prepared update whose job could not start. */
186
213
  export declare function abandonRuntimeUpdate(stateDir: string, id: string, why: string, now: Date): void;
187
- export declare function requestRuntimeUpdateCancel(stateDir: string): string;
214
+ export declare function requestRuntimeUpdateCancel(stateDir: string, now?: Date): string;
188
215
  /** Keep the newest release-* runtimes (and any in `keep`), at most KEEP_RUNTIMES; deploy-browser's browser-* and
189
216
  * the rollback-* records are not this updater's to remove. */
190
217
  export declare function pruneRuntimes(stateDir: string, keep: readonly string[]): string[];
@@ -202,24 +229,30 @@ export declare function markWhatsNewSeen(stateDir: string): void;
202
229
  type Exec = (command: string, args: string[], options?: {
203
230
  cwd?: string;
204
231
  timeout?: number;
232
+ input?: string;
205
233
  }) => {
206
234
  status: number | null;
207
235
  stdout: string;
208
236
  stderr: string;
209
237
  };
210
238
  export declare function currentRuntime(version: string): RuntimeRef;
211
- /** Seams for tests: npm and ps (`exec`), launchctl (`run`), and process liveness. */
239
+ /** Seams for tests: npm, node and ps (`exec`), launchctl (`run`), process liveness, and launchd's waits (`sleep`). */
212
240
  export type MachineSeams = {
213
241
  exec?: Exec;
214
242
  run?: SupervisorRunner;
215
243
  alive?: (pid: number) => boolean;
244
+ sleep?: (ms: number) => Promise<void>;
245
+ execPath?: string;
216
246
  };
217
247
  export declare function machineSystem(home?: string, env?: Record<string, string | undefined>, seams?: MachineSeams): UpdateSystem;
218
- /** The console starts the updater for one prepared journal as its own one-off
219
- * launchd job, so the service it restarts is not its parent. The job resumes
220
- * that id only; it does not run at login (no RunAtLoad: launchd starts it
221
- * with a kickstart) and removes its definition when it finishes. Elsewhere it
222
- * is a detached process. */
248
+ /** npm's own Sigstore verifier. Found from npm itself (the `npm` on PATH, then the one beside node), never only from
249
+ * `npm root --global`: with a custom global prefix (npm's advice for permission errors) that folder holds the global
250
+ * packages, not npm. */
251
+ export declare function findSigstoreVerifier(o: {
252
+ path: string;
253
+ execPath: string;
254
+ npmRoot: () => string | null;
255
+ }): string | null;
223
256
  export declare function launchRuntimeUpdate(args: {
224
257
  databaseFile: string;
225
258
  id: string;
@@ -228,6 +261,7 @@ export declare function launchRuntimeUpdate(args: {
228
261
  home?: string;
229
262
  run?: SupervisorRunner;
230
263
  platform?: NodeJS.Platform;
264
+ npmBin?: () => string | null;
231
265
  }): Promise<void>;
232
266
  /** The job's last act: its definition goes, so nothing can start it again. Only the definition for this id. */
233
267
  export declare function retireUpdateJob(id: string, home?: string): void;