@caelo-cms/provisioning 0.1.1 → 0.2.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.
Files changed (65) hide show
  1. package/dist/cli.js +92 -7
  2. package/dist/cli.js.map +1 -1
  3. package/dist/compose.d.ts +7 -0
  4. package/dist/compose.d.ts.map +1 -1
  5. package/dist/compose.js +10 -9
  6. package/dist/compose.js.map +1 -1
  7. package/dist/dns/cloudflare.d.ts +9 -0
  8. package/dist/dns/cloudflare.d.ts.map +1 -0
  9. package/dist/dns/cloudflare.js +160 -0
  10. package/dist/dns/cloudflare.js.map +1 -0
  11. package/dist/dns/index.d.ts +12 -0
  12. package/dist/dns/index.d.ts.map +1 -0
  13. package/dist/dns/index.js +42 -0
  14. package/dist/dns/index.js.map +1 -0
  15. package/dist/dns/manual.d.ts +5 -0
  16. package/dist/dns/manual.d.ts.map +1 -0
  17. package/dist/dns/manual.js +96 -0
  18. package/dist/dns/manual.js.map +1 -0
  19. package/dist/dns/types.d.ts +23 -0
  20. package/dist/dns/types.d.ts.map +1 -0
  21. package/dist/dns/types.js +3 -0
  22. package/dist/dns/types.js.map +1 -0
  23. package/dist/gcloud.d.ts +42 -0
  24. package/dist/gcloud.d.ts.map +1 -0
  25. package/dist/gcloud.js +187 -0
  26. package/dist/gcloud.js.map +1 -0
  27. package/dist/install-state.d.ts +54 -0
  28. package/dist/install-state.d.ts.map +1 -0
  29. package/dist/install-state.js +118 -0
  30. package/dist/install-state.js.map +1 -0
  31. package/dist/lifecycle.d.ts +19 -0
  32. package/dist/lifecycle.d.ts.map +1 -0
  33. package/dist/lifecycle.js +589 -0
  34. package/dist/lifecycle.js.map +1 -0
  35. package/dist/migration-runner.d.ts +15 -0
  36. package/dist/migration-runner.d.ts.map +1 -0
  37. package/dist/migration-runner.js +174 -0
  38. package/dist/migration-runner.js.map +1 -0
  39. package/dist/redirects-emit.d.ts.map +1 -1
  40. package/dist/redirects-emit.js +4 -1
  41. package/dist/redirects-emit.js.map +1 -1
  42. package/dist/wizard.d.ts +35 -0
  43. package/dist/wizard.d.ts.map +1 -0
  44. package/dist/wizard.js +160 -0
  45. package/dist/wizard.js.map +1 -0
  46. package/dist/wizards/gcp-cost.d.ts +27 -0
  47. package/dist/wizards/gcp-cost.d.ts.map +1 -0
  48. package/dist/wizards/gcp-cost.js +77 -0
  49. package/dist/wizards/gcp-cost.js.map +1 -0
  50. package/dist/wizards/gcp-pulumi.d.ts +37 -0
  51. package/dist/wizards/gcp-pulumi.d.ts.map +1 -0
  52. package/dist/wizards/gcp-pulumi.js +100 -0
  53. package/dist/wizards/gcp-pulumi.js.map +1 -0
  54. package/dist/wizards/gcp.d.ts +9 -0
  55. package/dist/wizards/gcp.d.ts.map +1 -0
  56. package/dist/wizards/gcp.js +895 -0
  57. package/dist/wizards/gcp.js.map +1 -0
  58. package/package.json +13 -2
  59. package/stacks/aws/index.ts +6 -7
  60. package/stacks/azure/index.ts +11 -11
  61. package/stacks/gcp/Pulumi.production.yaml +16 -0
  62. package/stacks/gcp/Pulumi.yaml +52 -6
  63. package/stacks/gcp/index.ts +569 -188
  64. package/stacks/self-hosted/index.ts +3 -3
  65. package/static/welcome.html +155 -0
