@shopify/oxygen-cli 1.12.3-unstable.202309251429.0 → 2.0.0
Sign up to get free protection for your applications and to get access to all the features.
- package/README.md +12 -2
- package/dist/commands/oxygen/deploy.d.ts +2 -2
- package/dist/commands/oxygen/deploy.js +10 -10
- package/dist/deploy/index.js +5 -5
- package/dist/deploy/types.d.ts +7 -7
- package/dist/deploy/types.js +2 -2
- package/dist/deploy/{health-check.d.ts → verify-deployment.d.ts} +3 -3
- package/dist/deploy/{health-check.js → verify-deployment.js} +15 -13
- package/dist/utils/test-helper.js +2 -2
- package/dist/utils/utils.js +1 -1
- package/oclif.manifest.json +9 -10
- package/package.json +2 -2
package/README.md
CHANGED
@@ -42,8 +42,8 @@ oxygen:deploy [options]
|
|
42
42
|
- -o, --workerOnly: Worker only deployment.
|
43
43
|
- -s, --skipBuild: Skip running build command.
|
44
44
|
- -b, --buildCommand <buildCommand>: Build command (default: `yarn build`).
|
45
|
-
- -
|
46
|
-
- -d, --
|
45
|
+
- -v, --skipVerification: skip the worker deployment verification step
|
46
|
+
- -d, --verificationMaxDuration: The maximum duration (in seconds) that the deployment verification is allowed to run before it is considered failed. Accepts values between 10 and 300.
|
47
47
|
- --publicDeployment: set the deployment to be publicly accessible.
|
48
48
|
- --metadataDescription <metadataDescription>: A brief description of the deployment, typically the commit message associated with the changes being deployed.
|
49
49
|
- --metadataUrl <metadataUrl>: URL that links to the deployment.
|
@@ -62,6 +62,16 @@ This command will deploy your Oxygen project to the staging environment with the
|
|
62
62
|
|
63
63
|
The `environmentTag` option and the `metadata` options serve as overrides for values that can be retrieved from supported CI environments, see the section on environment variables below.
|
64
64
|
|
65
|
+
### Deployment Verification
|
66
|
+
|
67
|
+
By default, `oxygen-cli` performs a verification step to ensure the worker deployment process has completed successfully. This step attempts to confirm the successful deployment of your worker. However, please note that this verification step does not dispatch requests to the worker, so it does not validate that the worker is correctly handling requests.
|
68
|
+
|
69
|
+
If you wish to skip this verification step, you can use the` --skipVerification` command flag.
|
70
|
+
|
71
|
+
The verification step runs for a default duration of 180 seconds. If the verification process does not complete successfully within this time, the deployment is considered unsuccessful. However, you can customize this duration using the --verificationMaxDuration command flag. This flag allows you to specify a maximum duration between 10 and 300 seconds for the verification process. If the verification process does not complete within your specified duration, the deployment will be considered unsuccessful.
|
72
|
+
|
73
|
+
In the case of the deployment verification failing, we recommend checking your Shopify Admin to confirm the status of the deployment.
|
74
|
+
|
65
75
|
## Environment variables
|
66
76
|
|
67
77
|
The Oxygen deployment token can be specified with the `token` option. Alternatively, you can use the environment variable `OXYGEN_DEPLOYMENT_TOKEN` for this. In CI environments this is recommended. For example, when using CircleCI you can define a custom environment variable in your project settings which holds the token. The `OXYGEN_DEPLOYMENT_TOKEN` can then be populated with this variable's value in your `config.yml` file:
|
@@ -8,11 +8,11 @@ declare class Deploy extends Command {
|
|
8
8
|
assetsFolder: _oclif_core_lib_interfaces_parser_js.OptionFlag<string, _oclif_core_lib_interfaces_parser_js.CustomOptions>;
|
9
9
|
buildCommand: _oclif_core_lib_interfaces_parser_js.OptionFlag<string, _oclif_core_lib_interfaces_parser_js.CustomOptions>;
|
10
10
|
environmentTag: _oclif_core_lib_interfaces_parser_js.OptionFlag<string | undefined, _oclif_core_lib_interfaces_parser_js.CustomOptions>;
|
11
|
-
|
11
|
+
verificationMaxDuration: _oclif_core_lib_interfaces_parser_js.OptionFlag<number, _oclif_core_lib_interfaces_parser_js.CustomOptions>;
|
12
12
|
path: _oclif_core_lib_interfaces_parser_js.OptionFlag<string, _oclif_core_lib_interfaces_parser_js.CustomOptions>;
|
13
13
|
publicDeployment: _oclif_core_lib_interfaces_parser_js.BooleanFlag<boolean>;
|
14
14
|
skipBuild: _oclif_core_lib_interfaces_parser_js.BooleanFlag<boolean>;
|
15
|
-
|
15
|
+
skipVerification: _oclif_core_lib_interfaces_parser_js.BooleanFlag<boolean>;
|
16
16
|
token: _oclif_core_lib_interfaces_parser_js.OptionFlag<string, _oclif_core_lib_interfaces_parser_js.CustomOptions>;
|
17
17
|
workerFolder: _oclif_core_lib_interfaces_parser_js.OptionFlag<string, _oclif_core_lib_interfaces_parser_js.CustomOptions>;
|
18
18
|
workerOnly: _oclif_core_lib_interfaces_parser_js.BooleanFlag<boolean>;
|
@@ -3,7 +3,7 @@ import { consoleError } from '@shopify/cli-kit/node/output';
|
|
3
3
|
import { normalizePath } from '@shopify/cli-kit/node/path';
|
4
4
|
import { createDeploy } from '../../deploy/index.js';
|
5
5
|
import { deployDefaults, parseToken, verifyConfig, getBuildCommandFromLockFile } from '../../utils/utils.js';
|
6
|
-
import {
|
6
|
+
import { VerificationError } from '../../deploy/types.js';
|
7
7
|
|
8
8
|
class Deploy extends Command {
|
9
9
|
static description = "Creates a deployment to Oxygen";
|
@@ -30,13 +30,13 @@ class Deploy extends Command {
|
|
30
30
|
description: "Tag of the environment to deploy to",
|
31
31
|
required: false
|
32
32
|
}),
|
33
|
-
|
33
|
+
verificationMaxDuration: Flags.integer({
|
34
34
|
char: "d",
|
35
|
-
description: "the maximum duration (in seconds) that the
|
35
|
+
description: "the maximum duration (in seconds) that the deployment verification step is allowed to run before it is considered failed.",
|
36
36
|
min: 10,
|
37
37
|
max: 300,
|
38
38
|
required: false,
|
39
|
-
default: deployDefaults.
|
39
|
+
default: deployDefaults.verificationMaxDurationDefault
|
40
40
|
}),
|
41
41
|
path: Flags.string({
|
42
42
|
char: "p",
|
@@ -56,9 +56,9 @@ class Deploy extends Command {
|
|
56
56
|
required: false,
|
57
57
|
default: false
|
58
58
|
}),
|
59
|
-
|
60
|
-
char: "
|
61
|
-
description: "Skip running deployment
|
59
|
+
skipVerification: Flags.boolean({
|
60
|
+
char: "v",
|
61
|
+
description: "Skip running deployment verification step",
|
62
62
|
required: false,
|
63
63
|
default: false
|
64
64
|
}),
|
@@ -115,7 +115,7 @@ class Deploy extends Command {
|
|
115
115
|
deploymentToken: parseToken(flags.token),
|
116
116
|
environmentTag: flags.environmentTag,
|
117
117
|
deploymentUrl,
|
118
|
-
|
118
|
+
verificationMaxDuration: flags.verificationMaxDuration,
|
119
119
|
metadata: {
|
120
120
|
description: flags.metadataDescription,
|
121
121
|
url: flags.metadataUrl,
|
@@ -125,7 +125,7 @@ class Deploy extends Command {
|
|
125
125
|
publicDeployment: flags.publicDeployment,
|
126
126
|
rootPath: normalizePath(flags.path),
|
127
127
|
skipBuild: flags.skipBuild,
|
128
|
-
|
128
|
+
skipVerification: flags.skipVerification,
|
129
129
|
workerDir: normalizePath(flags.workerFolder),
|
130
130
|
workerOnly: flags.workerOnly
|
131
131
|
};
|
@@ -137,7 +137,7 @@ class Deploy extends Command {
|
|
137
137
|
} catch (error) {
|
138
138
|
if (!(error instanceof Error)) {
|
139
139
|
consoleError(error);
|
140
|
-
} else if (!(error instanceof
|
140
|
+
} else if (!(error instanceof VerificationError)) {
|
141
141
|
consoleError(error.message);
|
142
142
|
}
|
143
143
|
this.exit(1);
|
package/dist/deploy/index.js
CHANGED
@@ -6,10 +6,10 @@ import { buildCancel } from './build-cancel.js';
|
|
6
6
|
import { getUploadFiles } from './get-upload-files.js';
|
7
7
|
import { deploymentInitiate } from './deployment-initiate.js';
|
8
8
|
import { deploymentComplete } from './deployment-complete.js';
|
9
|
-
import {
|
9
|
+
import { verifyDeployment } from './verify-deployment.js';
|
10
10
|
import { deploymentCancel } from './deployment-cancel.js';
|
11
11
|
import { uploadFiles } from './upload-files.js';
|
12
|
-
import {
|
12
|
+
import { VerificationError } from './types.js';
|
13
13
|
import { buildProject } from './build-project.js';
|
14
14
|
import { getMetadata, createLabels, getEnvironmentInput } from './metadata.js';
|
15
15
|
|
@@ -59,8 +59,8 @@ async function createDeploy(options) {
|
|
59
59
|
config,
|
60
60
|
deployment.deployment.id
|
61
61
|
);
|
62
|
-
if (!config.
|
63
|
-
await
|
62
|
+
if (!config.skipVerification) {
|
63
|
+
await verifyDeployment({
|
64
64
|
config,
|
65
65
|
url: deploymentCompleteOp.deployment.url,
|
66
66
|
logger,
|
@@ -82,7 +82,7 @@ ${urlMessage} preview URL: ${deploymentCompleteOp.deployment.url}`,
|
|
82
82
|
console.error("Unknown error", error);
|
83
83
|
return Promise.reject(new Error("Unknown error"));
|
84
84
|
}
|
85
|
-
if (error instanceof
|
85
|
+
if (error instanceof VerificationError) {
|
86
86
|
outputWarn(error.message, logger);
|
87
87
|
} else if (build.id && !buildCompleted) {
|
88
88
|
outputWarn(
|
package/dist/deploy/types.d.ts
CHANGED
@@ -7,9 +7,9 @@ interface ClientError extends Error {
|
|
7
7
|
}
|
8
8
|
interface DeploymentHooks {
|
9
9
|
buildFunction?: (urlPath?: string) => Promise<void>;
|
10
|
-
|
11
|
-
|
12
|
-
|
10
|
+
onVerificationStart?: () => void;
|
11
|
+
onVerificationComplete?: () => void;
|
12
|
+
onVerificationError?: (error: Error) => void;
|
13
13
|
onUploadFilesStart?: () => void;
|
14
14
|
onUploadFilesError?: (error: Error) => void;
|
15
15
|
onUploadFilesComplete?: () => void;
|
@@ -20,7 +20,6 @@ interface DeploymentConfig {
|
|
20
20
|
deploymentToken: DeploymentToken;
|
21
21
|
deploymentUrl: string;
|
22
22
|
environmentTag?: string;
|
23
|
-
healthCheckMaxDuration: number;
|
24
23
|
metadata: {
|
25
24
|
description?: string;
|
26
25
|
user?: string;
|
@@ -30,7 +29,8 @@ interface DeploymentConfig {
|
|
30
29
|
publicDeployment: boolean;
|
31
30
|
rootPath?: string;
|
32
31
|
skipBuild: boolean;
|
33
|
-
|
32
|
+
skipVerification: boolean;
|
33
|
+
verificationMaxDuration: number;
|
34
34
|
workerDir?: string;
|
35
35
|
workerOnly: boolean;
|
36
36
|
}
|
@@ -61,7 +61,7 @@ declare enum FileType {
|
|
61
61
|
interface OxygenError {
|
62
62
|
message: string;
|
63
63
|
}
|
64
|
-
declare class
|
64
|
+
declare class VerificationError extends Error {
|
65
65
|
}
|
66
66
|
|
67
|
-
export { Build, ClientError, DeploymentConfig, DeploymentHooks, DeploymentManifestFile, DeploymentToken, EnvironmentInput, FileType,
|
67
|
+
export { Build, ClientError, DeploymentConfig, DeploymentHooks, DeploymentManifestFile, DeploymentToken, EnvironmentInput, FileType, OxygenError, VerificationError };
|
package/dist/deploy/types.js
CHANGED
@@ -3,7 +3,7 @@ var FileType = /* @__PURE__ */ ((FileType2) => {
|
|
3
3
|
FileType2["Asset"] = "ASSET";
|
4
4
|
return FileType2;
|
5
5
|
})(FileType || {});
|
6
|
-
class
|
6
|
+
class VerificationError extends Error {
|
7
7
|
}
|
8
8
|
|
9
|
-
export { FileType,
|
9
|
+
export { FileType, VerificationError };
|
@@ -1,12 +1,12 @@
|
|
1
1
|
import { Logger } from '@shopify/cli-kit/node/output';
|
2
2
|
import { DeploymentConfig, DeploymentHooks } from './types.js';
|
3
3
|
|
4
|
-
interface
|
4
|
+
interface VerificationOptions {
|
5
5
|
config: DeploymentConfig;
|
6
6
|
hooks?: DeploymentHooks;
|
7
7
|
logger: Logger;
|
8
8
|
url: string;
|
9
9
|
}
|
10
|
-
declare function
|
10
|
+
declare function verifyDeployment(options: VerificationOptions): Promise<void>;
|
11
11
|
|
12
|
-
export {
|
12
|
+
export { verifyDeployment };
|
@@ -1,14 +1,14 @@
|
|
1
1
|
import { fetch } from '@shopify/cli-kit/node/http';
|
2
2
|
import { outputInfo } from '@shopify/cli-kit/node/output';
|
3
|
-
import {
|
3
|
+
import { VerificationError } from './types.js';
|
4
4
|
|
5
|
-
async function
|
5
|
+
async function verifyDeployment(options) {
|
6
6
|
const { config, url, logger, hooks } = options;
|
7
|
-
hooks?.
|
8
|
-
outputInfo("
|
7
|
+
hooks?.onVerificationStart?.();
|
8
|
+
outputInfo("Verifying worker deployment has been completed...", logger);
|
9
9
|
let attempts = 0;
|
10
10
|
let delay = 0;
|
11
|
-
let
|
11
|
+
let calledVerificationError = false;
|
12
12
|
const startTime = Date.now();
|
13
13
|
const handleInterval = async () => {
|
14
14
|
if (attempts < 10) {
|
@@ -17,11 +17,13 @@ async function healthCheck(options) {
|
|
17
17
|
delay += 5e3;
|
18
18
|
}
|
19
19
|
const elapsedTime = (Date.now() - startTime) / 1e3;
|
20
|
-
if (elapsedTime + delay / 1e3 > config.
|
21
|
-
const error = new
|
22
|
-
|
23
|
-
|
24
|
-
|
20
|
+
if (elapsedTime + delay / 1e3 > config.verificationMaxDuration) {
|
21
|
+
const error = new VerificationError(
|
22
|
+
"Unable to verify worker deployment completion."
|
23
|
+
);
|
24
|
+
if (!calledVerificationError) {
|
25
|
+
calledVerificationError = true;
|
26
|
+
hooks?.onVerificationError?.(error);
|
25
27
|
}
|
26
28
|
throw error;
|
27
29
|
}
|
@@ -33,8 +35,8 @@ async function healthCheck(options) {
|
|
33
35
|
try {
|
34
36
|
const response = await fetch(`${url}/.oxygen/deployment`);
|
35
37
|
if (response.status === 200) {
|
36
|
-
outputInfo("Deployment
|
37
|
-
hooks?.
|
38
|
+
outputInfo("Deployment verification check passed", logger);
|
39
|
+
hooks?.onVerificationComplete?.();
|
38
40
|
return Promise.resolve();
|
39
41
|
}
|
40
42
|
await handleInterval();
|
@@ -45,4 +47,4 @@ async function healthCheck(options) {
|
|
45
47
|
await check();
|
46
48
|
}
|
47
49
|
|
48
|
-
export {
|
50
|
+
export { verifyDeployment };
|
@@ -16,12 +16,12 @@ function createTestConfig(rootFolder) {
|
|
16
16
|
deploymentToken: testToken,
|
17
17
|
environmentTag: "environment",
|
18
18
|
deploymentUrl: "https://localhost:3000",
|
19
|
-
|
19
|
+
verificationMaxDuration: 300,
|
20
20
|
metadata: {},
|
21
21
|
rootPath: rootFolder,
|
22
22
|
publicDeployment: false,
|
23
23
|
skipBuild: false,
|
24
|
-
|
24
|
+
skipVerification: false,
|
25
25
|
workerDir: "/worker/",
|
26
26
|
workerOnly: false
|
27
27
|
};
|
package/dist/utils/utils.js
CHANGED
@@ -6,7 +6,7 @@ import { AbortError } from '@shopify/cli-kit/node/error';
|
|
6
6
|
const deployDefaults = {
|
7
7
|
assetsDirDefault: "dist/client/",
|
8
8
|
buildCommandDefault: "yarn build",
|
9
|
-
|
9
|
+
verificationDurationDefault: 180,
|
10
10
|
maxUploadAttempts: 3,
|
11
11
|
maxResumabeUploadAttempts: 9,
|
12
12
|
workerDirDefault: "dist/worker/"
|
package/oclif.manifest.json
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
{
|
2
|
-
"version": "
|
2
|
+
"version": "2.0.0",
|
3
3
|
"commands": {
|
4
4
|
"oxygen:deploy": {
|
5
5
|
"id": "oxygen:deploy",
|
@@ -37,14 +37,13 @@
|
|
37
37
|
"required": false,
|
38
38
|
"multiple": false
|
39
39
|
},
|
40
|
-
"
|
41
|
-
"name": "
|
40
|
+
"verificationMaxDuration": {
|
41
|
+
"name": "verificationMaxDuration",
|
42
42
|
"type": "option",
|
43
43
|
"char": "d",
|
44
|
-
"description": "the maximum duration (in seconds) that the
|
44
|
+
"description": "the maximum duration (in seconds) that the deployment verification step is allowed to run before it is considered failed.",
|
45
45
|
"required": false,
|
46
|
-
"multiple": false
|
47
|
-
"default": 180
|
46
|
+
"multiple": false
|
48
47
|
},
|
49
48
|
"path": {
|
50
49
|
"name": "path",
|
@@ -70,11 +69,11 @@
|
|
70
69
|
"required": false,
|
71
70
|
"allowNo": false
|
72
71
|
},
|
73
|
-
"
|
74
|
-
"name": "
|
72
|
+
"skipVerification": {
|
73
|
+
"name": "skipVerification",
|
75
74
|
"type": "boolean",
|
76
|
-
"char": "
|
77
|
-
"description": "Skip running deployment
|
75
|
+
"char": "v",
|
76
|
+
"description": "Skip running deployment verification step",
|
78
77
|
"required": false,
|
79
78
|
"allowNo": false
|
80
79
|
},
|
package/package.json
CHANGED
@@ -5,7 +5,7 @@
|
|
5
5
|
"@shopify:registry": "https://registry.npmjs.org"
|
6
6
|
},
|
7
7
|
"license": "MIT",
|
8
|
-
"version": "
|
8
|
+
"version": "2.0.0",
|
9
9
|
"type": "module",
|
10
10
|
"scripts": {
|
11
11
|
"build": "tsup --clean --config ./tsup.config.ts && oclif manifest",
|
@@ -42,7 +42,7 @@
|
|
42
42
|
"@changesets/cli": "^2.26.1",
|
43
43
|
"@shopify/eslint-plugin": "^43.0.0",
|
44
44
|
"@shopify/prettier-config": "^1.1.2",
|
45
|
-
"@types/async": "^3.2.
|
45
|
+
"@types/async": "^3.2.21",
|
46
46
|
"@types/node": "^20.6.3",
|
47
47
|
"eslint": "^8.50.0",
|
48
48
|
"eslint-plugin-prettier": "^5.0.0",
|