@caelo-cms/provisioning 0.11.10 → 0.11.11

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 (212) hide show
  1. package/dist/adapter.d.ts +6 -0
  2. package/dist/adapter.d.ts.map +1 -1
  3. package/dist/adopt-existing.d.ts +6 -2
  4. package/dist/adopt-existing.d.ts.map +1 -1
  5. package/dist/adopt-existing.js +57 -0
  6. package/dist/adopt-existing.js.map +1 -1
  7. package/dist/agent/command.d.ts +5 -2
  8. package/dist/agent/command.d.ts.map +1 -1
  9. package/dist/agent/command.js +1 -1
  10. package/dist/agent/command.js.map +1 -1
  11. package/dist/agent-db.js +25 -8
  12. package/dist/cli-routing.js +1 -1
  13. package/dist/cli-routing.js.map +1 -1
  14. package/dist/cli.js +59 -7
  15. package/dist/cli.js.map +1 -1
  16. package/dist/cloudsql-tls.d.ts +30 -0
  17. package/dist/cloudsql-tls.d.ts.map +1 -1
  18. package/dist/cloudsql-tls.js +7 -1
  19. package/dist/cloudsql-tls.js.map +1 -1
  20. package/dist/compose.d.ts +14 -0
  21. package/dist/compose.d.ts.map +1 -1
  22. package/dist/compose.js +54 -1
  23. package/dist/compose.js.map +1 -1
  24. package/dist/converge-db-trust.d.ts +44 -0
  25. package/dist/converge-db-trust.d.ts.map +1 -0
  26. package/dist/converge-db-trust.js +158 -0
  27. package/dist/converge-db-trust.js.map +1 -0
  28. package/dist/converge-job-gcp.d.ts +5 -2
  29. package/dist/converge-job-gcp.d.ts.map +1 -1
  30. package/dist/converge-job-gcp.js +9 -2
  31. package/dist/converge-job-gcp.js.map +1 -1
  32. package/dist/converge-job-preflight.d.ts.map +1 -1
  33. package/dist/converge-job-preflight.js +8 -0
  34. package/dist/converge-job-preflight.js.map +1 -1
  35. package/dist/converge-job.d.ts +17 -0
  36. package/dist/converge-job.d.ts.map +1 -1
  37. package/dist/converge-job.js +12 -0
  38. package/dist/converge-job.js.map +1 -1
  39. package/dist/gcp-names.d.ts +13 -0
  40. package/dist/gcp-names.d.ts.map +1 -1
  41. package/dist/gcp-names.js +21 -0
  42. package/dist/gcp-names.js.map +1 -1
  43. package/dist/index.d.ts +2 -1
  44. package/dist/index.d.ts.map +1 -1
  45. package/dist/index.js +1 -0
  46. package/dist/index.js.map +1 -1
  47. package/dist/infra-contract.d.ts +1 -1
  48. package/dist/infra-contract.d.ts.map +1 -1
  49. package/dist/infra-contract.js +22 -1
  50. package/dist/infra-contract.js.map +1 -1
  51. package/dist/install-job.d.ts +4 -2
  52. package/dist/install-job.d.ts.map +1 -1
  53. package/dist/install-job.js +4 -1
  54. package/dist/install-job.js.map +1 -1
  55. package/dist/install-state.d.ts +7 -0
  56. package/dist/install-state.d.ts.map +1 -1
  57. package/dist/install-state.js.map +1 -1
  58. package/dist/lifecycle.d.ts.map +1 -1
  59. package/dist/lifecycle.js +3 -0
  60. package/dist/lifecycle.js.map +1 -1
  61. package/dist/migration-runner.d.ts.map +1 -1
  62. package/dist/migration-runner.js +8 -3
  63. package/dist/migration-runner.js.map +1 -1
  64. package/dist/migration-targets.d.ts +11 -0
  65. package/dist/migration-targets.d.ts.map +1 -0
  66. package/dist/migration-targets.js +12 -0
  67. package/dist/migration-targets.js.map +1 -0
  68. package/dist/operator-access.d.ts +10 -0
  69. package/dist/operator-access.d.ts.map +1 -1
  70. package/dist/operator-access.js +5 -0
  71. package/dist/operator-access.js.map +1 -1
  72. package/dist/pool-budget-stack.d.ts +13 -1
  73. package/dist/pool-budget-stack.d.ts.map +1 -1
  74. package/dist/pool-budget-stack.js +11 -1
  75. package/dist/pool-budget-stack.js.map +1 -1
  76. package/dist/public-role-isolation.d.ts +7 -3
  77. package/dist/public-role-isolation.d.ts.map +1 -1
  78. package/dist/public-role-isolation.js +25 -13
  79. package/dist/public-role-isolation.js.map +1 -1
  80. package/dist/release-contract.d.ts.map +1 -1
  81. package/dist/release-contract.js +3 -0
  82. package/dist/release-contract.js.map +1 -1
  83. package/dist/runtime-secrets.d.ts +2 -0
  84. package/dist/runtime-secrets.d.ts.map +1 -1
  85. package/dist/runtime-secrets.js +19 -15
  86. package/dist/runtime-secrets.js.map +1 -1
  87. package/dist/scheduler-setup.d.ts +75 -0
  88. package/dist/scheduler-setup.d.ts.map +1 -0
  89. package/dist/scheduler-setup.js +331 -0
  90. package/dist/scheduler-setup.js.map +1 -0
  91. package/dist/self-hosted-roles.d.ts +16 -9
  92. package/dist/self-hosted-roles.d.ts.map +1 -1
  93. package/dist/self-hosted-roles.js +49 -15
  94. package/dist/self-hosted-roles.js.map +1 -1
  95. package/dist/self-hosted-scheduler-interval.d.ts +21 -0
  96. package/dist/self-hosted-scheduler-interval.d.ts.map +1 -0
  97. package/dist/self-hosted-scheduler-interval.js +68 -0
  98. package/dist/self-hosted-scheduler-interval.js.map +1 -0
  99. package/dist/self-hosted-upgrade.d.ts +7 -4
  100. package/dist/self-hosted-upgrade.d.ts.map +1 -1
  101. package/dist/self-hosted-upgrade.js +9 -5
  102. package/dist/self-hosted-upgrade.js.map +1 -1
  103. package/dist/stack-contract.d.ts +67 -6
  104. package/dist/stack-contract.d.ts.map +1 -1
  105. package/dist/stack-contract.js +87 -6
  106. package/dist/stack-contract.js.map +1 -1
  107. package/dist/staging-database.d.ts +22 -0
  108. package/dist/staging-database.d.ts.map +1 -0
  109. package/dist/staging-database.js +117 -0
  110. package/dist/staging-database.js.map +1 -0
  111. package/dist/upgrade/converge.d.ts +5 -0
  112. package/dist/upgrade/converge.d.ts.map +1 -1
  113. package/dist/upgrade/converge.js +110 -10
  114. package/dist/upgrade/converge.js.map +1 -1
  115. package/dist/upgrade/upgrade.d.ts +6 -0
  116. package/dist/upgrade/upgrade.d.ts.map +1 -1
  117. package/dist/upgrade/upgrade.js +3 -0
  118. package/dist/upgrade/upgrade.js.map +1 -1
  119. package/dist/upgrader-gcp.d.ts +5 -4
  120. package/dist/upgrader-gcp.d.ts.map +1 -1
  121. package/dist/upgrader-gcp.js +5 -4
  122. package/dist/upgrader-gcp.js.map +1 -1
  123. package/dist/wizard.d.ts +7 -0
  124. package/dist/wizard.d.ts.map +1 -1
  125. package/dist/wizard.js +11 -0
  126. package/dist/wizard.js.map +1 -1
  127. package/dist/wizards/gcp-cost.d.ts +31 -0
  128. package/dist/wizards/gcp-cost.d.ts.map +1 -1
  129. package/dist/wizards/gcp-cost.js +81 -11
  130. package/dist/wizards/gcp-cost.js.map +1 -1
  131. package/dist/wizards/gcp.d.ts.map +1 -1
  132. package/dist/wizards/gcp.js +87 -11
  133. package/dist/wizards/gcp.js.map +1 -1
  134. package/package.json +2 -2
  135. package/src/adapter.ts +6 -0
  136. package/src/admin-memory.test.ts +1 -1
  137. package/src/adopt-existing.test.ts +46 -0
  138. package/src/adopt-existing.ts +58 -2
  139. package/src/agent/command.ts +6 -3
  140. package/src/caddy-redirects.test.ts +1 -1
  141. package/src/cli-routing.test.ts +1 -1
  142. package/src/cli-routing.ts +1 -1
  143. package/src/cli.ts +63 -8
  144. package/src/cloudsql-tls.test.ts +30 -0
  145. package/src/cloudsql-tls.ts +10 -3
  146. package/src/compose.ts +68 -0
  147. package/src/converge-db-trust.test.ts +237 -0
  148. package/src/converge-db-trust.ts +212 -0
  149. package/src/converge-job-gcp.ts +9 -1
  150. package/src/converge-job-preflight.test.ts +5 -0
  151. package/src/converge-job-preflight.ts +8 -0
  152. package/src/converge-job.test.ts +70 -0
  153. package/src/converge-job.ts +32 -0
  154. package/src/database-tls-builders.test.ts +3 -2
  155. package/src/deployed-release.test.ts +3 -0
  156. package/src/gateway-env-isolation.test.ts +40 -7
  157. package/src/gcp-names.ts +25 -0
  158. package/src/index.test.ts +3 -3
  159. package/src/index.ts +6 -0
  160. package/src/infra-contract.test.ts +5 -3
  161. package/src/infra-contract.ts +22 -1
  162. package/src/install-job.ts +4 -1
  163. package/src/install-state.ts +7 -0
  164. package/src/lifecycle.ts +3 -0
  165. package/src/migration-runner.ts +14 -9
  166. package/src/migration-targets.ts +12 -0
  167. package/src/operator-access.test.ts +15 -0
  168. package/src/operator-access.ts +14 -0
  169. package/src/pool-budget-stack.ts +15 -0
  170. package/src/pool-budget-stacks.test.ts +38 -13
  171. package/src/public-role-isolation.test.ts +18 -8
  172. package/src/public-role-isolation.ts +31 -17
  173. package/src/release-contract.ts +3 -0
  174. package/src/runtime-secrets.test.ts +18 -8
  175. package/src/runtime-secrets.ts +37 -18
  176. package/src/scheduler-setup.test.ts +201 -0
  177. package/src/scheduler-setup.ts +375 -0
  178. package/src/self-hosted-backup.test.ts +1 -0
  179. package/src/self-hosted-compose.test.ts +72 -1
  180. package/src/self-hosted-roles.integration.test.ts +2 -0
  181. package/src/self-hosted-roles.test.ts +49 -19
  182. package/src/self-hosted-roles.ts +60 -20
  183. package/src/self-hosted-scheduler-interval.test.ts +66 -0
  184. package/src/self-hosted-scheduler-interval.ts +79 -0
  185. package/src/self-hosted-start.test.ts +1 -0
  186. package/src/self-hosted-upgrade.test.ts +2 -1
  187. package/src/self-hosted-upgrade.ts +14 -8
  188. package/src/stack-contract.test.ts +31 -3
  189. package/src/stack-contract.ts +113 -6
  190. package/src/stack-converge-secrets.test.ts +2 -0
  191. package/src/stack-converge.test.ts +6 -4
  192. package/src/staging-database.test.ts +114 -0
  193. package/src/staging-database.ts +148 -0
  194. package/src/upgrade/converge.ts +130 -9
  195. package/src/upgrade/upgrade.test.ts +85 -2
  196. package/src/upgrade/upgrade.ts +9 -0
  197. package/src/upgrader-gcp.ts +5 -4
  198. package/src/wizard.ts +19 -0
  199. package/src/wizards/gcp-cost.test.ts +54 -1
  200. package/src/wizards/gcp-cost.ts +101 -11
  201. package/src/wizards/gcp.ts +109 -8
  202. package/stacks/aws/Pulumi.yaml +1 -1
  203. package/stacks/aws/index.ts +41 -1
  204. package/stacks/azure/index.ts +51 -3
  205. package/stacks/gcp/Pulumi.yaml +1 -1
  206. package/stacks/gcp/README.md +1 -0
  207. package/stacks/gcp/index.ts +50 -1
  208. package/stacks/gcp-firebase/Pulumi.yaml +1 -1
  209. package/stacks/gcp-firebase/index.ts +50 -1
  210. package/stacks/self-hosted/Pulumi.yaml +3 -0
  211. package/stacks/self-hosted/README.md +4 -0
  212. package/stacks/self-hosted/index.ts +29 -4
