@nocobase/app-installer 0.0.0-stage → 0.1.0-beta.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.
Files changed (71) hide show
  1. package/README.md +263 -2
  2. package/bin/run.js +43 -0
  3. package/dist/cli.js +212 -0
  4. package/dist/cli.js.map +1 -0
  5. package/dist/commands/install.js +333 -0
  6. package/dist/commands/install.js.map +1 -0
  7. package/dist/commands/rollback.js +289 -0
  8. package/dist/commands/rollback.js.map +1 -0
  9. package/dist/commands/status.js +134 -0
  10. package/dist/commands/status.js.map +1 -0
  11. package/dist/commands/upgrade.js +598 -0
  12. package/dist/commands/upgrade.js.map +1 -0
  13. package/dist/lib/app-cli.js +89 -0
  14. package/dist/lib/app-cli.js.map +1 -0
  15. package/dist/lib/app-source.js +163 -0
  16. package/dist/lib/app-source.js.map +1 -0
  17. package/dist/lib/backup.js +167 -0
  18. package/dist/lib/backup.js.map +1 -0
  19. package/dist/lib/checksum-repair.js +76 -0
  20. package/dist/lib/checksum-repair.js.map +1 -0
  21. package/dist/lib/confirm.js +36 -0
  22. package/dist/lib/confirm.js.map +1 -0
  23. package/dist/lib/current-link.js +22 -0
  24. package/dist/lib/current-link.js.map +1 -0
  25. package/dist/lib/ecosystem.js +82 -0
  26. package/dist/lib/ecosystem.js.map +1 -0
  27. package/dist/lib/env-file.js +87 -0
  28. package/dist/lib/env-file.js.map +1 -0
  29. package/dist/lib/errors.js +32 -0
  30. package/dist/lib/errors.js.map +1 -0
  31. package/dist/lib/health.js +55 -0
  32. package/dist/lib/health.js.map +1 -0
  33. package/dist/lib/initial-admin.js +39 -0
  34. package/dist/lib/initial-admin.js.map +1 -0
  35. package/dist/lib/interrupt.js +50 -0
  36. package/dist/lib/interrupt.js.map +1 -0
  37. package/dist/lib/invocation.js +33 -0
  38. package/dist/lib/invocation.js.map +1 -0
  39. package/dist/lib/layout.js +48 -0
  40. package/dist/lib/layout.js.map +1 -0
  41. package/dist/lib/lock.js +59 -0
  42. package/dist/lib/lock.js.map +1 -0
  43. package/dist/lib/mount-path.js +34 -0
  44. package/dist/lib/mount-path.js.map +1 -0
  45. package/dist/lib/offline-bundle.js +91 -0
  46. package/dist/lib/offline-bundle.js.map +1 -0
  47. package/dist/lib/output.js +61 -0
  48. package/dist/lib/output.js.map +1 -0
  49. package/dist/lib/pm2.js +92 -0
  50. package/dist/lib/pm2.js.map +1 -0
  51. package/dist/lib/prechecks.js +199 -0
  52. package/dist/lib/prechecks.js.map +1 -0
  53. package/dist/lib/registry.js +9 -0
  54. package/dist/lib/registry.js.map +1 -0
  55. package/dist/lib/release.js +173 -0
  56. package/dist/lib/release.js.map +1 -0
  57. package/dist/lib/remote.js +331 -0
  58. package/dist/lib/remote.js.map +1 -0
  59. package/dist/lib/run-command.js +198 -0
  60. package/dist/lib/run-command.js.map +1 -0
  61. package/dist/lib/service.js +100 -0
  62. package/dist/lib/service.js.map +1 -0
  63. package/dist/lib/source.js +54 -0
  64. package/dist/lib/source.js.map +1 -0
  65. package/dist/lib/state.js +87 -0
  66. package/dist/lib/state.js.map +1 -0
  67. package/dist/lib/version.js +51 -0
  68. package/dist/lib/version.js.map +1 -0
  69. package/dist/remote-entry.js +98 -0
  70. package/dist/remote-entry.js.map +1 -0
  71. package/package.json +53 -3
