@toa.io/operations 1.0.0-alpha.33 → 1.0.0-alpha.331

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 (78) hide show
  1. package/CHANGELOG.md +378 -0
  2. package/image/runtime.Dockerfile +20 -0
  3. package/package.json +10 -10
  4. package/readme.md +224 -0
  5. package/src/deployment/.deployment/.describe/components.js +1 -5
  6. package/src/deployment/.deployment/.describe/compositions.js +26 -7
  7. package/src/deployment/.deployment/.describe/dependencies.js +1 -6
  8. package/src/deployment/.deployment/.describe/events.js +63 -0
  9. package/src/deployment/.deployment/.describe/fold.js +42 -0
  10. package/src/deployment/.deployment/.describe/fold.test.js +108 -0
  11. package/src/deployment/.deployment/.describe/index.js +4 -13
  12. package/src/deployment/.deployment/.describe/mounts.js +17 -0
  13. package/src/deployment/.deployment/.describe/resources.js +129 -0
  14. package/src/deployment/.deployment/.describe/resources.test.js +129 -0
  15. package/src/deployment/.deployment/.describe/services.js +32 -6
  16. package/src/deployment/.deployment/.describe/services.test.js +78 -0
  17. package/src/deployment/.deployment/.describe/variables.js +5 -9
  18. package/src/deployment/.deployment/declare.js +1 -5
  19. package/src/deployment/.deployment/describe.js +160 -10
  20. package/src/deployment/.deployment/index.js +3 -9
  21. package/src/deployment/.deployment/merge.js +66 -6
  22. package/src/deployment/.deployment/merge.test.js +133 -0
  23. package/src/deployment/chart/templates/components.configmap.yaml +13 -0
  24. package/src/deployment/chart/templates/components.yaml +4 -3
  25. package/src/deployment/chart/templates/compositions.yaml +109 -4
  26. package/src/deployment/chart/templates/mono.yaml +195 -0
  27. package/src/deployment/chart/templates/services.yaml +97 -7
  28. package/src/deployment/chart/values.yaml +23 -1
  29. package/src/deployment/composition.js +8 -6
  30. package/src/deployment/deployment.js +175 -35
  31. package/src/deployment/drain.js +70 -0
  32. package/src/deployment/drain.test.js +64 -0
  33. package/src/deployment/factory.js +172 -37
  34. package/src/deployment/images/bundle.js +93 -0
  35. package/src/deployment/images/composition.Dockerfile +9 -17
  36. package/src/deployment/images/composition.js +9 -56
  37. package/src/deployment/images/dependencies.Dockerfile +23 -0
  38. package/src/deployment/images/dependencies.js +171 -0
  39. package/src/deployment/images/dependencies.test.js +271 -0
  40. package/src/deployment/images/factory.js +31 -15
  41. package/src/deployment/images/format.js +66 -0
  42. package/src/deployment/images/format.test.js +150 -0
  43. package/src/deployment/images/image.fixtures.js +17 -19
  44. package/src/deployment/images/image.js +79 -38
  45. package/src/deployment/images/image.test.js +11 -5
  46. package/src/deployment/images/index.js +1 -5
  47. package/src/deployment/images/mono.Dockerfile +11 -0
  48. package/src/deployment/images/mono.js +15 -0
  49. package/src/deployment/images/publish.js +91 -0
  50. package/src/deployment/images/runtime-base.test.js +97 -0
  51. package/src/deployment/images/service.Dockerfile +17 -5
  52. package/src/deployment/images/service.js +63 -14
  53. package/src/deployment/index.js +1 -5
  54. package/src/deployment/operator.js +25 -16
  55. package/src/deployment/operator.test.js +98 -7
  56. package/src/deployment/registry.js +210 -46
  57. package/src/deployment/registry.test.js +539 -0
  58. package/src/deployment/secrets.js +92 -0
  59. package/src/deployment/secrets.test.js +180 -0
  60. package/src/deployment/service.js +4 -6
  61. package/src/deployment/workspace.js +13 -8
  62. package/src/index.js +3 -2
  63. package/src/process.js +51 -13
  64. package/src/process.test.js +33 -0
  65. package/types/_deployment/composition.d.ts +2 -3
  66. package/types/_deployment/dependency.d.ts +15 -7
  67. package/types/_deployment/deployment.d.ts +10 -8
  68. package/types/_deployment/factory.d.ts +2 -4
  69. package/types/_deployment/images/factory.d.ts +6 -8
  70. package/types/_deployment/images/image.d.ts +16 -1
  71. package/types/_deployment/images/registry.d.ts +8 -11
  72. package/types/_deployment/operator.d.ts +10 -9
  73. package/types/_deployment/registry.d.ts +7 -4
  74. package/types/_deployment/service.d.ts +4 -3
  75. package/types/dependency.ts +79 -0
  76. package/types/index.ts +1 -0
  77. package/types/dependency.d.ts +0 -39
  78. package/types/index.d.ts +0 -1