@@ -41,8 +41,10 @@ import {
41
41
  runServiceAccountId,
42
42
  } from "../../dist/gcp-names.js";
43
43
  import {
44
+ DEFAULT_ADMIN_MAX_INSTANCES,
44
45
  DEFAULT_GATEWAY_MAX_INSTANCES,
45
46
  DEFAULT_MAX_CONNECTIONS,
47
+ DEFAULT_STAGING_GATEWAY_MAX_INSTANCES,
46
48
  stackPoolBudget,
47
49
  } from "../../dist/pool-budget-stack.js";
48
50
  import {
@@ -109,7 +111,10 @@ const adminMinInstances = Number.parseInt(cfg.get("adminMinInstances") ?? "0", 1
109
111
  // #553 — the admin also runs the Lighthouse quality audit; same knob and
110
112
  // default on every adapter (stack-contract.ts ADMIN_MEMORY_DEFAULT).
111
113
  const adminMemory = cfg.get("adminMemory") ?? ADMIN_MEMORY_DEFAULT;
112
- const adminMaxInstances = Number.parseInt(cfg.get("adminMaxInstances") ?? "5", 10);
114
+ const adminMaxInstances = Number.parseInt(
115
+ cfg.get("adminMaxInstances") ?? String(DEFAULT_ADMIN_MAX_INSTANCES),
116
+ 10,
117
+ );
113
118
  const gatewayMinInstances = Number.parseInt(cfg.get("gatewayMinInstances") ?? "0", 10);
114
119
  // #1254 — part of the connection budget (stacks/gcp has the long comment).
115
120
  const gatewayMaxInstances = Number.parseInt(
@@ -125,6 +130,8 @@ const poolBudget = stackPoolBudget("gcp-firebase", {
125
130
  maxConnections,
126
131
  adminMaxInstances,
127
132
  gatewayMaxInstances,
133
+ // #1329 — the staging gateway (P3b-2) is budgeted from this release on.
134
+ stagingGatewayMaxInstances: DEFAULT_STAGING_GATEWAY_MAX_INSTANCES,
128
135
  });
129
136
  const backupRetentionDays = Number.parseInt(cfg.get("backupRetentionDays") ?? "7", 10);
130
137
  const iapAllowlistRaw = cfg.get("iapAllowlist");
@@ -262,6 +269,8 @@ const runtimeSecretIds: Record<RuntimeSecret, pulumi.Input<string>> = {
262
269
  "tool-approval-secret": gcpSecretId(env, "tool-approval-secret"),
263
270
  "staging-gate-secret": gcpSecretId(env, "staging-gate-secret"),
264
271
  "public-role-password": gcpSecretId(env, "public-role-password"),
272
+ // #1329 — the staging gateway's login, never the live one's.
273
+ "public-staging-role-password": gcpSecretId(env, "public-staging-role-password"),
265
274
  // #914 / #806 — the Owner-set Google sign-in client (a placeholder until
266
275
  // then; IAP login, IAP programmatic access and the remote-MCP broker) and
267
276
  // the broker's seal key, both CLI-generated.
@@ -278,6 +287,14 @@ const publicRolePassword = pulumi.secret(
278
287
  { provider: gcpProvider },
279
288
  ).secretData,
280
289
  );
290
+ // #1329 — public_staging_role's own password (CLI-generated like the one
291
+ // above): the staging gateway's only login, on cms_public_staging only.
292
+ const publicStagingRolePassword = pulumi.secret(
293
+ gcp.secretmanager.getSecretVersionOutput(
294
+ { project, secret: gcpSecretId(env, "public-staging-role-password") },
295
+ { provider: gcpProvider },
296
+ ).secretData,
297
+ );
281
298
 
282
299
  // =========================================================================
283
300
  // Tier 4 — Cloud SQL Postgres (private IP only; HA configurable)
@@ -334,6 +351,13 @@ const cmsPublicDb = new gcp.sql.Database(
334
351
  { instance: sqlInstance.name, name: "cms_public" },
335
352
  opts,
336
353
  );
354
+ // #1329 — staging's own data: the twin of cms_public on the same instance
355
+ // (no extra cost), reached by the staging gateway only.
356
+ const cmsPublicStagingDb = new gcp.sql.Database(
357
+ `${namePrefix}-cms-public-staging`,
358
+ { instance: sqlInstance.name, name: "cms_public_staging" },
359
+ opts,
360
+ );
337
361
 
338
362
  const pgAdminUser = new gcp.sql.User(
339
363
  `${namePrefix}-admin-user`,
@@ -352,6 +376,14 @@ new gcp.sql.User(
352
376
  { instance: sqlInstance.name, name: "public_role", password: publicRolePassword },
353
377
  opts,
354
378
  );
379
+ // #1329 — the staging gateway's login: an Admin API user like public_role,
380
+ // so the same membership revoke (public-role-isolation.ts) and the same
381
+ // audit apply; migration 0530 gives it CONNECT on cms_public_staging only.
382
+ new gcp.sql.User(
383
+ `${namePrefix}-public-staging-user`,
384
+ { instance: sqlInstance.name, name: "public_staging_role", password: publicStagingRolePassword },
385
+ opts,
386
+ );
355
387
 
356
388
  // #1338 — the instance's DNS name, resolved to its private IP by a private
357
389
  // zone in the VPC (Cloud SQL assigns the name, it does not resolve it).
@@ -729,6 +761,7 @@ function cloudRunService(args: CloudRunArgs): gcp.cloudrunv2.Service {
729
761
  pgAdminUser,
730
762
  cmsAdminDb,
731
763
  cmsPublicDb,
764
+ cmsPublicStagingDb,
732
765
  // The env contract names the media bucket as a string; keep it
733
766
  // ordered before the services that use it.
734
767
  mediaBucket,
@@ -756,6 +789,8 @@ const envContractInputs = {
756
789
  admin: dbUrls.admin,
757
790
  publicAdmin: dbUrls.publicAdmin,
758
791
  public: dbUrls.public,
792
+ publicStagingAdmin: dbUrls.publicStagingAdmin,
793
+ publicStaging: dbUrls.publicStaging,
759
794
  },
760
795
  } as const;
761
796
 
@@ -1129,6 +1164,18 @@ new gcp.iap.WebCloudRunServiceIamMember(
1129
1164
  // (packages/provisioning/src/capture-job-setup.ts), for the same reason as
1130
1165
  // the audit job above.
1131
1166
 
1167
+ // =========================================================================
1168
+ // Scheduler tick — deliberately NOT here
1169
+ // =========================================================================
1170
+ //
1171
+ // #1140 — one Cloud Scheduler job starts a Cloud Workflows execution every
1172
+ // `schedulerIntervalMinutes` (1–15, default 5); the workflow signs an IAP
1173
+ // credential as the scheduler's own service account and POSTs the admin's
1174
+ // /api/internal/scheduler/tick, where the admin runs its periodic work and
1175
+ // plugin workers from its due-table. The CLI owns the account, its grants,
1176
+ // the workflow and the job (packages/provisioning/src/scheduler-setup.ts),
1177
+ // for the same reason as the audit job above.
1178
+
1132
1179
  // =========================================================================
1133
1180
  // Operator access — deliberately NOT here
1134
1181
  // =========================================================================
@@ -1213,6 +1260,7 @@ const out: CloudAdapterOutputs = {
1213
1260
  // Password-less — the password lives only in Secret Manager.
1214
1261
  adminDatabaseUrl: dbUrls.admin as unknown as string,
1215
1262
  publicDatabaseUrl: dbUrls.public as unknown as string,
1263
+ publicStagingDatabaseUrl: dbUrls.publicStaging as unknown as string,
1216
1264
  mediaStorageUrl: pulumi.interpolate`gs://${mediaBucket.name}` as unknown as string,
1217
1265
  // Firebase Hosting serves media via its own CDN; we proxy through
1218
1266
  // the Firebase site's apex domain for canonical URLs.
@@ -1229,6 +1277,7 @@ const out: CloudAdapterOutputs = {
1229
1277
 
1230
1278
  export const adminDatabaseUrlOut = out.adminDatabaseUrl;
1231
1279
  export const publicDatabaseUrlOut = out.publicDatabaseUrl;
1280
+ export const publicStagingDatabaseUrlOut = out.publicStagingDatabaseUrl;
1232
1281
  export const mediaStorageUrlOut = out.mediaStorageUrl;
1233
1282
  export const mediaCdnBaseUrlOut = out.mediaCdnBaseUrl;
1234
1283
  export const bootstrapUrlOut = out.bootstrapUrl;
@@ -29,3 +29,6 @@ config:
29
29
  type: string
30
30
  default: "2Gi"
31
31
  description: Memory reserved for the admin container (it runs the Lighthouse quality audit).
32
+ caelo-self-hosted:schedulerIntervalMinutes:
33
+ type: integer
34
+ description: Minutes between scheduler ticks (1-15, default 5; #1140). On an install `cms-provision init` set up, `.caelo/config.json` records it and this key must match.
@@ -33,6 +33,10 @@ pulumi stack output bootstrapUrl
33
33
 
34
34
  Open that URL once Caddy has issued the cert (~30 s).
35
35
 
36
+ ## Scheduler tick
37
+
38
+ The Compose file runs a `caelo-scheduler` container (the admin image, no database access, only the internal secret it signs with) that POSTs the admin's `/api/internal/scheduler/tick` every `schedulerIntervalMinutes` (#1140; 1–15, default 5). The admin runs its periodic work and plugin workers on that tick. Set the interval with `cms-provision init --scheduler-interval-minutes 2` (recorded in `.caelo/config.json`, which every CLI render reads) or, on an install without a `config.json`, with `pulumi config set caelo-self-hosted:schedulerIntervalMinutes 2`. The stack reads `.caelo/config.json` too, so a `pulumi up` keeps the recorded interval; a Pulumi key that disagrees with it is refused. An install from before the scheduler gets the container on its next `upgrade`, which rewrites the Compose file.
39
+
36
40
  ## Connection budget
37
41
 
38
42
  The generated Compose file starts Postgres with `max_connections=100` and sizes every pool from it (#1254, docs/dev/connection-budget.md): the admin gets a cms_admin pool of 77 and a cms_public pool of 4, the gateway a pool of 2, and static builds 2 per pool.
@@ -34,7 +34,12 @@ import {
34
34
  generateDockerCompose,
35
35
  SITE_OUTPUT_ROOT,
36
36
  } from "../../dist/compose.js";
37
+ import { MIGRATION_TARGETS } from "../../dist/migration-targets.js";
37
38
  import { selfHostedBootstrapScript } from "../../dist/self-hosted-roles.js";
39
+ import {
40
+ recordedSchedulerIntervalMinutes,
41
+ selfHostedSchedulerIntervalMinutes,
42
+ } from "../../dist/self-hosted-scheduler-interval.js";
38
43
 
39
44
  const cfg = new pulumi.Config();
40
45
  const domain = cfg.require("domain");
@@ -44,6 +49,17 @@ const ownerEmail = cfg.require("ownerEmail");
44
49
  const caeloDir = cfg.get("caeloDir") ?? "./.caelo";
45
50
  // #553 — same knob as every adapter; undefined = stack-contract default.
46
51
  const adminMemory = cfg.get("adminMemory");
52
+ // #1140 — how often the scheduler container calls the admin's tick (1–15
53
+ // minutes, default 5). `init --scheduler-interval-minutes` records it in
54
+ // <caeloDir>/config.json, which the CLI renders from; the stack reads the
55
+ // same record so a `pulumi up` does not put it back to the default, and
56
+ // refuses a Pulumi key that disagrees with it.
57
+ const caeloConfigPath = resolve(caeloDir, "config.json");
58
+ const schedulerIntervalMinutes = selfHostedSchedulerIntervalMinutes(
59
+ cfg.getNumber("schedulerIntervalMinutes"),
60
+ recordedSchedulerIntervalMinutes(caeloConfigPath),
61
+ caeloConfigPath,
62
+ );
47
63
  // #696 — the prebuilt, cosign-verified release images, pinned by digest
48
64
  // (`ghcr.io/caelo-cms/<svc>@sha256:…`; the generator refuses anything else).
49
65
  // `cms-provision init` resolves + verifies them and records them in
@@ -69,21 +85,30 @@ const postgresPassword = pulumi.secret(randomHex(32));
69
85
  // public_role one (#635: no cms_admin login).
70
86
  const adminRolePassword = pulumi.secret(randomHex(32));
71
87
  const publicRolePassword = pulumi.secret(randomHex(32));
88
+ // #1329 — the staging gateway's own login on cms_public_staging.
89
+ const publicStagingRolePassword = pulumi.secret(randomHex(32));
72
90
  // P18 — the KEK that encrypts stored provider keys.
73
91
  const caeloSecretKek = pulumi.secret(randomHex(32));
74
92
 
75
93
  const composeYaml = pulumi
76
- .all([postgresPassword, adminRolePassword, publicRolePassword, caeloSecretKek])
77
- .apply(([pgPw, adminPw, publicPw, kek]) =>
94
+ .all([
95
+ postgresPassword,
96
+ adminRolePassword,
97
+ publicRolePassword,
98
+ publicStagingRolePassword,
99
+ caeloSecretKek,
100
+ ])
101
+ .apply(([pgPw, adminPw, publicPw, publicStagingPw, kek]) =>
78
102
  generateDockerCompose({
79
103
  domain,
80
104
  postgresPassword: pgPw,
81
- rolePasswords: { admin: adminPw, public: publicPw },
105
+ rolePasswords: { admin: adminPw, public: publicPw, publicStaging: publicStagingPw },
82
106
  caeloSecretKek: kek,
83
107
  anthropicApiKey: process.env.ANTHROPIC_API_KEY,
84
108
  resendApiKey: process.env.RESEND_API_KEY,
85
109
  diskSize: "20Gi",
86
110
  ...(adminMemory ? { adminMemory } : {}),
111
+ ...(schedulerIntervalMinutes !== undefined ? { schedulerIntervalMinutes } : {}),
87
112
  images: {
88
113
  mode: "release",
89
114
  admin: adminImage,
@@ -144,7 +169,7 @@ const composeUp = new local.Command(
144
169
  // install's admin image, then everything else.
145
170
  create: pulumi.interpolate`set -e
146
171
  docker compose -f ${composePath} up -d --wait postgres
147
- for target in admin public; do
172
+ for target in ${MIGRATION_TARGETS.join(" ")}; do
148
173
  docker compose -f ${composePath} run --rm --no-deps -T caelo-admin bun --bun /app/packages/migrations/src/migrate.ts "$target"
149
174
  done
150
175
  docker compose -f ${composePath} up -d --remove-orphans`,