@faable/faable 1.15.0 → 1.15.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.
package/dist/api/FaableApi.js
CHANGED
|
@@ -92,6 +92,12 @@ class FaableApi {
|
|
|
92
92
|
image,
|
|
93
93
|
}));
|
|
94
94
|
}
|
|
95
|
+
// Fetch a deployment with its runtime status, so the deploy command can
|
|
96
|
+
// watch for a terminal failure (ERROR/BUILD_ERROR + reason) while polling
|
|
97
|
+
// for promotion — and fail the run fast instead of timing out green.
|
|
98
|
+
async getDeployment(deployment_id) {
|
|
99
|
+
return data(this.client.get(`/deployment/${deployment_id}`));
|
|
100
|
+
}
|
|
95
101
|
// Attach the captured build/deploy output to a deployment. The base client
|
|
96
102
|
// timeout (10s) is too short for a multi-MB body on a slow uplink.
|
|
97
103
|
async uploadDeploymentLogs(deployment_id, body) {
|
|
@@ -112,6 +112,7 @@ const deploy = {
|
|
|
112
112
|
const start = Date.now();
|
|
113
113
|
log.info(`⏳ Waiting for deployment to be promoted...`);
|
|
114
114
|
let promoted = false;
|
|
115
|
+
let failure = null;
|
|
115
116
|
while (Date.now() - start < timeoutMs) {
|
|
116
117
|
await wait(intervalMs);
|
|
117
118
|
try {
|
|
@@ -120,6 +121,16 @@ const deploy = {
|
|
|
120
121
|
promoted = true;
|
|
121
122
|
break;
|
|
122
123
|
}
|
|
124
|
+
// Watch for a terminal runtime failure so we fail fast (and red)
|
|
125
|
+
// instead of timing out green. The controller marks a crash-looping
|
|
126
|
+
// deployment ERROR — with a reason (e.g. a missing module) — within
|
|
127
|
+
// ~1min, long before this 5min promotion timeout.
|
|
128
|
+
const dep = await api.getDeployment(deployment.id);
|
|
129
|
+
const phase = dep.status?.phase;
|
|
130
|
+
if (phase === "ERROR" || phase === "BUILD_ERROR") {
|
|
131
|
+
failure = { phase, reason: dep.status?.reason };
|
|
132
|
+
break;
|
|
133
|
+
}
|
|
123
134
|
}
|
|
124
135
|
catch (_error) {
|
|
125
136
|
// Ignore transient errors while polling and keep waiting
|
|
@@ -129,6 +140,15 @@ const deploy = {
|
|
|
129
140
|
if (promoted) {
|
|
130
141
|
log.info(`🌍 Deployment promoted and live, visit: https://${app.url}`);
|
|
131
142
|
}
|
|
143
|
+
else if (failure) {
|
|
144
|
+
// Fail the command (non-zero exit → red GitHub Action) and surface the
|
|
145
|
+
// reason the controller captured so the user sees WHY without digging.
|
|
146
|
+
log.error(`❌ Deployment failed (${failure.phase}).`);
|
|
147
|
+
if (failure.reason)
|
|
148
|
+
log.error(failure.reason);
|
|
149
|
+
log.error(`Check the logs in the dashboard -> ${dashboard_url}`);
|
|
150
|
+
throw new Error(`Deployment ${deployment.id} failed with phase ${failure.phase}`);
|
|
151
|
+
}
|
|
132
152
|
else {
|
|
133
153
|
log.warn(`⌛ Timed out after 5min waiting for promotion. The deployment is still rolling out, check the dashboard -> ${dashboard_url}`);
|
|
134
154
|
}
|