servyx-cli 0.1.9 → 0.1.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.
- package/package.json +1 -1
- package/src/commands/deploy.js +3 -36
- package/src/lib/api.js +9 -10
package/package.json
CHANGED
package/src/commands/deploy.js
CHANGED
|
@@ -5,23 +5,11 @@ import { loadProjectConfig, loadServyxIgnore } from '../lib/project.js';
|
|
|
5
5
|
import { rsyncDeploy, sshPreflight, DEFAULT_RSYNC_EXCLUDES, preserveServerDotfiles, ensureRemoteDir, verifyRemoteStagingDir } from '../lib/rsync.js';
|
|
6
6
|
|
|
7
7
|
const TERMINAL_STATUSES = new Set(['success', 'failure', 'cancelled']);
|
|
8
|
-
const MIN_POLL_MS = 3000;
|
|
9
|
-
const MAX_POLL_MS = 10000;
|
|
10
8
|
|
|
11
9
|
function sleep(ms) {
|
|
12
10
|
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
13
11
|
}
|
|
14
12
|
|
|
15
|
-
function deploymentSnapshot(deployment) {
|
|
16
|
-
return [
|
|
17
|
-
deployment.status,
|
|
18
|
-
deployment.phase,
|
|
19
|
-
deployment.percent,
|
|
20
|
-
deployment.message,
|
|
21
|
-
deployment.error_message,
|
|
22
|
-
].join('|');
|
|
23
|
-
}
|
|
24
|
-
|
|
25
13
|
function formatDeploymentLine(deployment) {
|
|
26
14
|
const pct = deployment.percent != null ? `${deployment.percent}%` : '';
|
|
27
15
|
const phase = deployment.phase || deployment.status || 'unknown';
|
|
@@ -161,36 +149,15 @@ export async function runDeploy(options = {}) {
|
|
|
161
149
|
|
|
162
150
|
console.log(pc.dim(`Deployment ID: ${deploymentId}`));
|
|
163
151
|
|
|
164
|
-
let pollIntervalMs = MIN_POLL_MS;
|
|
165
|
-
let lastSnapshot = null;
|
|
166
|
-
|
|
167
152
|
while (true) {
|
|
168
|
-
|
|
169
|
-
try {
|
|
170
|
-
statusResult = await getDeployment(deploymentId);
|
|
171
|
-
pollIntervalMs = Math.min(MAX_POLL_MS, pollIntervalMs + 500);
|
|
172
|
-
} catch (err) {
|
|
173
|
-
if (err.status === 429 || err.code === 'RATE_LIMITED') {
|
|
174
|
-
const retryMs = (err.retryAfterSeconds || Math.ceil(pollIntervalMs / 1000)) * 1000;
|
|
175
|
-
pollIntervalMs = Math.min(MAX_POLL_MS * 2, Math.max(retryMs, pollIntervalMs * 2));
|
|
176
|
-
console.log(pc.yellow(`Rate limited — retrying in ${Math.ceil(pollIntervalMs / 1000)}s...`));
|
|
177
|
-
await sleep(pollIntervalMs);
|
|
178
|
-
continue;
|
|
179
|
-
}
|
|
180
|
-
throw err;
|
|
181
|
-
}
|
|
182
|
-
|
|
153
|
+
const statusResult = await getDeployment(appId, deploymentId);
|
|
183
154
|
const current = statusResult?.data?.deployment;
|
|
184
155
|
if (!current) {
|
|
185
156
|
console.error(pc.red('Deployment not found while polling.'));
|
|
186
157
|
process.exit(1);
|
|
187
158
|
}
|
|
188
159
|
|
|
189
|
-
|
|
190
|
-
if (snapshot !== lastSnapshot) {
|
|
191
|
-
console.log(formatDeploymentLine(current));
|
|
192
|
-
lastSnapshot = snapshot;
|
|
193
|
-
}
|
|
160
|
+
console.log(formatDeploymentLine(current));
|
|
194
161
|
|
|
195
162
|
if (TERMINAL_STATUSES.has(current.status)) {
|
|
196
163
|
if (current.status === 'success') {
|
|
@@ -205,6 +172,6 @@ export async function runDeploy(options = {}) {
|
|
|
205
172
|
process.exit(1);
|
|
206
173
|
}
|
|
207
174
|
|
|
208
|
-
await sleep(
|
|
175
|
+
await sleep(2000);
|
|
209
176
|
}
|
|
210
177
|
}
|
package/src/lib/api.js
CHANGED
|
@@ -30,17 +30,16 @@ function unwrap(response) {
|
|
|
30
30
|
if (response.status >= 200 && response.status < 300) {
|
|
31
31
|
return response.data;
|
|
32
32
|
}
|
|
33
|
-
|
|
33
|
+
|
|
34
|
+
const isHtml = typeof response.data === 'string' && response.data.includes('<html');
|
|
35
|
+
const message = isHtml
|
|
36
|
+
? `API returned ${response.status} (expected JSON). Check SERVYX_API_URL / cli-service routing.`
|
|
37
|
+
: (response.data?.error || response.data?.message || response.statusText || 'Request failed');
|
|
38
|
+
|
|
39
|
+
const err = new Error(message);
|
|
34
40
|
err.status = response.status;
|
|
35
41
|
err.code = response.data?.code;
|
|
36
42
|
err.data = response.data;
|
|
37
|
-
const retryAfter = response.headers?.['retry-after'];
|
|
38
|
-
if (retryAfter) {
|
|
39
|
-
const seconds = Number.parseInt(retryAfter, 10);
|
|
40
|
-
if (!Number.isNaN(seconds)) {
|
|
41
|
-
err.retryAfterSeconds = seconds;
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
43
|
throw err;
|
|
45
44
|
}
|
|
46
45
|
|
|
@@ -73,9 +72,9 @@ export async function startDeployment(appId, message, { withEnv = false } = {})
|
|
|
73
72
|
}
|
|
74
73
|
}
|
|
75
74
|
|
|
76
|
-
export async function getDeployment(deploymentId) {
|
|
75
|
+
export async function getDeployment(appId, deploymentId) {
|
|
77
76
|
const client = createClient();
|
|
78
|
-
return unwrap(await client.get(`/deployments/${deploymentId}`));
|
|
77
|
+
return unwrap(await client.get(`/apps/${appId}/deployments/${deploymentId}`));
|
|
79
78
|
}
|
|
80
79
|
|
|
81
80
|
export async function listAppDeployments(appId, limit = 10) {
|