@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.
@@ -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
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@faable/faable",
3
- "version": "1.15.0",
3
+ "version": "1.15.1",
4
4
  "main": "dist/index.js",
5
5
  "license": "MIT",
6
6
  "author": "Marc Pomar <marc@faable.com>",