@@ -0,0 +1,598 @@
1
+ import { existsSync } from 'node:fs';
2
+ import { rm } from 'node:fs/promises';
3
+ import path from 'node:path';
4
+ import { Flags } from '@oclif/core';
5
+ import { buildApp, resolveApp } from "../lib/app-source.js";
6
+ import { pendingTaskCount, runAppCli } from "../lib/app-cli.js";
7
+ import { backupForUpgrade, backupName, readDatabaseInventory, removeBackup, restoreDatabase, } from "../lib/backup.js";
8
+ import { confirm } from "../lib/confirm.js";
9
+ import { previewChecksumRepair, requireChecksumApproval, } from "../lib/checksum-repair.js";
10
+ import { switchCurrent } from "../lib/current-link.js";
11
+ import { healthUrl, mountPathOf, readAppEnv } from "../lib/env-file.js";
12
+ import { assertFixedMountPath } from "../lib/mount-path.js";
13
+ import { EXIT_FAILED, EXIT_INVALID, EXIT_ROLLBACK_FAILED, EXIT_ROLLED_BACK, InstallerError, } from "../lib/errors.js";
14
+ import { quoteForShell } from '@nocobase/cli-envelope';
15
+ import { installerCommand, installerCommandLine } from "../lib/invocation.js";
16
+ import { layoutOf, releaseDir, releaseLinkTarget, } from "../lib/layout.js";
17
+ import { acquireLock } from "../lib/lock.js";
18
+ import { checkPlatform, checkPm2, checkPortFree, currentNodeMajor, } from "../lib/prechecks.js";
19
+ import { assertStorageOutsideRelease, checkArchiveDriver, unpackRelease, } from "../lib/release.js";
20
+ import { runCommand } from "../lib/run-command.js";
21
+ import { resolveArchivePath } from "../lib/source.js";
22
+ import { checkPm2Ownership, errorLogCommandLine, errorLogTail, startAdvice, startApp, stopApp, } from "../lib/service.js";
23
+ import { findRelease, fixedMountPathOf, readState, writeState, } from "../lib/state.js";
24
+ import { compareVersions } from "../lib/version.js";
25
+ export const UPGRADE_FLAGS = {
26
+ dir: Flags.string({
27
+ description: 'Installation root managed by app-installer. Defaults to the current directory.',
28
+ }),
29
+ to: Flags.string({
30
+ description: 'Version or dist-tag of an npm application to install; defaults to latest.',
31
+ }),
32
+ rebuild: Flags.boolean({
33
+ default: false,
34
+ description: 'Build the currently installed npm application version again for this machine.',
35
+ }),
36
+ archive: Flags.string({
37
+ description: 'The new deployment archive, built by `pnpm build --tar` for this machine.',
38
+ }),
39
+ 'backup-done': Flags.boolean({
40
+ default: false,
41
+ description: 'Confirm that the databases app-installer cannot back up, any but SQLite, are backed up.',
42
+ }),
43
+ 'repair-checksums': Flags.string({
44
+ description: 'Authorize only the checksum repair plan identified by the token returned during preflight.',
45
+ }),
46
+ 'health-timeout': Flags.integer({
47
+ default: 180,
48
+ min: 1,
49
+ description: 'Seconds to wait for the new release to answer its health check.',
50
+ }),
51
+ keep: Flags.integer({
52
+ default: 3,
53
+ min: 2,
54
+ description: 'Releases to keep on disk, counting the new one; the one upgraded from is always kept so rollback stays possible.',
55
+ }),
56
+ yes: Flags.boolean({
57
+ default: false,
58
+ description: 'Proceed without asking for confirmation.',
59
+ }),
60
+ json: Flags.boolean({
61
+ default: false,
62
+ description: 'Print one JSON result on stdout; progress stays on stderr.',
63
+ }),
64
+ };
65
+ /** The installation was interrupted by a previous operation that never finished; refuse to stack another on top. */
66
+ export function assertNoPending(state, root) {
67
+ if (!state.pending)
68
+ return;
69
+ const { action, from, to, startedAt } = state.pending;
70
+ throw new InstallerError('OPERATION_INTERRUPTED', `${action === 'upgrade' ? 'An upgrade from' : 'A rollback from'} ${from} to ${to}, started ${startedAt}, did not finish; the application may be stopped or half-switched.`, {
71
+ exitCode: EXIT_INVALID,
72
+ suggestions: [
73
+ {
74
+ message: 'Recover first; an interrupted upgrade is undone and an interrupted rollback is finished:',
75
+ run: installerCommandLine(['rollback', '--dir', root], {
76
+ registry: state.registry,
77
+ }),
78
+ },
79
+ ],
80
+ });
81
+ }
82
+ /**
83
+ * Keeps the newest `keep` releases by install time. `protect` — the current release and the one it was upgraded from,
84
+ * which `rollback` returns to — is never pruned, whatever its install time.
85
+ */
86
+ export function releasesToPrune(releases, protect, keep) {
87
+ const newestFirst = [...releases].sort((a, b) => b.installedAt.localeCompare(a.installedAt));
88
+ const kept = new Set(protect);
89
+ for (const record of newestFirst) {
90
+ if (kept.size >= keep)
91
+ break;
92
+ kept.add(record.id);
93
+ }
94
+ return releases.filter((record) => !kept.has(record.id));
95
+ }
96
+ function recordOf(prepared) {
97
+ return {
98
+ id: prepared.id,
99
+ version: prepared.version,
100
+ builtAt: prepared.builtAt,
101
+ installedAt: new Date().toISOString(),
102
+ buildTarget: prepared.buildTarget,
103
+ ...(prepared.relocatable
104
+ ? { relocatable: true }
105
+ : { basePath: prepared.basePath }),
106
+ };
107
+ }
108
+ function replaceRecord(state, record) {
109
+ state.releases = [
110
+ ...state.releases.filter((entry) => entry.id !== record.id),
111
+ record,
112
+ ];
113
+ }
114
+ /** An upgrade moves to another deployment archive, which `--archive` names. */
115
+ function requireArchive(state, root, flags) {
116
+ if (flags.archive === undefined) {
117
+ throw new InstallerError('INVALID_USAGE', `${root} upgrades from a deployment archive; pass the new one with --archive.`, {
118
+ exitCode: EXIT_INVALID,
119
+ // No `run`: a suggestion's command runs as printed, and the archive's path is not known here.
120
+ suggestions: [
121
+ {
122
+ message: `Build it for this machine in the application project, copy it to the server, then run: ${installerCommand(`upgrade --dir ${quoteForShell(root)} --archive <the copied archive>`, { registry: state.registry })}`,
123
+ },
124
+ ],
125
+ });
126
+ }
127
+ return flags.archive;
128
+ }
129
+ /**
130
+ * The archive must be a later build of the same application: its package name owns the migration history in the
131
+ * database. An archive from before relocatable builds also has its base path compiled into the client, so it has to
132
+ * be the path the installation serves now.
133
+ */
134
+ function checkArchiveMatches(state, prepared, env) {
135
+ if (prepared.appName !== state.appName) {
136
+ throw new InstallerError('APP_MISMATCH', `The archive holds ${prepared.appName}, but this installation runs ${state.appName}; a different application has a migration history of its own.`, {
137
+ exitCode: EXIT_INVALID,
138
+ suggestions: [
139
+ {
140
+ message: 'Install a different application into a directory of its own with install --archive.',
141
+ },
142
+ ],
143
+ });
144
+ }
145
+ if (!prepared.relocatable) {
146
+ assertFixedMountPath('The archive', prepared.basePath, mountPathOf(env));
147
+ }
148
+ }
149
+ /**
150
+ * Undoes an upgrade that failed after the switch: the new release is stopped, `current` goes back, the databases are
151
+ * restored when the new release may have migrated them, and the previous release is started again. Always throws: exit
152
+ * 3 when the previous release is healthy again, exit 4 when it is not.
153
+ *
154
+ * When the previous release does not come back, the operation stays pending and the new release stays on disk and on
155
+ * record: it may be the only one that can run, as when the machine's Node major changed, and `rollback` recovers from
156
+ * the pending state.
157
+ */
158
+ async function rollBackUpgrade(context) {
159
+ const { layout, state, service, from, to, backup } = context;
160
+ const reason = context.cause instanceof Error
161
+ ? context.cause.message
162
+ : String(context.cause);
163
+ await service.pm2.remove(service.name).catch(() => undefined);
164
+ const log = await errorLogTail(layout);
165
+ const hasDatabase = backup.databases.some((database) => database.files.length > 0);
166
+ let databaseRestored = false;
167
+ let healthy = false;
168
+ let rollbackError;
169
+ try {
170
+ await switchCurrent(layout, releaseLinkTarget(from.id));
171
+ if ((context.pending > 0 || context.checksumRepairs > 0) && hasDatabase) {
172
+ await restoreDatabase(layout, backup.relative);
173
+ databaseRestored = true;
174
+ }
175
+ healthy = await startApp({ ...service, timeoutMs: context.timeoutMs });
176
+ }
177
+ catch (error) {
178
+ rollbackError = error;
179
+ }
180
+ const kept = context.newRecord !== undefined;
181
+ if (healthy) {
182
+ if (kept) {
183
+ await rm(path.dirname(releaseDir(layout, to.id)), {
184
+ recursive: true,
185
+ force: true,
186
+ });
187
+ }
188
+ delete state.pending;
189
+ }
190
+ else if (kept) {
191
+ replaceRecord(state, context.newRecord);
192
+ }
193
+ state.history.push({
194
+ action: 'upgrade',
195
+ from: from.id,
196
+ to: to.id,
197
+ at: new Date().toISOString(),
198
+ outcome: 'rolled-back',
199
+ migrations: context.pending,
200
+ checksumRepairs: context.checksumRepairs,
201
+ backup: backup.relative,
202
+ databaseRestored,
203
+ });
204
+ await writeState(layout, state);
205
+ const doing = `Upgrading to ${to.id}`;
206
+ const externalDatabaseNote = (context.pending > 0 || context.checksumRepairs > 0) &&
207
+ context.externalConnections.length > 0
208
+ ? ` ${to.id} may already have migrated or repaired the external database connections ${context.externalConnections.join(', ')}; these were not restored. Restore them from your own pre-upgrade backup before relying on ${from.id}.`
209
+ : '';
210
+ if (healthy) {
211
+ throw new InstallerError('UPGRADE_ROLLED_BACK', `${doing} failed (${reason}). ${from.id} is running again${databaseRestored ? ' on the databases restored from the backup' : ''}.${externalDatabaseNote}`, {
212
+ exitCode: EXIT_ROLLED_BACK,
213
+ details: { log, backup: backup.relative, databaseRestored },
214
+ suggestions: [
215
+ {
216
+ message: 'The failed release logged:',
217
+ run: errorLogCommandLine(layout),
218
+ },
219
+ ],
220
+ });
221
+ }
222
+ throw new InstallerError('ROLLBACK_FAILED', `${doing} failed (${reason}), and ${from.id} did not come back either${rollbackError instanceof Error ? ` (${rollbackError.message})` : ''}. The application is down.`, {
223
+ exitCode: EXIT_ROLLBACK_FAILED,
224
+ details: { log, backup: backup.relative, databaseRestored },
225
+ suggestions: [
226
+ {
227
+ message: 'Read the error log:',
228
+ run: errorLogCommandLine(layout),
229
+ },
230
+ ...(hasDatabase && !databaseRestored
231
+ ? [
232
+ {
233
+ message: `The databases from before the upgrade are in ${path.join(layout.root, backup.relative)}; the rollback below restores them from there.`,
234
+ },
235
+ ]
236
+ : []),
237
+ {
238
+ message: 'Once the cause is fixed, finish the rollback; it restores the databases from the backup if needed:',
239
+ run: installerCommandLine(['rollback', '--dir', layout.root], {
240
+ registry: state.registry,
241
+ }),
242
+ },
243
+ ...(kept
244
+ ? [
245
+ {
246
+ message: `Or return to ${to.id}, which was kept:`,
247
+ run: installerCommandLine([
248
+ 'rollback',
249
+ '--dir',
250
+ layout.root,
251
+ '--to',
252
+ to.id,
253
+ '--no-restore',
254
+ ], { registry: state.registry }),
255
+ },
256
+ ]
257
+ : []),
258
+ ],
259
+ });
260
+ }
261
+ export async function upgrade(input, deps) {
262
+ const { flags } = input;
263
+ const { reporter, pm2 } = deps;
264
+ const root = path.resolve(deps.cwd ?? process.cwd(), flags.dir ?? '.');
265
+ const layout = layoutOf(root);
266
+ const run = deps.run ?? runCommand;
267
+ const releaseLock = await acquireLock(layout.lockFile);
268
+ try {
269
+ // Read under the lock: a run that waited on it must see what the previous one wrote.
270
+ const state = await readState(layout);
271
+ assertNoPending(state, root);
272
+ const npmApp = state.source.kind === 'app' ? state.source : undefined;
273
+ if ((npmApp && flags.archive !== undefined) ||
274
+ (!npmApp && (flags.to !== undefined || flags.rebuild)) ||
275
+ (flags.to !== undefined && flags.rebuild)) {
276
+ throw new InstallerError('INVALID_USAGE', 'Use --archive for archive installations, or --to / --rebuild for npm applications; --to and --rebuild cannot be combined.', { exitCode: EXIT_INVALID });
277
+ }
278
+ const archive = npmApp
279
+ ? undefined
280
+ : resolveArchivePath(deps.cwd ?? process.cwd(), requireArchive(state, root, flags));
281
+ const env = await readAppEnv(layout);
282
+ const from = findRelease(state, state.current);
283
+ if (!from) {
284
+ throw new InstallerError('RELEASE_MISSING', `installer.json names ${state.current} as the running release but holds no record of it.`, { exitCode: EXIT_INVALID });
285
+ }
286
+ const machineMajor = currentNodeMajor();
287
+ const nodeChanged = from.buildTarget.nodeMajor !== machineMajor;
288
+ const noop = (warning) => {
289
+ if (warning)
290
+ reporter.warn(warning);
291
+ return {
292
+ status: 'success-noop',
293
+ result: {
294
+ directory: root,
295
+ current: from.id,
296
+ version: from.version,
297
+ upgraded: false,
298
+ nodeMatches: !nodeChanged,
299
+ },
300
+ summary: [
301
+ `The application is already on ${from.version} (${from.id}).`,
302
+ ...(warning ? [` ${warning}`] : []),
303
+ ],
304
+ };
305
+ };
306
+ const refuseDowngrade = (version) => {
307
+ throw new InstallerError('DOWNGRADE', `${version} is older than the running ${from.version}. An older release does not know the newer migrations and would run on a schema it does not understand.`, {
308
+ exitCode: EXIT_INVALID,
309
+ suggestions: [
310
+ {
311
+ message: 'Go back with rollback, which restores the databases backed up before the upgrade:',
312
+ run: installerCommandLine(['rollback', '--dir', root, '--to', version], { registry: state.registry }),
313
+ },
314
+ ],
315
+ });
316
+ };
317
+ const url = healthUrl(env);
318
+ const service = {
319
+ layout,
320
+ pm2,
321
+ name: state.name,
322
+ healthUrl: url,
323
+ fetchImpl: deps.fetchImpl,
324
+ };
325
+ checkPlatform();
326
+ await checkPm2(pm2);
327
+ await checkPm2Ownership(service);
328
+ // What to switch to: an archive has to be unpacked first, because only its manifest says which release it is.
329
+ const app = npmApp
330
+ ? await resolveApp({
331
+ package: npmApp.package,
332
+ selector: flags.rebuild ? from.version : (flags.to ?? 'latest'),
333
+ }, state.registry, run)
334
+ : undefined;
335
+ if (app) {
336
+ if ((compareVersions(app.selector, from.version) ?? 0) < 0)
337
+ refuseDowngrade(app.selector);
338
+ if (app.selector === from.version && !flags.rebuild && !nodeChanged)
339
+ return noop();
340
+ }
341
+ const unpacked = app
342
+ ? await buildApp({ app, registry: state.registry, layout, run, reporter })
343
+ : await unpackRelease({ layout, archive: archive });
344
+ const discard = async () => {
345
+ if (!unpacked.reused) {
346
+ await rm(path.dirname(unpacked.dir), {
347
+ recursive: true,
348
+ force: true,
349
+ });
350
+ }
351
+ };
352
+ try {
353
+ checkArchiveMatches(state, unpacked, env);
354
+ checkArchiveDriver(unpacked.dir, state.dialect);
355
+ if (unpacked.id === from.id) {
356
+ return noop();
357
+ }
358
+ if ((compareVersions(unpacked.version, from.version) ?? 0) < 0) {
359
+ refuseDowngrade(unpacked.version);
360
+ }
361
+ }
362
+ catch (error) {
363
+ await discard();
364
+ throw error;
365
+ }
366
+ const reuse = unpacked.reused ? findRelease(state, unpacked.id) : undefined;
367
+ const prepared = reuse ? undefined : unpacked;
368
+ const inventory = readDatabaseInventory(layout, env);
369
+ const unprotected = [...inventory.external, ...inventory.unresolved];
370
+ // Everything up to the stop happens while the current release keeps serving.
371
+ let to;
372
+ let newRecord;
373
+ if (reuse) {
374
+ reporter.progress(`Reusing the ${reuse.id} release already on disk`);
375
+ to = reuse;
376
+ }
377
+ else {
378
+ to = recordOf(prepared);
379
+ newRecord = to;
380
+ }
381
+ // A release built before relocatable builds runs only at the path it was built for.
382
+ const fixedMountPath = fixedMountPathOf(to, state);
383
+ if (fixedMountPath !== undefined) {
384
+ try {
385
+ assertFixedMountPath(to.id, fixedMountPath, mountPathOf(env));
386
+ }
387
+ catch (error) {
388
+ if (newRecord) {
389
+ await rm(path.dirname(releaseDir(layout, to.id)), {
390
+ recursive: true,
391
+ force: true,
392
+ });
393
+ }
394
+ throw error;
395
+ }
396
+ }
397
+ const dir = releaseDir(layout, to.id);
398
+ const removeNewRelease = async () => {
399
+ if (newRecord) {
400
+ await rm(path.dirname(dir), { recursive: true, force: true });
401
+ }
402
+ };
403
+ const cli = { releaseDir: dir, cwd: root, env, run };
404
+ let pending;
405
+ let repairPlan;
406
+ const repairIdentity = {
407
+ appName: state.appName,
408
+ from: from.id,
409
+ version: to.version,
410
+ };
411
+ try {
412
+ reporter.progress(`Checking the configuration and pending migrations with ${to.id}`);
413
+ await runAppCli(['config', 'check'], cli);
414
+ pending = pendingTaskCount(await runAppCli(['db', 'apply', '--dry-run'], cli));
415
+ repairPlan = await previewChecksumRepair(cli, repairIdentity);
416
+ requireChecksumApproval(repairPlan, flags['repair-checksums']);
417
+ if (unprotected.length > 0 && !flags['backup-done']) {
418
+ throw new InstallerError('BACKUP_REQUIRED', `app-installer cannot back up the database connection${unprotected.length === 1 ? '' : 's'} ${unprotected.join(', ')}. Back ${unprotected.length === 1 ? 'it' : 'them'} up, then pass --backup-done.`, { exitCode: EXIT_INVALID });
419
+ }
420
+ await confirm([
421
+ `Upgrade the application at ${root} from ${from.id} to ${to.id}.`,
422
+ 'The application stops while the release switches.',
423
+ `${pending} migration and seed task(s) will run; ${repairPlan.changes.length} checksum(s) will be repaired after backup.`,
424
+ inventory.sqlite.length > 0
425
+ ? 'The SQLite databases and the configuration are copied to backups/ before anything is migrated.'
426
+ : 'The configuration is copied to backups/ before anything is migrated.',
427
+ ...(unprotected.length > 0
428
+ ? [
429
+ `You confirmed with --backup-done that ${unprotected.join(', ')} ${unprotected.length === 1 ? 'is' : 'are'} backed up.`,
430
+ ]
431
+ : []),
432
+ ...(nodeChanged
433
+ ? [
434
+ `This machine runs Node ${machineMajor}, but ${from.id} was built for Node ${from.buildTarget.nodeMajor}: it cannot be rolled back to.`,
435
+ ]
436
+ : []),
437
+ ], { yes: flags.yes, json: flags.json });
438
+ }
439
+ catch (error) {
440
+ await removeNewRelease();
441
+ throw error;
442
+ }
443
+ reporter.progress(pending > 0
444
+ ? `${to.id} will apply ${pending} migration and seed task(s)`
445
+ : `${to.id} has no pending migrations`);
446
+ const name = backupName(from.id, to.id, new Date());
447
+ const backupRelative = path.join('backups', name);
448
+ state.pending = {
449
+ action: 'upgrade',
450
+ from: from.id,
451
+ to: to.id,
452
+ startedAt: new Date().toISOString(),
453
+ };
454
+ await writeState(layout, state);
455
+ // Downtime starts here.
456
+ reporter.progress(`Stopping ${from.id}`);
457
+ let backup;
458
+ try {
459
+ await stopApp(service);
460
+ // Health stopped answering; make sure nothing else holds the port the new release has to bind.
461
+ await checkPortFree(env.APP_SERVER_HOST ?? '127.0.0.1', Number(env.APP_SERVER_PORT ?? 13000));
462
+ reporter.progress('Backing up the databases and configuration');
463
+ backup = await backupForUpgrade(layout, name, inventory.sqlite);
464
+ const main = backup.databases.find((database) => database.connection === inventory.defaultConnection);
465
+ if (main && main.files.length === 0) {
466
+ throw new Error(`the SQLite database was not found at ${main.file}`);
467
+ }
468
+ // Recorded only now that it is complete: a recovery must never restore from a backup that was cut short.
469
+ state.pending.backup = backup.relative;
470
+ await writeState(layout, state);
471
+ }
472
+ catch (error) {
473
+ // Nothing was switched: bring the current release back and report the upgrade as not done.
474
+ await removeBackup(layout, backupRelative);
475
+ const healthy = await startApp({
476
+ ...service,
477
+ timeoutMs: flags['health-timeout'] * 1000,
478
+ }).catch(() => false);
479
+ delete state.pending;
480
+ await writeState(layout, state);
481
+ await removeNewRelease();
482
+ throw new InstallerError('UPGRADE_ABORTED', `Upgrading to ${to.id} stopped before switching: ${error instanceof Error ? error.message : String(error)}. ${healthy ? `${from.id} is running again.` : `${from.id} did not start again.`}`, {
483
+ exitCode: healthy ? EXIT_FAILED : EXIT_ROLLBACK_FAILED,
484
+ cause: error,
485
+ suggestions: healthy
486
+ ? []
487
+ : startAdvice(layout, `Start ${from.id} again once the cause is fixed:`),
488
+ });
489
+ }
490
+ try {
491
+ // Marked before the link moves, so an interruption from here on is undone with a database restore.
492
+ // Older installers cannot safely recover a repair-only upgrade; make them refuse this state.
493
+ if (repairPlan.changes.length > 0)
494
+ state.schemaVersion = 2;
495
+ state.pending.switched = true;
496
+ await writeState(layout, state);
497
+ await switchCurrent(layout, releaseLinkTarget(to.id));
498
+ // Recheck after stopping writers; an approval never covers newly discovered drift.
499
+ const finalPlan = await previewChecksumRepair(cli, repairIdentity);
500
+ if (finalPlan.token !== repairPlan.token) {
501
+ throw new InstallerError('CHECKSUM_PLAN_CHANGED', 'The checksum repair plan changed after preflight. Review the new plan before retrying.', { details: { checksumRepair: finalPlan } });
502
+ }
503
+ if (repairPlan.changes.length > 0) {
504
+ reporter.progress('Repairing the reviewed migration and seed checksums');
505
+ await runAppCli(['db', 'repair', '--force'], cli);
506
+ }
507
+ reporter.progress('Applying database migrations');
508
+ await runAppCli(['db', 'apply'], cli);
509
+ assertStorageOutsideRelease(dir);
510
+ reporter.progress(`Starting ${to.id}`);
511
+ const healthy = await startApp({
512
+ ...service,
513
+ timeoutMs: flags['health-timeout'] * 1000,
514
+ });
515
+ if (!healthy) {
516
+ throw new Error(`${url} did not become healthy (waited up to ${flags['health-timeout']}s)`);
517
+ }
518
+ }
519
+ catch (error) {
520
+ reporter.progress(`Rolling back to ${from.id}`);
521
+ // Awaited here rather than returned as a promise: the `finally` below awaits the lock before the caller can
522
+ // attach a handler, and a rollback that fails first would be reported as an unhandled rejection.
523
+ return await rollBackUpgrade({
524
+ layout,
525
+ state,
526
+ service,
527
+ from,
528
+ to,
529
+ pending,
530
+ checksumRepairs: repairPlan.changes.length,
531
+ externalConnections: unprotected,
532
+ backup,
533
+ newRecord,
534
+ timeoutMs: flags['health-timeout'] * 1000,
535
+ cause: error,
536
+ });
537
+ }
538
+ // The new release is serving: record that first, so nothing after this can make it look unfinished.
539
+ const at = new Date().toISOString();
540
+ state.current = to.id;
541
+ if (newRecord)
542
+ replaceRecord(state, newRecord);
543
+ // A release whose directory was removed by hand can never be returned to; forget it rather than prune around it.
544
+ state.releases = state.releases.filter((record) => existsSync(releaseDir(layout, record.id)));
545
+ delete state.pending;
546
+ state.history.push({
547
+ action: 'upgrade',
548
+ from: from.id,
549
+ to: to.id,
550
+ at,
551
+ outcome: 'completed',
552
+ migrations: pending,
553
+ checksumRepairs: repairPlan.changes.length,
554
+ backup: backup.relative,
555
+ });
556
+ await writeState(layout, state);
557
+ const pruned = releasesToPrune(state.releases, [to.id, from.id], flags.keep);
558
+ for (const record of pruned) {
559
+ await rm(path.dirname(releaseDir(layout, record.id)), {
560
+ recursive: true,
561
+ force: true,
562
+ });
563
+ }
564
+ if (pruned.length > 0) {
565
+ state.releases = state.releases.filter((record) => !pruned.some((gone) => gone.id === record.id));
566
+ await writeState(layout, state);
567
+ }
568
+ return {
569
+ status: 'success',
570
+ result: {
571
+ directory: root,
572
+ from: from.id,
573
+ to: to.id,
574
+ fromVersion: from.version,
575
+ toVersion: to.version,
576
+ upgraded: true,
577
+ reused: reuse !== undefined,
578
+ migrations: pending,
579
+ checksumRepairs: repairPlan.changes.length,
580
+ backup: backup.relative,
581
+ pruned: pruned.map((record) => record.id),
582
+ },
583
+ summary: [
584
+ `Upgraded the application from ${from.version} to ${to.version}.`,
585
+ ` Release ${to.id}`,
586
+ ` Migrations ${pending}`,
587
+ ` Backup ${backup.relative}`,
588
+ ...(pruned.length > 0
589
+ ? [` Pruned ${pruned.map((record) => record.id).join(', ')}`]
590
+ : []),
591
+ ],
592
+ };
593
+ }
594
+ finally {
595
+ await releaseLock();
596
+ }
597
+ }
598
+ //# sourceMappingURL=upgrade.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"upgrade.js","sourceRoot":"","sources":["../../src/commands/upgrade.ts"],"names":[],"mappings":"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"}