@hyperframes/gcp-cloud-run 0.7.71 → 0.7.72
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.
- package/Dockerfile +1 -0
- package/dist/events.d.ts +71 -11
- package/dist/events.d.ts.map +1 -1
- package/dist/gcsTransport.d.ts +12 -0
- package/dist/gcsTransport.d.ts.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +338 -6
- package/dist/index.js.map +2 -2
- package/dist/sdk/index.js +10 -2
- package/dist/sdk/index.js.map +2 -2
- package/dist/sdk/renderToCloudRun.d.ts +6 -1
- package/dist/sdk/renderToCloudRun.d.ts.map +1 -1
- package/dist/server.d.ts +2 -1
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +333 -5
- package/dist/server.js.map +2 -2
- package/package.json +4 -3
- package/terraform/main.tf +5 -0
- package/terraform/outputs.tf +10 -0
- package/terraform/smoke-safety.test.ts +71 -0
- package/terraform/variables.tf +9 -0
- package/terraform/workflow.test.ts +148 -0
- package/terraform/workflow.yaml +149 -10
package/terraform/workflow.yaml
CHANGED
|
@@ -26,9 +26,23 @@ main:
|
|
|
26
26
|
- planOutputGcsPrefix: ${args.PlanOutputGcsPrefix}
|
|
27
27
|
- outputGcsUri: ${args.OutputGcsUri}
|
|
28
28
|
- config: ${args.Config}
|
|
29
|
+
# Backward-compatible default. v2 is accepted only through an
|
|
30
|
+
# explicit top-level PlanProtocol opt-in.
|
|
31
|
+
- planProtocol: ${default(map.get(args, "PlanProtocol"), "v1")}
|
|
29
32
|
|
|
30
33
|
# ── Plan (Activity A) ────────────────────────────────────────────────────
|
|
31
|
-
-
|
|
34
|
+
- selectPlanProtocol:
|
|
35
|
+
switch:
|
|
36
|
+
- condition: ${planProtocol == "v1"}
|
|
37
|
+
next: planV1
|
|
38
|
+
- condition: ${planProtocol == "v2"}
|
|
39
|
+
next: planV2
|
|
40
|
+
next: unsupportedPlanProtocol
|
|
41
|
+
- unsupportedPlanProtocol:
|
|
42
|
+
raise:
|
|
43
|
+
code: PLAN_PROTOCOL_UNSUPPORTED
|
|
44
|
+
message: ${"PlanProtocol must be v1 or v2; got " + string(planProtocol)}
|
|
45
|
+
- planV1:
|
|
32
46
|
try:
|
|
33
47
|
call: http.post
|
|
34
48
|
args:
|
|
@@ -36,22 +50,69 @@ main:
|
|
|
36
50
|
timeout: 1800
|
|
37
51
|
auth:
|
|
38
52
|
type: OIDC
|
|
53
|
+
audience: ${serviceUrl}
|
|
39
54
|
body:
|
|
40
55
|
Action: plan
|
|
56
|
+
PlanProtocol: v1
|
|
41
57
|
ProjectGcsUri: ${projectGcsUri}
|
|
42
58
|
PlanOutputGcsPrefix: ${planOutputGcsPrefix}
|
|
43
59
|
Config: ${config}
|
|
44
|
-
result:
|
|
60
|
+
result: planRespV1
|
|
45
61
|
retry:
|
|
46
62
|
predicate: ${retryable}
|
|
47
|
-
max_retries:
|
|
63
|
+
max_retries: 6
|
|
48
64
|
backoff:
|
|
49
65
|
initial_delay: 2
|
|
50
66
|
max_delay: 60
|
|
51
67
|
multiplier: 2
|
|
52
|
-
|
|
68
|
+
next: capturePlanV1
|
|
69
|
+
- capturePlanV1:
|
|
70
|
+
assign:
|
|
71
|
+
- planResult: ${planRespV1.body}
|
|
72
|
+
next: validatePlanResult
|
|
73
|
+
- planV2:
|
|
74
|
+
try:
|
|
75
|
+
call: http.post
|
|
76
|
+
args:
|
|
77
|
+
url: ${serviceUrl}
|
|
78
|
+
timeout: 1800
|
|
79
|
+
auth:
|
|
80
|
+
type: OIDC
|
|
81
|
+
audience: ${serviceUrl}
|
|
82
|
+
body:
|
|
83
|
+
Action: plan
|
|
84
|
+
PlanProtocol: v2
|
|
85
|
+
ProjectGcsUri: ${projectGcsUri}
|
|
86
|
+
PlanOutputGcsPrefix: ${planOutputGcsPrefix}
|
|
87
|
+
Config: ${config}
|
|
88
|
+
result: planRespV2
|
|
89
|
+
retry:
|
|
90
|
+
predicate: ${retryable}
|
|
91
|
+
max_retries: 6
|
|
92
|
+
backoff:
|
|
93
|
+
initial_delay: 2
|
|
94
|
+
max_delay: 60
|
|
95
|
+
multiplier: 2
|
|
96
|
+
next: capturePlanV2
|
|
97
|
+
- capturePlanV2:
|
|
98
|
+
assign:
|
|
99
|
+
- planResult: ${planRespV2.body}
|
|
100
|
+
next: validatePlanResult
|
|
101
|
+
- validatePlanResult:
|
|
102
|
+
# Fail closed before fan-out. A v2 render may never fall back to a
|
|
103
|
+
# v1 PlanGcsUri, and a v1 render may never consume v2 locators.
|
|
104
|
+
switch:
|
|
105
|
+
- condition: ${planProtocol == "v1" and (not("PlanProtocol" in planResult) or planResult.PlanProtocol == "v1") and ("PlanGcsUri" in planResult) and not("PlanV2ManifestGcsUri" in planResult) and not("PlanV2ArtifactGcsPrefix" in planResult)}
|
|
106
|
+
next: captureChunkCount
|
|
107
|
+
- condition: ${planProtocol == "v2" and ("PlanProtocol" in planResult) and planResult.PlanProtocol == "v2" and ("PlanV2ManifestGcsUri" in planResult) and ("PlanV2ArtifactGcsPrefix" in planResult) and not("PlanGcsUri" in planResult)}
|
|
108
|
+
next: captureChunkCount
|
|
109
|
+
next: planProtocolLocatorMismatch
|
|
110
|
+
- planProtocolLocatorMismatch:
|
|
111
|
+
raise:
|
|
112
|
+
code: PLAN_PROTOCOL_LOCATOR_MISMATCH
|
|
113
|
+
message: "Plan response did not match the selected protocol's disjoint locator contract."
|
|
114
|
+
- captureChunkCount:
|
|
53
115
|
assign:
|
|
54
|
-
- planResult: ${planResp.body}
|
|
55
116
|
- chunkCount: ${planResult.ChunkCount}
|
|
56
117
|
|
|
57
118
|
# ── BuildChunkList + AssertChunkCount ──────────────────────────────────────
|
|
@@ -98,7 +159,12 @@ main:
|
|
|
98
159
|
value: idx
|
|
99
160
|
in: ${chunkIndexes}
|
|
100
161
|
steps:
|
|
101
|
-
-
|
|
162
|
+
- selectChunkProtocol:
|
|
163
|
+
switch:
|
|
164
|
+
- condition: ${planProtocol == "v2"}
|
|
165
|
+
next: renderOneChunkV2
|
|
166
|
+
next: renderOneChunkV1
|
|
167
|
+
- renderOneChunkV1:
|
|
102
168
|
try:
|
|
103
169
|
call: http.post
|
|
104
170
|
args:
|
|
@@ -106,8 +172,10 @@ main:
|
|
|
106
172
|
timeout: 1800
|
|
107
173
|
auth:
|
|
108
174
|
type: OIDC
|
|
175
|
+
audience: ${serviceUrl}
|
|
109
176
|
body:
|
|
110
177
|
Action: renderChunk
|
|
178
|
+
PlanProtocol: v1
|
|
111
179
|
ChunkIndex: ${idx}
|
|
112
180
|
PlanGcsUri: ${planResult.PlanGcsUri}
|
|
113
181
|
PlanHash: ${planResult.PlanHash}
|
|
@@ -121,13 +189,46 @@ main:
|
|
|
121
189
|
initial_delay: 2
|
|
122
190
|
max_delay: 60
|
|
123
191
|
multiplier: 2
|
|
192
|
+
next: storeChunk
|
|
193
|
+
- renderOneChunkV2:
|
|
194
|
+
try:
|
|
195
|
+
call: http.post
|
|
196
|
+
args:
|
|
197
|
+
url: ${serviceUrl}
|
|
198
|
+
timeout: 1800
|
|
199
|
+
auth:
|
|
200
|
+
type: OIDC
|
|
201
|
+
audience: ${serviceUrl}
|
|
202
|
+
body:
|
|
203
|
+
Action: renderChunk
|
|
204
|
+
PlanProtocol: v2
|
|
205
|
+
ChunkIndex: ${idx}
|
|
206
|
+
PlanV2ManifestGcsUri: ${planResult.PlanV2ManifestGcsUri}
|
|
207
|
+
PlanV2ArtifactGcsPrefix: ${planResult.PlanV2ArtifactGcsPrefix}
|
|
208
|
+
PlanHash: ${planResult.PlanHash}
|
|
209
|
+
ChunkOutputGcsPrefix: ${planOutputGcsPrefix}
|
|
210
|
+
Format: ${planResult.Format}
|
|
211
|
+
result: chunkResp
|
|
212
|
+
retry:
|
|
213
|
+
predicate: ${retryable}
|
|
214
|
+
max_retries: 4
|
|
215
|
+
backoff:
|
|
216
|
+
initial_delay: 2
|
|
217
|
+
max_delay: 60
|
|
218
|
+
multiplier: 2
|
|
219
|
+
next: storeChunk
|
|
124
220
|
- storeChunk:
|
|
125
221
|
assign:
|
|
126
222
|
- chunkUris[idx]: ${chunkResp.body.ChunkGcsUri}
|
|
127
223
|
- chunkResults[idx]: ${chunkResp.body}
|
|
128
224
|
|
|
129
225
|
# ── Assemble (Activity C) ──────────────────────────────────────────────────
|
|
130
|
-
-
|
|
226
|
+
- selectAssembleProtocol:
|
|
227
|
+
switch:
|
|
228
|
+
- condition: ${planProtocol == "v2"}
|
|
229
|
+
next: assembleV2
|
|
230
|
+
next: assembleV1
|
|
231
|
+
- assembleV1:
|
|
131
232
|
try:
|
|
132
233
|
call: http.post
|
|
133
234
|
args:
|
|
@@ -135,8 +236,10 @@ main:
|
|
|
135
236
|
timeout: 1800
|
|
136
237
|
auth:
|
|
137
238
|
type: OIDC
|
|
239
|
+
audience: ${serviceUrl}
|
|
138
240
|
body:
|
|
139
241
|
Action: assemble
|
|
242
|
+
PlanProtocol: v1
|
|
140
243
|
PlanGcsUri: ${planResult.PlanGcsUri}
|
|
141
244
|
ChunkGcsUris: ${chunkUris}
|
|
142
245
|
AudioGcsUri: ${planResult.AudioGcsUri}
|
|
@@ -154,6 +257,38 @@ main:
|
|
|
154
257
|
initial_delay: 2
|
|
155
258
|
max_delay: 60
|
|
156
259
|
multiplier: 2
|
|
260
|
+
next: done
|
|
261
|
+
- assembleV2:
|
|
262
|
+
try:
|
|
263
|
+
call: http.post
|
|
264
|
+
args:
|
|
265
|
+
url: ${serviceUrl}
|
|
266
|
+
timeout: 1800
|
|
267
|
+
auth:
|
|
268
|
+
type: OIDC
|
|
269
|
+
audience: ${serviceUrl}
|
|
270
|
+
body:
|
|
271
|
+
Action: assemble
|
|
272
|
+
PlanProtocol: v2
|
|
273
|
+
PlanV2ManifestGcsUri: ${planResult.PlanV2ManifestGcsUri}
|
|
274
|
+
PlanV2ArtifactGcsPrefix: ${planResult.PlanV2ArtifactGcsPrefix}
|
|
275
|
+
PlanHash: ${planResult.PlanHash}
|
|
276
|
+
ChunkGcsUris: ${chunkUris}
|
|
277
|
+
# Audio is an assembler-scoped v2 artifact and is materialized
|
|
278
|
+
# from the manifest, never carried through a v1 AudioGcsUri.
|
|
279
|
+
AudioGcsUri: null
|
|
280
|
+
OutputGcsUri: ${outputGcsUri}
|
|
281
|
+
Format: ${planResult.Format}
|
|
282
|
+
Cfr: ${("cfr" in config) and config.cfr}
|
|
283
|
+
result: assembleResp
|
|
284
|
+
retry:
|
|
285
|
+
predicate: ${retryable}
|
|
286
|
+
max_retries: 4
|
|
287
|
+
backoff:
|
|
288
|
+
initial_delay: 2
|
|
289
|
+
max_delay: 60
|
|
290
|
+
multiplier: 2
|
|
291
|
+
next: done
|
|
157
292
|
|
|
158
293
|
- done:
|
|
159
294
|
return:
|
|
@@ -161,9 +296,11 @@ main:
|
|
|
161
296
|
Chunks: ${chunkResults}
|
|
162
297
|
Assemble: ${assembleResp.body}
|
|
163
298
|
|
|
164
|
-
# Retry predicate: retry transient/server failures (
|
|
165
|
-
# handler's non-retryable 400s (bad
|
|
166
|
-
# format, …).
|
|
299
|
+
# Retry predicate: retry transient/server failures (403 from Cloud Run IAM
|
|
300
|
+
# propagation, 429, and 5xx), never the handler's non-retryable 400s (bad
|
|
301
|
+
# input, plan-hash mismatch, unsupported format, …). The handler does not emit
|
|
302
|
+
# 403, so that status is always from Cloud Run's authentication edge.
|
|
303
|
+
# Connection / timeout errors carry no `.code`; retry those too.
|
|
167
304
|
retryable:
|
|
168
305
|
params: [e]
|
|
169
306
|
steps:
|
|
@@ -173,6 +310,8 @@ retryable:
|
|
|
173
310
|
return: true
|
|
174
311
|
- condition: ${e.code == 429}
|
|
175
312
|
return: true
|
|
313
|
+
- condition: ${e.code == 403}
|
|
314
|
+
return: true
|
|
176
315
|
- condition: ${e.code >= 500 and e.code < 600}
|
|
177
316
|
return: true
|
|
178
317
|
- nonRetryable:
|