package/CHANGELOG.md ADDED
@@ -0,0 +1,378 @@
1
+ # Change Log
2
+
3
+ All notable changes to this project will be documented in this file.
4
+ See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5
+
6
+ # [1.0.0-alpha.331](https://github.com/toa-io/toa/compare/v1.0.0-alpha.330...v1.0.0-alpha.331) (2026-10-16)
7
+
8
+ ### Bug Fixes
9
+
10
+ * **operations:** a deploy waited for is rolled back where it fails ([41ce1c5](https://github.com/toa-io/toa/commit/41ce1c5f462c5dcd78e138dba7c7cc4300e8e9fb))
11
+
12
+
13
+ # [1.0.0-alpha.330](https://github.com/toa-io/toa/compare/v1.0.0-alpha.329...v1.0.0-alpha.330) (2026-10-15)
14
+
15
+ **Note:** Version bump only for package @toa.io/operations
16
+
17
+
18
+
19
+
20
+
21
+ # [1.0.0-alpha.329](https://github.com/toa-io/toa/compare/v1.0.0-alpha.328...v1.0.0-alpha.329) (2026-10-11)
22
+
23
+ **Note:** Version bump only for package @toa.io/operations
24
+
25
+
26
+
27
+
28
+
29
+ # [1.0.0-alpha.328](https://github.com/toa-io/toa/compare/v1.0.0-alpha.327...v1.0.0-alpha.328) (2026-10-10)
30
+
31
+ **Note:** Version bump only for package @toa.io/operations
32
+
33
+
34
+
35
+
36
+
37
+ # [1.0.0-alpha.327](https://github.com/toa-io/toa/compare/v1.0.0-alpha.326...v1.0.0-alpha.327) (2026-10-10)
38
+
39
+ **Note:** Version bump only for package @toa.io/operations
40
+
41
+
42
+
43
+
44
+
45
+ # [1.0.0-alpha.326](https://github.com/toa-io/toa/compare/v1.0.0-alpha.325...v1.0.0-alpha.326) (2026-10-06)
46
+
47
+ **Note:** Version bump only for package @toa.io/operations
48
+
49
+
50
+
51
+
52
+
53
+ # [1.0.0-alpha.325](https://github.com/toa-io/toa/compare/v1.0.0-alpha.324...v1.0.0-alpha.325) (2026-10-02)
54
+
55
+ **Note:** Version bump only for package @toa.io/operations
56
+
57
+
58
+
59
+
60
+
61
+ # [1.0.0-alpha.324](https://github.com/toa-io/toa/compare/v1.0.0-alpha.323...v1.0.0-alpha.324) (2026-10-02)
62
+
63
+ **Note:** Version bump only for package @toa.io/operations
64
+
65
+
66
+
67
+
68
+
69
+ # [1.0.0-alpha.323](https://github.com/toa-io/toa/compare/v1.0.0-alpha.322...v1.0.0-alpha.323) (2026-10-01)
70
+
71
+ **Note:** Version bump only for package @toa.io/operations
72
+
73
+
74
+
75
+
76
+
77
+ # [1.0.0-alpha.322](https://github.com/toa-io/toa/compare/v1.0.0-alpha.321...v1.0.0-alpha.322) (2026-09-29)
78
+
79
+ **Note:** Version bump only for package @toa.io/operations
80
+
81
+
82
+
83
+
84
+
85
+ # [1.0.0-alpha.321](https://github.com/toa-io/toa/compare/v1.0.0-alpha.320...v1.0.0-alpha.321) (2026-09-28)
86
+
87
+ **Note:** Version bump only for package @toa.io/operations
88
+
89
+
90
+
91
+
92
+
93
+ # [1.0.0-alpha.320](https://github.com/toa-io/toa/compare/v1.0.0-alpha.319...v1.0.0-alpha.320) (2026-09-28)
94
+
95
+ **Note:** Version bump only for package @toa.io/operations
96
+
97
+
98
+
99
+
100
+
101
+ # [1.0.0-alpha.319](https://github.com/toa-io/toa/compare/v1.0.0-alpha.318...v1.0.0-alpha.319) (2026-09-27)
102
+
103
+ ### Features
104
+
105
+ * **operations:** refuse a deploy where the cluster does not hold a secret ([beb7ccf](https://github.com/toa-io/toa/commit/beb7ccf35619494ab9ad6659963969bb4f9603c8))
106
+
107
+
108
+ # [1.0.0-alpha.318](https://github.com/toa-io/toa/compare/v1.0.0-alpha.317...v1.0.0-alpha.318) (2026-09-23)
109
+
110
+ ### Features
111
+
112
+ * **deployment:** copy a component's linked sources as files ([1a1a8c1](https://github.com/toa-io/toa/commit/1a1a8c10684348dba02b475ab809a4083f86a601))
113
+
114
+
115
+ # [1.0.0-alpha.317](https://github.com/toa-io/toa/compare/v1.0.0-alpha.316...v1.0.0-alpha.317) (2026-09-23)
116
+
117
+ **Note:** Version bump only for package @toa.io/operations
118
+
119
+
120
+
121
+
122
+
123
+ # [1.0.0-alpha.316](https://github.com/toa-io/toa/compare/v1.0.0-alpha.315...v1.0.0-alpha.316) (2026-09-23)
124
+
125
+ **Note:** Version bump only for package @toa.io/operations
126
+
127
+
128
+
129
+
130
+
131
+ # [1.0.0-alpha.315](https://github.com/toa-io/toa/compare/v1.0.0-alpha.314...v1.0.0-alpha.315) (2026-09-23)
132
+
133
+ * feat(map)!: leave out of a contract what the runtime gives every component ([b81837a](https://github.com/toa-io/toa/commit/b81837a3bc4771d7ee1c10fe613c9a1d7501bf1a))
134
+
135
+ ### BREAKING CHANGES
136
+
137
+ * the deployed component map is `/etc/toa/.map.json.gz`.
138
+
139
+
140
+ # [1.0.0-alpha.314](https://github.com/toa-io/toa/compare/v1.0.0-alpha.313...v1.0.0-alpha.314) (2026-09-19)
141
+
142
+ ### Features
143
+
144
+ * **core:** a reference may name a declaration its package claims ([8040f60](https://github.com/toa-io/toa/commit/8040f60976549ab90497675bb54e664261f5b6bb))
145
+
146
+
147
+ # [1.0.0-alpha.313](https://github.com/toa-io/toa/compare/v1.0.0-alpha.312...v1.0.0-alpha.313) (2026-09-18)
148
+
149
+ **Note:** Version bump only for package @toa.io/operations
150
+
151
+
152
+
153
+
154
+
155
+ # [1.0.0-alpha.312](https://github.com/toa-io/toa/compare/v1.0.0-alpha.311...v1.0.0-alpha.312) (2026-09-18)
156
+
157
+ ### Features
158
+
159
+ * **operations:** point a component's service at the port a streamed call is served on ([dbad630](https://github.com/toa-io/toa/commit/dbad630f765d5c1d50b3eda65768352905149c0c))
160
+ * **operations:** refuse to render a chart for a context with no version ([d6cd083](https://github.com/toa-io/toa/commit/d6cd083bfe8d7da9f3d451c2c25d821eb41ce958))
161
+
162
+
163
+ # [1.0.0-alpha.311](https://github.com/toa-io/toa/compare/v1.0.0-alpha.310...v1.0.0-alpha.311) (2026-09-17)
164
+
165
+ **Note:** Version bump only for package @toa.io/operations
166
+
167
+
168
+
169
+
170
+
171
+ # [1.0.0-alpha.310](https://github.com/toa-io/toa/compare/v1.0.0-alpha.309...v1.0.0-alpha.310) (2026-09-16)
172
+
173
+ **Note:** Version bump only for package @toa.io/operations
174
+
175
+
176
+
177
+
178
+
179
+ # [1.0.0-alpha.309](https://github.com/toa-io/toa/compare/v1.0.0-alpha.308...v1.0.0-alpha.309) (2026-09-16)
180
+
181
+ **Note:** Version bump only for package @toa.io/operations
182
+
183
+
184
+
185
+
186
+
187
+ # [1.0.0-alpha.308](https://github.com/toa-io/toa/compare/v1.0.0-alpha.307...v1.0.0-alpha.308) (2026-09-15)
188
+
189
+ **Note:** Version bump only for package @toa.io/operations
190
+
191
+
192
+
193
+
194
+
195
+ # [1.0.0-alpha.307](https://github.com/toa-io/toa/compare/v1.0.0-alpha.306...v1.0.0-alpha.307) (2026-09-15)
196
+
197
+ **Note:** Version bump only for package @toa.io/operations
198
+
199
+
200
+
201
+
202
+
203
+ # [1.0.0-alpha.306](https://github.com/toa-io/toa/compare/v1.0.0-alpha.305...v1.0.0-alpha.306) (2026-09-14)
204
+
205
+ **Note:** Version bump only for package @toa.io/operations
206
+
207
+
208
+
209
+
210
+
211
+ # [1.0.0-alpha.305](https://github.com/toa-io/toa/compare/v1.0.0-alpha.304...v1.0.0-alpha.305) (2026-09-13)
212
+
213
+ **Note:** Version bump only for package @toa.io/operations
214
+
215
+
216
+
217
+
218
+
219
+ # [1.0.0-alpha.304](https://github.com/toa-io/toa/compare/v1.0.0-alpha.303...v1.0.0-alpha.304) (2026-09-13)
220
+
221
+ **Note:** Version bump only for package @toa.io/operations
222
+
223
+
224
+
225
+
226
+
227
+ # [1.0.0-alpha.303](https://github.com/toa-io/toa/compare/v1.0.0-alpha.302...v1.0.0-alpha.303) (2026-09-12)
228
+
229
+ ### Features
230
+
231
+ * **operations:** a composition states how many replicas it runs ([4466f5a](https://github.com/toa-io/toa/commit/4466f5abcc22c6dceb2994a0143b6bf9d5201d9d))
232
+
233
+
234
+ # [1.0.0-alpha.302](https://github.com/toa-io/toa/compare/v1.0.0-alpha.301...v1.0.0-alpha.302) (2026-09-11)
235
+
236
+ **Note:** Version bump only for package @toa.io/operations
237
+
238
+
239
+
240
+
241
+
242
+ # [1.0.0-alpha.301](https://github.com/toa-io/toa/compare/v1.0.0-alpha.300...v1.0.0-alpha.301) (2026-09-11)
243
+
244
+ ### Bug Fixes
245
+
246
+ * **operations:** a composition of evicted components asks for no resources ([a6a3ec7](https://github.com/toa-io/toa/commit/a6a3ec76781812f5a9bdd46c6de0fe7769174d57))
247
+
248
+ ### Features
249
+
250
+ * **operations:** an evicted component is given its environment and configuration ([6cf7890](https://github.com/toa-io/toa/commit/6cf7890a632a2185d2b7d9790890a04187e5a897))
251
+
252
+
253
+ # [1.0.0-alpha.300](https://github.com/toa-io/toa/compare/v1.0.0-alpha.299...v1.0.0-alpha.300) (2026-09-11)
254
+
255
+ * feat(core)!: an operation may ask to run once ([dca616c](https://github.com/toa-io/toa/commit/dca616cb380a7a389e277875d3bd5ca55a6e4d45))
256
+
257
+ ### Features
258
+
259
+ * **cli:** generate env for listed components and services ([b830613](https://github.com/toa-io/toa/commit/b830613ae2a0443bf8e72a353ffb6f2efaa72fb5))
260
+ * **core:** a call may name the process it goes to, and wait for a set time ([7d8adb2](https://github.com/toa-io/toa/commit/7d8adb2772a95ff45ae5374efdedfb5a857fbbe9))
261
+ * **norm:** a context says what it does not deploy ([135e6fd](https://github.com/toa-io/toa/commit/135e6fdfbc4270762028e9e5a0516766960ce59c))
262
+ * **operations:** a rollout spreads the pods of its revision across nodes ([63be649](https://github.com/toa-io/toa/commit/63be649a73978a415f0c1e7ffb3837ffa7802da7))
263
+
264
+ ### BREAKING CHANGES
265
+
266
+ * `Storage.store`, `.upsert` and `.ensure` take one more
267
+ argument, and `Storage` has two more members. A connector that ignores them
268
+ works exactly as it did; a component that asks it for `once` is refused at
269
+ boot. See migrations/299.md.
270
+
271
+
272
+ # [1.0.0-alpha.299](https://github.com/toa-io/toa/compare/v1.0.0-alpha.298...v1.0.0-alpha.299) (2026-09-10)
273
+
274
+ **Note:** Version bump only for package @toa.io/operations
275
+
276
+
277
+
278
+
279
+
280
+ # [1.0.0-alpha.298](https://github.com/toa-io/toa/compare/v1.0.0-alpha.297...v1.0.0-alpha.298) (2026-09-08)
281
+
282
+ ### Features
283
+
284
+ * **operations:** tag a deploy with the environment so registries can prune ([7247c35](https://github.com/toa-io/toa/commit/7247c35f33fb34dcfb3ffa04b196c14bfb3d5620))
285
+
286
+
287
+ # [1.0.0-alpha.297](https://github.com/toa-io/toa/compare/v1.0.0-alpha.296...v1.0.0-alpha.297) (2026-09-08)
288
+
289
+ **Note:** Version bump only for package @toa.io/operations
290
+
291
+
292
+
293
+
294
+
295
+ # [1.0.0-alpha.296](https://github.com/toa-io/toa/compare/v1.0.0-alpha.295...v1.0.0-alpha.296) (2026-09-08)
296
+
297
+ ### Bug Fixes
298
+
299
+ * **exposition:** the gateway's image carries every storage provider ([ab19d25](https://github.com/toa-io/toa/commit/ab19d2567764d5a3148b067f186819d7e646908f))
300
+
301
+
302
+ # [1.0.0-alpha.295](https://github.com/toa-io/toa/compare/v1.0.0-alpha.294...v1.0.0-alpha.295) (2026-09-07)
303
+
304
+ **Note:** Version bump only for package @toa.io/operations
305
+
306
+
307
+
308
+
309
+
310
+ # [1.0.0-alpha.294](https://github.com/toa-io/toa/compare/v1.0.0-alpha.293...v1.0.0-alpha.294) (2026-09-07)
311
+
312
+ **Note:** Version bump only for package @toa.io/operations
313
+
314
+
315
+
316
+
317
+
318
+ # [1.0.0-alpha.293](https://github.com/toa-io/toa/compare/v1.0.0-alpha.292...v1.0.0-alpha.293) (2026-09-07)
319
+
320
+ **Note:** Version bump only for package @toa.io/operations
321
+
322
+
323
+
324
+
325
+
326
+ # [1.0.0-alpha.292](https://github.com/toa-io/toa/compare/v1.0.0-alpha.291...v1.0.0-alpha.292) (2026-09-07)
327
+
328
+ ### Features
329
+
330
+ * **cli:** the deployment library is a peer, and the binary is the CLI's ([a923f81](https://github.com/toa-io/toa/commit/a923f8173a55ed1c091213a7c7db1863ca1d0ba6))
331
+ * **norm:** a package's definition is read by one resolver ([bffd41c](https://github.com/toa-io/toa/commit/bffd41c8d18c42786b0bf321623088b9dabc4724))
332
+
333
+
334
+ # [1.0.0-alpha.291](https://github.com/toa-io/toa/compare/v1.0.0-alpha.290...v1.0.0-alpha.291) (2026-09-07)
335
+
336
+ **Note:** Version bump only for package @toa.io/operations
337
+
338
+
339
+
340
+
341
+
342
+ # [1.0.0-alpha.290](https://github.com/toa-io/toa/compare/v1.0.0-alpha.289...v1.0.0-alpha.290) (2026-09-07)
343
+
344
+ * fix(operations)!: an image starts as root again ([9eb0db7](https://github.com/toa-io/toa/commit/9eb0db75e3d02098fe75710280e8e15e63b73d57))
345
+ * The runtime's environment is not a component's (#1070), closes [#1070](https://github.com/toa-io/toa/issues/1070)
346
+
347
+ ### BREAKING CHANGES
348
+
349
+ * a component that read `process.env.TOA_*` reads `context` instead;
350
+ `echo(input)` no longer substitutes from the environment; a bash operation sees no
351
+ `TOA_*`; images no longer set `USER node` — see migrations/289.md.
352
+ * an image built by alpha.289 runs its composition as `node` and
353
+ leaves the deployed environment readable under /proc; rebuild on 290. Nothing in
354
+ a context or a manifest changes.
355
+
356
+
357
+ # [1.0.0-alpha.289](https://github.com/toa-io/toa/compare/v1.0.0-alpha.288...v1.0.0-alpha.289) (2026-09-07)
358
+
359
+ * A deploy moves only what changed, and a component sees none of the runtime's environment (#1073) ([f38e3db](https://github.com/toa-io/toa/commit/f38e3db533f24db866c57bfa1ef294eff1eaf499)), closes [#1073](https://github.com/toa-io/toa/issues/1073) [#1064](https://github.com/toa-io/toa/issues/1064) [#1066](https://github.com/toa-io/toa/issues/1066) [#1067](https://github.com/toa-io/toa/issues/1067) [#1068](https://github.com/toa-io/toa/issues/1068) [#1069](https://github.com/toa-io/toa/issues/1069) [#1071](https://github.com/toa-io/toa/issues/1071) [#1070](https://github.com/toa-io/toa/issues/1070) [#1072](https://github.com/toa-io/toa/issues/1072)
360
+
361
+ ### BREAKING CHANGES
362
+
363
+ * a component that read `process.env.TOA_*` reads `context` instead;
364
+ `echo(input)` no longer substitutes from the environment; a bash operation sees no
365
+ `TOA_*`; images no longer set `USER node` — see migrations/289.md.
366
+
367
+
368
+ # [1.0.0-alpha.288](https://github.com/toa-io/toa/compare/v1.0.0-alpha.287...v1.0.0-alpha.288) (2026-09-06)
369
+
370
+ **Note:** Version bump only for package @toa.io/operations
371
+
372
+
373
+
374
+
375
+
376
+ # [1.0.0-alpha.287](https://github.com/toa-io/toa/compare/v1.0.0-alpha.286...v1.0.0-alpha.287) (2026-09-06)
377
+
378
+ **Note:** Version bump only for package @toa.io/operations
@@ -0,0 +1,20 @@
1
+ FROM node:24.14.0-alpine3.22
2
+
3
+ ARG VERSION
4
+
5
+ # installed locally rather than globally: the binary is @toa.io/cli's, which the runtime depends
6
+ # on, and npm links a dependency's binaries only into a local `node_modules/.bin`
7
+ WORKDIR /toa
8
+
9
+ # what the install scripts of Toa's own dependencies may do, stated where npm reads it — the
10
+ # project Toa is installed into, which every later `npm i --prefix /toa` of an image built on
11
+ # this one installs into too. npm runs no script nobody allowed and warns about each, and the
12
+ # one there is, msgpackr-extract's, only looks for the binary its optional dependency provides
13
+ RUN echo '{ "private": true, "allowScripts": { "msgpackr-extract": false } }' > package.json
14
+
15
+ # mounted rather than written: npm's cache is a hundred megabytes, and a layer keeps whatever
16
+ # the command left behind
17
+ RUN --mount=type=cache,target=/root/.npm,sharing=locked \
18
+ npm i @toa.io/runtime@${VERSION} --omit=dev
19
+
20
+ ENV PATH=/toa/node_modules/.bin:$PATH
package/package.json CHANGED
@@ -1,6 +1,7 @@
1
1
  {
2
2
  "name": "@toa.io/operations",
3
- "version": "1.0.0-alpha.33",
3
+ "version": "1.0.0-alpha.331",
4
+ "type": "module",
4
5
  "description": "Toa Deployment",
5
6
  "homepage": "https://toa.io",
6
7
  "author": {
@@ -16,23 +17,22 @@
16
17
  "url": "https://github.com/toa-io/toa/issues"
17
18
  },
18
19
  "engines": {
19
- "node": ">= 18.0.0"
20
+ "node": ">= 24.0.0"
20
21
  },
21
22
  "publishConfig": {
22
23
  "access": "public"
23
24
  },
24
25
  "main": "src/index.js",
25
- "types": "types/index.d.ts",
26
+ "types": "types/index.ts",
26
27
  "scripts": {
27
28
  "test": "echo \"Error: run tests from root\" && exit 1"
28
29
  },
29
30
  "dependencies": {
30
- "@toa.io/filesystem": "1.0.0-alpha.33",
31
- "@toa.io/generic": "1.0.0-alpha.33",
32
- "@toa.io/norm": "1.0.0-alpha.33",
33
- "@toa.io/yaml": "1.0.0-alpha.33",
34
- "execa": "5.1.1",
35
- "fs-extra": "11.1.1"
31
+ "@toa.io/generic": "1.0.0-alpha.330",
32
+ "@toa.io/kubernetes": "1.0.0-alpha.301",
33
+ "@toa.io/norm": "1.0.0-alpha.331",
34
+ "oxc-parser": "0.153.0",
35
+ "paseto": "4.0.1"
36
36
  },
37
- "gitHead": "ef81cea49d8f8b3b248adaba62d4548bbeb39f80"
37
+ "gitHead": "e7020d160910ca4f0c2ff9040b3cbb4fca8ea41f"
38
38
  }
package/readme.md CHANGED
@@ -1,9 +1,188 @@
1
1
  # Toa Operations
2
2
 
3
+ ## Installing
4
+
5
+ `toa deploy`, `toa build`, `toa push`, `toa env`, `toa export` and `toa conceal` need this package
6
+ beside the CLI. The runtime does not depend on it, so an application that deploys lists it with the
7
+ runtime:
8
+
9
+ ```shell
10
+ $ npm i -D @toa.io/runtime @toa.io/operations
11
+ ```
12
+
13
+ A machine that only deploys needs no runtime and no extension:
14
+
15
+ ```shell
16
+ $ npm i @toa.io/cli @toa.io/operations
17
+ $ npx toa deploy production -p application
18
+ ```
19
+
20
+ What the extensions declare is read from `@toa.io/definitions`, which the CLI brings; what they run
21
+ is not needed to render a chart. `registry.services: build` is the exception: it builds an
22
+ extension's service image from the installed package, so it needs the runtime installed beside
23
+ this one. `published` does not.
24
+
25
+ ## Compositions
26
+
27
+ A composition is deployed as one pod. Beside its components it may run extension services,
28
+ which are otherwise each deployed on their own:
29
+
30
+ ```yaml
31
+ # context.toa.yaml
32
+
33
+ compositions:
34
+ - name: edge
35
+ components:
36
+ - todos.tasks
37
+ services:
38
+ - exposition
39
+ ```
40
+
41
+ See [compositions](../documentation/compositions.md).
42
+
43
+ ## Evicted
44
+
45
+ What Toa does not deploy for a context, whatever a composition lists. It stays part of the
46
+ context, and is deployed by other means:
47
+
48
+ ```yaml
49
+ # context.toa.yaml
50
+
51
+ evicted:
52
+ components:
53
+ - todos.stats
54
+ services:
55
+ - exposition
56
+ ```
57
+
58
+ Nothing an evicted component alone required is deployed either — its storage, the extensions it
59
+ declared. `evicted@production` states it for one environment.
60
+
61
+ See [compositions](../documentation/compositions.md#evicted).
62
+
63
+ ## Secrets
64
+
65
+ A value that must not be in the chart is rendered as a reference to a Kubernetes secret, and the
66
+ secret is the application's to deploy. A deploy reads the namespace it deploys into before it builds
67
+ anything, and refuses where a key a workload would read is not there:
68
+
69
+ ```
70
+ $ toa deploy production
71
+ Secrets are not deployed: toa-mongodb.default/username, toa-mongodb.default/password
72
+ ```
73
+
74
+ Required is what `toa export secrets` lists, less the keys it marks `(optional)`, plus the
75
+ `registry.credentials` secret where a context names one. `toa deploy --dry` reads no cluster, and
76
+ neither does anything else that reads a context: `toa env`, `toa export`, `toa build` and `toa push`.
77
+
78
+ See [variables and secrets](../documentation/deployment.md#variables-and-secrets).
79
+
3
80
  ## Context
4
81
 
5
82
  ### Container Registry
6
83
 
84
+ Deploy images default to `FROM ghcr.io/toa-io/runtime:<runtime.version>`
85
+ (published with each Toa release). The base image already has `@toa.io/runtime`
86
+ installed; composition/service Dockerfiles only install component dependencies.
87
+
88
+ To use a custom base image, set `registry.build.image` (or `composition.image`).
89
+ That image must provide the `toa` CLI, or install it via `registry.build.run`. The binary is
90
+ `@toa.io/cli`'s, which the runtime depends on, so a local install puts it on the `PATH`:
91
+
92
+ ```yaml
93
+ # context.toa.yaml
94
+
95
+ registry:
96
+ build:
97
+ image: node:24.14.0-alpine3.22
98
+ run: |
99
+ npm i --prefix /toa @toa.io/runtime --omit=dev
100
+ ln -s /toa/node_modules/.bin/toa /usr/local/bin/toa
101
+ ```
102
+
103
+ `/toa` is where it goes: what an extension needs for what a component declares is installed
104
+ there, beside the extension that reads the declaration.
105
+
106
+ #### Composition Images
107
+
108
+ A composition is two images in one repository. `composition-<name>:deps-<hash>` is what its
109
+ components depend on, installed on the base image: it is tagged by everything the install
110
+ reads — the runtime version, the base image, the build options, each component's
111
+ `package.json` (and `package-lock.json`, where there is one), and what the extensions install
112
+ for what the components declare — and is built only when one of those changes. `composition-<name>:<hash>` is the sources laid over it in a single linked
113
+ layer, so a deploy that changes code alone builds and pushes that layer, and neither
114
+ downloads nor uploads the dependencies again. The same holds for `mono`.
115
+
116
+ The sources are copied as files, so a component that links a directory in — sources it shares with
117
+ another component — carries what the link points to, and a link the build cannot read fails the
118
+ build. What is linked is source alone: dependencies are installed per component, from its own
119
+ `package.json`.
120
+
121
+ Beside each component's sources the layer carries `manifest.toa.json`, the manifest as this
122
+ build normalised it. A composition reads it instead of normalising again, so it loads no
123
+ bridge to read what a module declares; a workspace has no such file and is read as it always
124
+ was. A component an extension ships has none either — its package is published long before any
125
+ image is built — and is read from the digest `@toa.io/definitions` carries, which a deploy has
126
+ always read. So nothing that runs reads a module's source, and `oxc-parser` is installed only
127
+ where a manifest is normalised: a workspace and a deploy, both through `@toa.io/operations`. What a build cannot express there — a prototype in a directory of the application's own
128
+ rather than in a package — fails the build, where before it failed the container.
129
+
130
+ A pushed image builds on the `toa` container builder, whose registry exporter is what lays
131
+ an image over a base it never pulled; `toa build` loads on the daemon's own.
132
+
133
+ A dependency named by a moving git ref is installed when the dependencies image is built and
134
+ not again until its manifest changes, so pin such a dependency to a commit and bump it there.
135
+
136
+ An extension's heavy dependency is not installed with the extension: `@toa.io/extensions.storages`
137
+ declares the AWS and Cloudinary SDKs as optional peers, so the base image carries neither. What a
138
+ component declares is what a deploy installs — the storages named in its `manifest.toa.yaml`,
139
+ resolved through the context's annotation to their providers' packages, installed into `/toa`
140
+ beside the extension that reads them. A composition whose components declare no `s3` storage
141
+ carries no AWS SDK, whatever the context declares for another composition. A workspace installs
142
+ the same set with `toa npm`.
143
+
144
+ #### Extension Service Images
145
+
146
+ `registry.services` says where an extension service's image comes from.
147
+
148
+ `build`, the default, builds one per service into `registry.base`. Its tag carries the
149
+ runtime version, so every Toa release rebuilds them all.
150
+
151
+ `published` deploys the image the extension ships and builds nothing:
152
+
153
+ ```yaml
154
+ # context.toa.yaml
155
+
156
+ registry:
157
+ services: published
158
+ ```
159
+
160
+ The images are tagged with the runtime version:
161
+
162
+ ```
163
+ ghcr.io/toa-io/extension-exposition-gateway:1.0.0-alpha.285
164
+ ghcr.io/toa-io/extension-introspection-explorer:1.0.0-alpha.285
165
+ ghcr.io/toa-io/extension-configuration-values:1.0.0-alpha.285
166
+ ```
167
+
168
+ The cluster pulls them from `ghcr.io` rather than from `registry.base`. They are public and
169
+ `registry.credentials` does not apply; a cluster that cannot reach `ghcr.io` needs `build`.
170
+
171
+ The field is environment-scoped like the rest:
172
+
173
+ ```yaml
174
+ # context.toa.yaml
175
+
176
+ registry:
177
+ base@local: localhost:5000
178
+ base@production: registry.digitalocean.com/acme
179
+ services: published
180
+ services@local: build
181
+ ```
182
+
183
+ An extension that states no image is built whatever this says, as is a service a
184
+ composition runs in its own pod.
185
+
7
186
  #### Build Options
8
187
 
9
188
  ```yaml
@@ -40,3 +219,48 @@ a secret containing required credentials can be specified using `registry.creden
40
219
  registry:
41
220
  credentials: docker-credentials-secret-name
42
221
  ```
222
+
223
+ The secret itself is not Toa's to create, and a deploy that does not find it in the cluster is
224
+ [refused](#secrets).
225
+
226
+ #### Toa images
227
+
228
+ Each release publishes `ghcr.io/toa-io/runtime:<version>` and, beside it, `:alpha` or `:latest`.
229
+ The extension services share that version:
230
+
231
+ ```
232
+ ghcr.io/toa-io/extension-exposition-gateway:1.0.0-alpha.285
233
+ ghcr.io/toa-io/extension-introspection-explorer:1.0.0-alpha.285
234
+ ghcr.io/toa-io/extension-configuration-values:1.0.0-alpha.285
235
+ ```
236
+
237
+ Untagged manifests are deleted. A prerelease older than 90 days, and not among the last 30, is
238
+ deleted with the four service images of that version. `:alpha`, `:latest`, and a version without
239
+ a pre-release suffix stay.
240
+
241
+ An application still on a deleted prerelease cannot pull `registry.services: published` and cannot
242
+ rebuild `FROM` that runtime. Images already in `registry.base` keep running. Stay inside the
243
+ window, or pin a graduated release.
244
+
245
+ #### Userspace images
246
+
247
+ `toa deploy production` writes two tags on the same composition image (`mono` and a service
248
+ `registry.services: build` built are the same):
249
+
250
+ - `<name>:<hash>` — what the chart pins. A hash of the runtime and the sources. `toa push` writes
251
+ this tag and nothing else.
252
+ - `<name>:production` — moved onto that image. The next production deploy moves it again.
253
+
254
+ `deps-<hash>` is not tagged with the environment. Do not name an environment eight hex digits, or
255
+ `deps-` plus eight: a retention job would treat it as a content tag.
256
+
257
+ A job the application runs deletes every `<hash>` and `deps-<hash>` older than 7 days, except the
258
+ last 5, except the image `:production` (or `:staging`, or `:latest`) currently names. Then:
259
+
260
+ ```shell
261
+ $ doctl registries garbage-collection start --include-untagged-manifests <registry>
262
+ ```
263
+
264
+ Rollback is only those 7 days, those last 5, and whatever the environment tag still names. Turn
265
+ the job on after the first deploy that writes that tag. The first garbage collection returns the
266
+ space the old tags held, and blocks pushes while it runs.
@@ -1,10 +1,8 @@
1
- 'use strict'
2
-
3
1
  /**
4
2
  * @param {toa.deployment.Composition[]} compositions
5
3
  * @returns {string[]}
6
4
  */
7
- const components = (compositions) => {
5
+ export const components = (compositions) => {
8
6
  /** @type {Set<string>} */
9
7
  const components = new Set()
10
8
 
@@ -16,5 +14,3 @@ const components = (compositions) => {
16
14
 
17
15
  return Array.from(components)
18
16
  }
19
-
20
- exports.components = components