@zuplo/cli 1.21.0 → 1.23.0
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/cmds/deploy.js
CHANGED
|
@@ -12,7 +12,6 @@ export default {
|
|
|
12
12
|
describe: "The API Key from Zuplo",
|
|
13
13
|
envVar: "API_KEY",
|
|
14
14
|
})
|
|
15
|
-
.demandOption(["api-key"])
|
|
16
15
|
.option("dir", {
|
|
17
16
|
type: "string",
|
|
18
17
|
describe: "The directory containing your zup",
|
|
@@ -20,6 +19,13 @@ export default {
|
|
|
20
19
|
normalize: true,
|
|
21
20
|
hidden: true,
|
|
22
21
|
})
|
|
22
|
+
.option("verify-remote", {
|
|
23
|
+
type: "boolean",
|
|
24
|
+
describe: "Verify that this Git repository matches the one configured on Zuplo. Use --no-verify-remote to disable.",
|
|
25
|
+
default: true,
|
|
26
|
+
})
|
|
27
|
+
.demandOption(["api-key"])
|
|
28
|
+
.boolean("verify-remote")
|
|
23
29
|
.check(async (argv) => {
|
|
24
30
|
return await new YargsChecker(validDeployDirectoryValidator).check(argv.dir);
|
|
25
31
|
})
|
package/dist/deploy/archive.js
CHANGED
|
@@ -8,11 +8,12 @@ import * as temp from "temp";
|
|
|
8
8
|
import { DEPLOYER_METADATA_FILE } from "../common/constants.js";
|
|
9
9
|
import { logger } from "../common/logger.js";
|
|
10
10
|
export const ARCHIVE_EXTENSION = ".tar.gz";
|
|
11
|
-
export async function archive(
|
|
11
|
+
export async function archive(argv) {
|
|
12
12
|
const tarball = temp.path({ suffix: ARCHIVE_EXTENSION });
|
|
13
|
+
const dir = argv.dir;
|
|
13
14
|
const ignoreFn = createIgnoreFunction(dir);
|
|
14
15
|
const normalizedDir = join(relative(process.cwd(), dir));
|
|
15
|
-
const metadata = await prepareDeployerMetadata(
|
|
16
|
+
const metadata = await prepareDeployerMetadata(argv);
|
|
16
17
|
await tar.create({
|
|
17
18
|
gzip: true,
|
|
18
19
|
file: tarball,
|
|
@@ -59,12 +60,14 @@ function createIgnoreFunction(normalizedDir) {
|
|
|
59
60
|
return baseIgnore.add("node_modules/");
|
|
60
61
|
}
|
|
61
62
|
}
|
|
62
|
-
async function prepareDeployerMetadata(
|
|
63
|
-
const
|
|
63
|
+
async function prepareDeployerMetadata(argv) {
|
|
64
|
+
const dir = argv.dir;
|
|
65
|
+
const metadata = await generateMetadata(argv);
|
|
64
66
|
await writeGeneratedMetadata(dir, metadata);
|
|
65
67
|
return metadata;
|
|
66
68
|
}
|
|
67
|
-
async function generateMetadata(
|
|
69
|
+
async function generateMetadata(argv) {
|
|
70
|
+
const dir = argv.dir;
|
|
68
71
|
const git = simpleGit({ baseDir: dir });
|
|
69
72
|
const status = await git.status();
|
|
70
73
|
if (!status.current) {
|
|
@@ -73,10 +76,12 @@ async function generateMetadata(dir) {
|
|
|
73
76
|
const branch = status.current.trim();
|
|
74
77
|
const sha = (await git.revparse(["HEAD"])).trim();
|
|
75
78
|
const repoUrl = (await git.listRemote(["--get-url"])).trim();
|
|
79
|
+
const verifyRemote = argv["verify-remote"];
|
|
76
80
|
return {
|
|
77
81
|
branch,
|
|
78
82
|
repoUrl,
|
|
79
83
|
sha,
|
|
84
|
+
verifyRemote,
|
|
80
85
|
};
|
|
81
86
|
}
|
|
82
87
|
async function writeGeneratedMetadata(dir, metadata) {
|
package/dist/deploy/handler.js
CHANGED
|
@@ -6,7 +6,7 @@ import { archive, ARCHIVE_EXTENSION } from "./archive.js";
|
|
|
6
6
|
import { upload } from "./file-upload.js";
|
|
7
7
|
import { pollDeployment } from "./poll-deployment.js";
|
|
8
8
|
export async function deploy(argv) {
|
|
9
|
-
const archiveMetadata = await archive(argv
|
|
9
|
+
const archiveMetadata = await archive(argv);
|
|
10
10
|
logger.info(`Tarball created locally at ${archiveMetadata}`);
|
|
11
11
|
const whoAmIResponse = await fetch(`${settings.ZUPLO_DEVELOPER_API_ENDPOINT}/v1/who-am-i`, {
|
|
12
12
|
method: "GET",
|
|
@@ -28,12 +28,13 @@ export async function deploy(argv) {
|
|
|
28
28
|
if (uploadResponse.ok) {
|
|
29
29
|
printDiagnosticsToConsole(`Deploying the current branch ${archiveMetadata.metadata.branch} to project ${project} on account ${account}...`);
|
|
30
30
|
const fileId = parse(new URL(uploadUrl).pathname).base.replace(ARCHIVE_EXTENSION, "");
|
|
31
|
-
const { url, buildResult } = await pollDeployment(argv, fileId, account, project);
|
|
31
|
+
const { url, steps, buildResult } = await pollDeployment(argv, fileId, account, project);
|
|
32
32
|
if (url) {
|
|
33
33
|
printResultToConsoleAndExitGracefully(`Deployed to ${url}`);
|
|
34
34
|
}
|
|
35
35
|
else {
|
|
36
|
-
|
|
36
|
+
const diagnostics = buildResult ?? steps;
|
|
37
|
+
printCriticalFailureToConsoleAndExit(`Failed to deploy the current branch ${archiveMetadata.metadata.branch} to project ${project} on account ${account}. Here's the diagnostics: ${JSON.stringify(diagnostics, null, 2)}`);
|
|
37
38
|
}
|
|
38
39
|
}
|
|
39
40
|
else {
|
|
@@ -5,6 +5,8 @@ function wait(duration = settings.POLL_INTERVAL) {
|
|
|
5
5
|
return new Promise((resolve) => setTimeout(resolve, duration));
|
|
6
6
|
}
|
|
7
7
|
export async function pollDeployment(argv, fileId, account, project) {
|
|
8
|
+
const MAX_RETRY_ATTEMPTS_FOR_SERVER_UPDATES = 5;
|
|
9
|
+
let CURRENT_RETRY_ATTEMPTS_FOR_SERVER_UPDATES = 0;
|
|
8
10
|
for (let pollRetry = 0; pollRetry < settings.MAX_POLL_RETRIES; pollRetry++) {
|
|
9
11
|
printDiagnosticsToConsole(`Polling for deployment status... (${pollRetry}/${settings.MAX_POLL_RETRIES})`);
|
|
10
12
|
const response = await fetch(`${settings.ZUPLO_DEVELOPER_API_ENDPOINT}/v1/accounts/${account}/projects/${project}/deployment-status/${fileId}`, {
|
|
@@ -15,7 +17,7 @@ export async function pollDeployment(argv, fileId, account, project) {
|
|
|
15
17
|
});
|
|
16
18
|
if (response.ok) {
|
|
17
19
|
const rawJSON = await response.text();
|
|
18
|
-
const { status, url, buildResult } = JSON.parse(rawJSON);
|
|
20
|
+
const { status, url, steps, buildResult } = JSON.parse(rawJSON);
|
|
19
21
|
switch (status) {
|
|
20
22
|
case "IN_PROGRESS":
|
|
21
23
|
await wait();
|
|
@@ -25,6 +27,7 @@ export async function pollDeployment(argv, fileId, account, project) {
|
|
|
25
27
|
if (zupResponse.ok) {
|
|
26
28
|
return {
|
|
27
29
|
url,
|
|
30
|
+
steps,
|
|
28
31
|
buildResult,
|
|
29
32
|
};
|
|
30
33
|
}
|
|
@@ -33,6 +36,7 @@ export async function pollDeployment(argv, fileId, account, project) {
|
|
|
33
36
|
}
|
|
34
37
|
case "ERROR":
|
|
35
38
|
return {
|
|
39
|
+
steps,
|
|
36
40
|
buildResult,
|
|
37
41
|
};
|
|
38
42
|
}
|
|
@@ -41,6 +45,13 @@ export async function pollDeployment(argv, fileId, account, project) {
|
|
|
41
45
|
await wait();
|
|
42
46
|
continue;
|
|
43
47
|
}
|
|
48
|
+
else if (response.status === 500 &&
|
|
49
|
+
CURRENT_RETRY_ATTEMPTS_FOR_SERVER_UPDATES <
|
|
50
|
+
MAX_RETRY_ATTEMPTS_FOR_SERVER_UPDATES) {
|
|
51
|
+
CURRENT_RETRY_ATTEMPTS_FOR_SERVER_UPDATES++;
|
|
52
|
+
await wait();
|
|
53
|
+
continue;
|
|
54
|
+
}
|
|
44
55
|
else {
|
|
45
56
|
logger.error(`Unexpected error from server while polling for deployment: ${response.status} ${response.statusText} ${await response.text()}`);
|
|
46
57
|
throw new Error(`Unexpected response from server while polling for deployment: ${response.status} ${response.statusText}`);
|