@@ -0,0 +1,589 @@
1
+ // SPDX-License-Identifier: MPL-2.0
2
+ /**
3
+ * Lifecycle commands per CLAUDE.md §11.C: every install gets a
4
+ * `caelo-cms` CLI binary with first-class `upgrade / backup / restore
5
+ * / rotate-secret / status / destroy` operations. These are the
6
+ * day-2 operations operators do regularly — they shouldn't drop
7
+ * into provider tools for any of them.
8
+ *
9
+ * Each command:
10
+ * - reads the install id from the active install (single install
11
+ * per machine for v1; multi-install via `--install-id` flag)
12
+ * - dispatches to provider-specific implementations (gcp / aws /
13
+ * azure / self-hosted)
14
+ * - emits human-readable progress + a final summary
15
+ */
16
+ import { existsSync, readdirSync } from "node:fs";
17
+ import { homedir } from "node:os";
18
+ import { cancel, confirm, isCancel, log, note, spinner } from "@clack/prompts";
19
+ import { bold, cyan, dim, green, red, yellow } from "kleur/colors";
20
+ import { gcloud } from "./gcloud.js";
21
+ import { installRoot, readMetadata, readSecret } from "./install-state.js";
22
+ /** Find the single install on this machine — or warn if 0/multiple. */
23
+ function findActiveInstall() {
24
+ const home = homedir();
25
+ if (!existsSync(home))
26
+ return null;
27
+ const candidates = readdirSync(home)
28
+ .filter((entry) => entry.startsWith(".caelo-"))
29
+ .map((entry) => entry.replace(/^\.caelo-/, ""));
30
+ for (const installId of candidates) {
31
+ const meta = readMetadata(installId);
32
+ if (meta)
33
+ return { installId, meta };
34
+ }
35
+ return null;
36
+ }
37
+ function requireInstall() {
38
+ const found = findActiveInstall();
39
+ if (!found) {
40
+ log.error(red("No Caelo install found on this machine."));
41
+ log.warn(`Run ${bold("bunx @caelo-cms/provisioning")} first to provision an install, OR copy ${dim("~/.caelo-<install-id>/")} from the provisioning machine.`);
42
+ process.exit(1);
43
+ }
44
+ return found;
45
+ }
46
+ /**
47
+ * Pulumi auto-naming appends a random 7-char suffix to every resource
48
+ * (e.g. `caelo-production-admin-3efcfea`). Lifecycle commands need the
49
+ * actual deployed names; this helper queries gcloud with a prefix
50
+ * filter and returns the single match (or null if missing/ambiguous).
51
+ *
52
+ * Used for Cloud Run services + Cloud SQL instances. We accept a
53
+ * `kind` for routing the gcloud subcommand (services vs sql instances).
54
+ */
55
+ async function resolveGcpResourceName(kind, prefix, projectId, region) {
56
+ const args = [];
57
+ if (kind === "run-service") {
58
+ args.push("run", "services", "list", "--region", region ?? "europe-west1", "--project", projectId, "--filter", `metadata.name~^${prefix}`, "--format=value(metadata.name)");
59
+ }
60
+ else {
61
+ args.push("sql", "instances", "list", "--project", projectId, "--filter", `name~^${prefix}`, "--format=value(name)");
62
+ }
63
+ const r = await gcloud(args);
64
+ if (!r.ok)
65
+ return null;
66
+ const matches = r.stdout
67
+ .trim()
68
+ .split("\n")
69
+ .map((s) => s.trim())
70
+ .filter((s) => s.length > 0);
71
+ return matches[0] ?? null;
72
+ }
73
+ // =========================================================================
74
+ // status — health check + monthly cost
75
+ // =========================================================================
76
+ export async function statusCommand() {
77
+ const { installId, meta } = requireInstall();
78
+ log.info(`Install: ${bold(installId)} ${dim(`(${meta.provider})`)}`);
79
+ log.info(`Domain: ${bold(meta.domain)}`);
80
+ log.info(`Project: ${bold(meta.projectId ?? "<self-hosted>")}`);
81
+ if (meta.provider === "gcp") {
82
+ await gcpStatus(meta);
83
+ }
84
+ else {
85
+ log.warn(`status command for provider ${meta.provider} not yet implemented.`);
86
+ }
87
+ }
88
+ /**
89
+ * P20 — fetch the latest stable Caelo release tag from GitHub.
90
+ * Returns null on any failure (network, rate limit, no releases yet)
91
+ * — status output skips the "newer available" line in that case.
92
+ * Caches in-process for 10 minutes to keep repeated `status` calls
93
+ * polite to GitHub's unauthenticated rate limit (60 req/hr).
94
+ */
95
+ let releaseCheckCache = null;
96
+ async function getLatestReleaseTag() {
97
+ const now = Date.now();
98
+ if (releaseCheckCache && now - releaseCheckCache.fetchedAt < 10 * 60 * 1000) {
99
+ return releaseCheckCache.latest;
100
+ }
101
+ try {
102
+ const res = await fetch("https://api.github.com/repos/caelo-cms/caelo-cms/releases/latest", {
103
+ headers: { Accept: "application/vnd.github+json" },
104
+ });
105
+ if (!res.ok) {
106
+ releaseCheckCache = { fetchedAt: now, latest: null };
107
+ return null;
108
+ }
109
+ const json = (await res.json());
110
+ const latest = json.tag_name ?? null;
111
+ releaseCheckCache = { fetchedAt: now, latest };
112
+ return latest;
113
+ }
114
+ catch {
115
+ releaseCheckCache = { fetchedAt: now, latest: null };
116
+ return null;
117
+ }
118
+ }
119
+ async function gcpStatus(meta) {
120
+ if (!meta.projectId)
121
+ return;
122
+ const s = spinner();
123
+ s.start("Resolving deployed resources + checking health...");
124
+ const region = meta.region ?? "europe-west1";
125
+ const adminName = await resolveGcpResourceName("run-service", "caelo-production-admin", meta.projectId, region);
126
+ const sqlName = await resolveGcpResourceName("sql-instance", "caelo-production-pg", meta.projectId);
127
+ if (!adminName || !sqlName) {
128
+ s.stop(red("Could not resolve deployed resource names — is the install live?"));
129
+ return;
130
+ }
131
+ const adminUri = await gcloud([
132
+ "run",
133
+ "services",
134
+ "describe",
135
+ adminName,
136
+ "--region",
137
+ region,
138
+ "--project",
139
+ meta.projectId,
140
+ "--format=value(status.url)",
141
+ ]);
142
+ const sqlState = await gcloud([
143
+ "sql",
144
+ "instances",
145
+ "describe",
146
+ sqlName,
147
+ "--project",
148
+ meta.projectId,
149
+ "--format=value(state)",
150
+ ]);
151
+ s.stop(green("Health check complete"));
152
+ // P20 — show running version vs latest available release. Pulled
153
+ // from the running admin's CAELO_VERSION env when set; falls back
154
+ // to the @caelo-cms/shared bundled version of the local CLI.
155
+ const { CAELO_VERSION } = await import("@caelo-cms/shared");
156
+ const latestTag = await getLatestReleaseTag();
157
+ const latestStable = latestTag?.replace(/^v/, "") ?? null;
158
+ const upgradeHint = latestStable && latestStable !== CAELO_VERSION
159
+ ? `${yellow(`v${latestStable} available`)} — run \`bunx @caelo-cms/provisioning upgrade\``
160
+ : latestStable === CAELO_VERSION
161
+ ? green("up to date")
162
+ : dim("(latest unknown)");
163
+ note([
164
+ `${dim("Admin Cloud Run URL")} ${adminUri.ok ? bold(adminUri.stdout.trim()) : red("error")}`,
165
+ `${dim("Cloud SQL state")} ${sqlState.ok ? bold(sqlState.stdout.trim()) : red("error")}`,
166
+ `${dim("Public site")} ${cyan(`https://${meta.domain}`)}`,
167
+ `${dim("Admin (IAP-gated)")} ${cyan(`https://admin.${meta.domain}`)}`,
168
+ `${dim("CLI version")} v${CAELO_VERSION} ${upgradeHint}`,
169
+ ].join("\n"), "Status");
170
+ }
171
+ /** Look up the currently-serving Cloud Run revision so we can roll back to it. */
172
+ async function findCurrentRevision(projectId, region, serviceName) {
173
+ const r = await gcloud([
174
+ "run",
175
+ "services",
176
+ "describe",
177
+ serviceName,
178
+ "--region",
179
+ region,
180
+ "--project",
181
+ projectId,
182
+ "--format=value(status.traffic[0].revisionName)",
183
+ ]);
184
+ if (!r.ok)
185
+ return null;
186
+ const rev = r.stdout.trim().split("\n")[0]?.trim();
187
+ return rev || null;
188
+ }
189
+ /** Cloud Run service URL, used as the health-probe target after a roll. */
190
+ async function findServiceUrl(projectId, region, serviceName) {
191
+ const r = await gcloud([
192
+ "run",
193
+ "services",
194
+ "describe",
195
+ serviceName,
196
+ "--region",
197
+ region,
198
+ "--project",
199
+ projectId,
200
+ "--format=value(status.url)",
201
+ ]);
202
+ if (!r.ok)
203
+ return null;
204
+ return r.stdout.trim() || null;
205
+ }
206
+ /**
207
+ * Poll the health endpoint until it returns 200 (ok) or the deadline
208
+ * expires (unhealthy). Cold starts on Cloud Run can take 10–30s, so
209
+ * we give 60s before declaring failure.
210
+ */
211
+ async function probeHealthy(url, deadlineMs) {
212
+ const deadline = Date.now() + deadlineMs;
213
+ while (Date.now() < deadline) {
214
+ try {
215
+ const ctrl = new AbortController();
216
+ const t = setTimeout(() => ctrl.abort(), 5_000);
217
+ const res = await fetch(url, { signal: ctrl.signal });
218
+ clearTimeout(t);
219
+ if (res.ok) {
220
+ const body = (await res.json().catch(() => null));
221
+ if (body?.ok === true)
222
+ return true;
223
+ }
224
+ }
225
+ catch {
226
+ // network blip / cold start in progress — retry.
227
+ }
228
+ await new Promise((r) => setTimeout(r, 2_000));
229
+ }
230
+ return false;
231
+ }
232
+ async function rollbackTraffic(projectId, region, serviceName, priorRevision) {
233
+ const r = await gcloud([
234
+ "run",
235
+ "services",
236
+ "update-traffic",
237
+ serviceName,
238
+ "--region",
239
+ region,
240
+ "--project",
241
+ projectId,
242
+ "--to-revisions",
243
+ `${priorRevision}=100`,
244
+ "--quiet",
245
+ ]);
246
+ return r.ok;
247
+ }
248
+ export async function upgradeCommand(opts = {}) {
249
+ const { meta } = requireInstall();
250
+ if (meta.provider !== "gcp") {
251
+ log.warn(`upgrade for provider ${meta.provider} not yet implemented.`);
252
+ return;
253
+ }
254
+ if (!meta.projectId)
255
+ return;
256
+ const region = meta.region ?? "europe-west1";
257
+ const registryProject = "caelo-website";
258
+ const registryRegion = "europe-west1";
259
+ const registryRepo = "caelo-cms-images";
260
+ const targetTag = (() => {
261
+ if (opts.version)
262
+ return opts.version.startsWith("v") ? opts.version.slice(1) : opts.version;
263
+ if (opts.channel === "rc")
264
+ return "rc";
265
+ if (opts.channel === "beta")
266
+ return "beta";
267
+ return "latest";
268
+ })();
269
+ log.info(`Upgrading admin + gateway to ${bold(targetTag)}`);
270
+ // ────────────────────────────────────────────────────────────────
271
+ // Phase 1: pre-flight. Resolve both digests + capture both prior
272
+ // revisions BEFORE rolling anything. If any service is missing or
273
+ // any digest can't be resolved, abort cleanly with no partial state.
274
+ // ────────────────────────────────────────────────────────────────
275
+ const plans = [];
276
+ const sPre = spinner();
277
+ sPre.start("Pre-flight: resolving services + image digests + current revisions...");
278
+ for (const slug of ["admin", "gateway"]) {
279
+ const serviceName = await resolveGcpResourceName("run-service", `caelo-production-${slug}`, meta.projectId, region);
280
+ if (!serviceName) {
281
+ sPre.stop(red(`Could not find caelo-production-${slug}* Cloud Run service`));
282
+ return;
283
+ }
284
+ const tagInfo = await gcloud([
285
+ "artifacts",
286
+ "docker",
287
+ "tags",
288
+ "list",
289
+ `${registryRegion}-docker.pkg.dev/${registryProject}/${registryRepo}/${slug}`,
290
+ "--filter",
291
+ `tag=${targetTag}`,
292
+ "--format=value(version)",
293
+ "--project",
294
+ registryProject,
295
+ ]);
296
+ if (!tagInfo.ok || !tagInfo.stdout.trim()) {
297
+ sPre.stop(red(`Couldn't resolve image digest for ${slug}:${targetTag}`));
298
+ log.error(`Verify the tag exists at ${registryRegion}-docker.pkg.dev/${registryProject}/${registryRepo}/${slug}:${targetTag}`);
299
+ return;
300
+ }
301
+ const digest = tagInfo.stdout.trim().split("\n")[0]?.trim() ?? "";
302
+ const priorRevision = await findCurrentRevision(meta.projectId, region, serviceName);
303
+ if (!priorRevision) {
304
+ sPre.stop(red(`Could not capture current revision for ${slug} — refusing to roll`));
305
+ return;
306
+ }
307
+ plans.push({
308
+ slug,
309
+ serviceName,
310
+ digest,
311
+ imageRef: `${registryRegion}-docker.pkg.dev/${registryProject}/${registryRepo}/${slug}@${digest}`,
312
+ priorRevision,
313
+ // Admin's health endpoint is shipped at /_caelo/health (P21);
314
+ // gateway's is /healthz (existed since P0).
315
+ healthPath: slug === "admin" ? "/_caelo/health" : "/healthz",
316
+ });
317
+ }
318
+ sPre.stop(green(`Pre-flight ok — ${plans.length} services planned`));
319
+ // ────────────────────────────────────────────────────────────────
320
+ // P21 ship 4 — cosign verify each resolved digest against the
321
+ // Caelo release workflow's keyless OIDC identity. Refuses to roll
322
+ // on signature mismatch (compromised registry, typosquatted repo,
323
+ // or operator pointed at a fork's image).
324
+ //
325
+ // Verification is opt-out via --skip-verify for forks/staging that
326
+ // intentionally use unsigned images. Cosign-not-installed produces
327
+ // a clear "install cosign or pass --skip-verify" message rather
328
+ // than a confusing stack.
329
+ // ────────────────────────────────────────────────────────────────
330
+ if (!opts.skipVerify) {
331
+ const verified = await verifyCosignAll(plans, registryRegion, registryProject, registryRepo);
332
+ if (!verified)
333
+ return;
334
+ }
335
+ else {
336
+ log.warn(yellow("--skip-verify set — image signatures NOT verified."));
337
+ }
338
+ // ────────────────────────────────────────────────────────────────
339
+ // P21 ship 3 — DB migrations BEFORE traffic shifts. Idempotent
340
+ // (drizzle bookkeeping table); a failure here aborts the upgrade
341
+ // before the new image touches traffic, so the admin keeps
342
+ // serving the old version against the existing schema.
343
+ // ────────────────────────────────────────────────────────────────
344
+ const sMig = spinner();
345
+ sMig.start("Applying DB migrations (idempotent)...");
346
+ const { runMigrationsViaCloudRunJob } = await import("./migration-runner.js");
347
+ const mig = await runMigrationsViaCloudRunJob({ projectId: meta.projectId, region });
348
+ if (!mig.ok) {
349
+ sMig.stop(red(`Migrations failed (${mig.error ?? "unknown"}). Aborting upgrade.`));
350
+ log.warn("No traffic was shifted. Inspect the Cloud Run Job logs:\n" +
351
+ " gcloud logging read 'resource.type=cloud_run_job AND " +
352
+ 'resource.labels.job_name=~"caelo-migrate-.*"\' ' +
353
+ `--project=${meta.projectId} --limit=50`);
354
+ return;
355
+ }
356
+ sMig.stop(green("Migrations applied"));
357
+ // ────────────────────────────────────────────────────────────────
358
+ // Phase 2: roll each service, probe health, auto-rollback on fail.
359
+ // If admin succeeds but gateway fails, also roll admin back so the
360
+ // operator never ends up on a mismatched-version pair.
361
+ // ────────────────────────────────────────────────────────────────
362
+ const rolled = [];
363
+ for (const plan of plans) {
364
+ const s = spinner();
365
+ s.start(`Rolling ${plan.slug} → ${plan.digest.slice(0, 19)}...`);
366
+ const upd = await gcloud([
367
+ "run",
368
+ "services",
369
+ "update",
370
+ plan.serviceName,
371
+ "--region",
372
+ region,
373
+ "--project",
374
+ meta.projectId,
375
+ "--image",
376
+ plan.imageRef,
377
+ "--quiet",
378
+ ]);
379
+ if (!upd.ok) {
380
+ s.stop(red(`Failed: ${upd.stderr.trim()}`));
381
+ await rollbackPriorlyRolled(meta.projectId, region, rolled);
382
+ return;
383
+ }
384
+ const url = await findServiceUrl(meta.projectId, region, plan.serviceName);
385
+ if (!url) {
386
+ s.stop(red(`Could not resolve service URL for ${plan.slug} — rolling back`));
387
+ await rollbackTraffic(meta.projectId, region, plan.serviceName, plan.priorRevision);
388
+ await rollbackPriorlyRolled(meta.projectId, region, rolled);
389
+ return;
390
+ }
391
+ s.stop(green(`${plan.slug} rolled — probing ${url}${plan.healthPath} for 60s...`));
392
+ const sProbe = spinner();
393
+ sProbe.start(`Health-probing ${plan.slug}...`);
394
+ const healthy = await probeHealthy(`${url}${plan.healthPath}`, 60_000);
395
+ if (!healthy) {
396
+ sProbe.stop(red(`${plan.slug} unhealthy after roll — auto-rolling back`));
397
+ const rb = await rollbackTraffic(meta.projectId, region, plan.serviceName, plan.priorRevision);
398
+ if (!rb) {
399
+ log.error(red(`Rollback of ${plan.slug} FAILED — manually shift traffic back: ` +
400
+ `gcloud run services update-traffic ${plan.serviceName} ` +
401
+ `--to-revisions=${plan.priorRevision}=100 ` +
402
+ `--region=${region} --project=${meta.projectId}`));
403
+ }
404
+ await rollbackPriorlyRolled(meta.projectId, region, rolled);
405
+ return;
406
+ }
407
+ sProbe.stop(green(`${plan.slug} healthy ✓`));
408
+ rolled.push(plan);
409
+ }
410
+ log.success(`Upgrade to ${bold(targetTag)} complete (admin + gateway both healthy).`);
411
+ }
412
+ /**
413
+ * Roll back any services that already passed their probe in this
414
+ * upgrade run. Called when a later service fails its probe so the
415
+ * operator never ends up on an admin-new + gateway-old (or vice versa)
416
+ * mismatched pair.
417
+ */
418
+ /**
419
+ * P21 ship 4 — verify cosign keyless signatures on every planned
420
+ * image digest. Sigstore Fulcio + Rekor; the certificate identity
421
+ * must match the Caelo release-images workflow. A mismatch means
422
+ * either a registry compromise, a typosquat, or the operator pointed
423
+ * at a fork's image. Either way: refuse to roll.
424
+ *
425
+ * Returns true on success (or skips with a clear error and returns
426
+ * false if cosign isn't installed / verification fails).
427
+ */
428
+ async function verifyCosignAll(plans, registryRegion, registryProject, registryRepo) {
429
+ // First check cosign is on PATH. The Bun.spawnSync API surfaces
430
+ // ENOENT as a non-zero exit; we surface the actionable hint
431
+ // separately from a real verify failure.
432
+ const cosignProbe = Bun.spawnSync(["cosign", "version"], {
433
+ stdout: "pipe",
434
+ stderr: "pipe",
435
+ });
436
+ if (cosignProbe.exitCode !== 0) {
437
+ log.error(red("cosign not found on PATH — required for image-signature verification."));
438
+ log.warn("Install cosign:\n" +
439
+ " • brew install cosign (macOS)\n" +
440
+ " • https://docs.sigstore.dev/cosign/installation/ (other)\n" +
441
+ "Or pass --skip-verify to roll without signature checks (NOT recommended for production).");
442
+ return false;
443
+ }
444
+ for (const plan of plans) {
445
+ const s = spinner();
446
+ s.start(`Verifying cosign signature for ${plan.slug}@${plan.digest.slice(0, 19)}...`);
447
+ const fullRef = `${registryRegion}-docker.pkg.dev/${registryProject}/${registryRepo}/${plan.slug}@${plan.digest}`;
448
+ const verify = Bun.spawnSync([
449
+ "cosign",
450
+ "verify",
451
+ fullRef,
452
+ "--certificate-identity-regexp",
453
+ // Both release-images.yml and release.yml dispatch images;
454
+ // accept either workflow as the signer identity. The repo
455
+ // path is fixed; only the workflow filename varies.
456
+ "https://github.com/caelo-cms/caelo-cms/.github/workflows/(release-images|release).yml@.*",
457
+ "--certificate-oidc-issuer",
458
+ "https://token.actions.githubusercontent.com",
459
+ ], { stdout: "pipe", stderr: "pipe" });
460
+ if (verify.exitCode !== 0) {
461
+ const stderr = new TextDecoder().decode(verify.stderr);
462
+ s.stop(red(`cosign verify FAILED for ${plan.slug}`));
463
+ log.error(red(`${plan.slug}@${plan.digest.slice(0, 19)} signature does NOT match the Caelo release workflow identity.\n` +
464
+ "Either:\n" +
465
+ " • the registry was compromised, OR\n" +
466
+ " • you're targeting a fork's image (verify your install's registry path), OR\n" +
467
+ " • cosign / sigstore had a transient outage (retry).\n" +
468
+ `cosign stderr: ${stderr.trim().slice(0, 500)}`));
469
+ return false;
470
+ }
471
+ s.stop(green(`${plan.slug} signature verified ✓`));
472
+ }
473
+ return true;
474
+ }
475
+ async function rollbackPriorlyRolled(projectId, region, rolled) {
476
+ if (rolled.length === 0)
477
+ return;
478
+ log.warn(yellow(`Rolling back ${rolled.length} service(s) that succeeded earlier in this run...`));
479
+ for (const plan of rolled) {
480
+ const ok = await rollbackTraffic(projectId, region, plan.serviceName, plan.priorRevision);
481
+ log.info(ok
482
+ ? green(` ${plan.slug} traffic restored to ${plan.priorRevision}`)
483
+ : red(` ${plan.slug} rollback FAILED — manual fix required`));
484
+ }
485
+ }
486
+ // =========================================================================
487
+ // backup — Cloud SQL on-demand backup + bundle Pulumi state
488
+ // =========================================================================
489
+ export async function backupCommand() {
490
+ const { meta } = requireInstall();
491
+ if (meta.provider !== "gcp") {
492
+ log.warn(`backup for provider ${meta.provider} not yet implemented.`);
493
+ return;
494
+ }
495
+ if (!meta.projectId)
496
+ return;
497
+ const s = spinner();
498
+ s.start("Resolving Cloud SQL instance + triggering on-demand backup...");
499
+ const sqlName = await resolveGcpResourceName("sql-instance", "caelo-production-pg", meta.projectId);
500
+ if (!sqlName) {
501
+ s.stop(red("Could not find caelo-production-pg* Cloud SQL instance"));
502
+ return;
503
+ }
504
+ const r = await gcloud([
505
+ "sql",
506
+ "backups",
507
+ "create",
508
+ "--instance",
509
+ sqlName,
510
+ "--project",
511
+ meta.projectId,
512
+ "--description",
513
+ `caelo-cms backup ${new Date().toISOString()}`,
514
+ ]);
515
+ if (!r.ok) {
516
+ s.stop(red(`Failed: ${r.stderr.trim()}`));
517
+ return;
518
+ }
519
+ s.stop(green(`Backup created. List with \`gcloud sql backups list --instance=${sqlName}\`.`));
520
+ }
521
+ // =========================================================================
522
+ // rotate-secret <name>
523
+ // =========================================================================
524
+ export async function rotateSecretCommand(name) {
525
+ if (!name) {
526
+ log.error(red("Usage: caelo-cms rotate-secret <name>"));
527
+ log.warn(`Names: ${[
528
+ "postgres-password",
529
+ "csrf-secret",
530
+ "cookie-secret",
531
+ "secret-kek",
532
+ "anthropic-api-key",
533
+ "resend-api-key",
534
+ ].join(", ")}`);
535
+ process.exit(2);
536
+ }
537
+ const { meta } = requireInstall();
538
+ if (meta.provider !== "gcp") {
539
+ log.warn(`rotate-secret for provider ${meta.provider} not yet implemented.`);
540
+ return;
541
+ }
542
+ log.warn(yellow(`Secret rotation v1 prints the gcloud command for you to run. Full automation lands in a follow-up.`));
543
+ note([
544
+ bold("Run this from your terminal:"),
545
+ "",
546
+ ` ${cyan(`echo -n "<new-value>" | gcloud secrets versions add caelo-production-${name} --data-file=- --project=${meta.projectId}`)}`,
547
+ "",
548
+ `Then redeploy admin + gateway to pick up the new value:`,
549
+ ` ${cyan(`bunx @caelo-cms/provisioning upgrade`)}`,
550
+ ].join("\n"), "Rotate secret");
551
+ }
552
+ // =========================================================================
553
+ // destroy — pulumi destroy + gcloud projects delete
554
+ // =========================================================================
555
+ export async function destroyCommand() {
556
+ const { installId, meta } = requireInstall();
557
+ log.warn(red(`${bold("Destroy will PERMANENTLY delete")} the GCP project + every Caelo resource. This is irreversible after the 30-day undelete window.`));
558
+ const confirm1 = await confirm({
559
+ message: `Destroy the install for ${bold(meta.domain)} (${bold(meta.projectId ?? "self-hosted")})?`,
560
+ initialValue: false,
561
+ });
562
+ if (isCancel(confirm1) || !confirm1) {
563
+ cancel("Cancelled.");
564
+ process.exit(0);
565
+ }
566
+ const typed = await import("@clack/prompts").then((m) => m.text({
567
+ message: `Type the domain to confirm: ${bold(meta.domain)}`,
568
+ validate: (v) => (v === meta.domain ? undefined : "Domain doesn't match — aborting"),
569
+ }));
570
+ if (isCancel(typed)) {
571
+ cancel("Cancelled.");
572
+ process.exit(0);
573
+ }
574
+ if (meta.provider === "gcp" && meta.projectId) {
575
+ const s = spinner();
576
+ s.start(`Deleting GCP project ${meta.projectId}...`);
577
+ const r = await gcloud(["projects", "delete", meta.projectId, "--quiet"]);
578
+ if (!r.ok) {
579
+ s.stop(red(`Failed: ${r.stderr.trim()}`));
580
+ log.warn(`You can delete the project manually via the Cloud Console: https://console.cloud.google.com/iam-admin/settings?project=${meta.projectId}`);
581
+ }
582
+ else {
583
+ s.stop(green(`Project ${meta.projectId} marked for deletion (30-day undelete window).`));
584
+ }
585
+ }
586
+ log.info(`Local state at ${dim(installRoot(installId))} preserved. Remove manually if you want a clean slate: ${bold(`rm -rf ${installRoot(installId)}`)}.`);
587
+ void readSecret; // unused-import guard
588
+ }
589
+ //# sourceMappingURL=lifecycle.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lifecycle.js","sourceRoot":"","sources":["../src/lifecycle.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,15 @@
1
+ interface MigrationRunnerOpts {
2
+ readonly projectId: string;
3
+ readonly region: string;
4
+ }
5
+ /**
6
+ * Run admin + public migrations against Cloud SQL. Returns `{ok}` so
7
+ * callers can decide what to do on failure (the wizard exits the
8
+ * process; upgrade aborts before rolling Cloud Run).
9
+ */
10
+ export declare function runMigrationsViaCloudRunJob(opts: MigrationRunnerOpts): Promise<{
11
+ ok: boolean;
12
+ error?: string;
13
+ }>;
14
+ export {};
15
+ //# sourceMappingURL=migration-runner.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"migration-runner.d.ts","sourceRoot":"","sources":["../src/migration-runner.ts"],"names":[],"mappings":"AAuBA,UAAU,mBAAmB;IAC3B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACzB;AA2FD;;;;GAIG;AACH,wBAAsB,2BAA2B,CAC/C,IAAI,EAAE,mBAAmB,GACxB,OAAO,CAAC;IAAE,EAAE,EAAE,OAAO,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,CAyE1C"}