@shopify/oxygen-cli 1.4.0 → 1.5.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/commands/oxygen/deploy.d.ts +3 -3
- package/dist/commands/oxygen/deploy.js +4 -3
- package/dist/deploy/build-cancel.d.ts +9 -2
- package/dist/deploy/build-cancel.js +4 -3
- package/dist/deploy/build-cancel.test.js +21 -4
- package/dist/deploy/build-initiate.d.ts +9 -2
- package/dist/deploy/build-initiate.js +4 -3
- package/dist/deploy/build-initiate.test.js +19 -8
- package/dist/deploy/build-project.d.ts +7 -2
- package/dist/deploy/build-project.js +34 -19
- package/dist/deploy/build-project.test.js +14 -8
- package/dist/deploy/deployment-cancel.d.ts +9 -2
- package/dist/deploy/deployment-cancel.js +4 -3
- package/dist/deploy/deployment-cancel.test.js +19 -16
- package/dist/deploy/deployment-complete.d.ts +2 -2
- package/dist/deploy/deployment-initiate.d.ts +10 -4
- package/dist/deploy/deployment-initiate.js +4 -3
- package/dist/deploy/deployment-initiate.test.js +26 -10
- package/dist/deploy/get-upload-files.d.ts +2 -2
- package/dist/deploy/index.d.ts +10 -3
- package/dist/deploy/index.js +40 -23
- package/dist/deploy/metadata.d.ts +4 -3
- package/dist/deploy/metadata.js +3 -3
- package/dist/deploy/metadata.test.js +4 -4
- package/dist/deploy/types.d.ts +10 -2
- package/dist/deploy/upload-files.d.ts +9 -2
- package/dist/deploy/upload-files.js +7 -4
- package/dist/deploy/upload-files.test.js +37 -18
- package/dist/utils/test-helper.d.ts +2 -2
- package/dist/utils/test-helper.js +1 -0
- package/dist/utils/utils.d.ts +3 -3
- package/dist/utils/utils.js +0 -5
- package/oclif.manifest.json +2 -2
- package/package.json +3 -3
@@ -1,12 +1,12 @@
|
|
1
1
|
import * as _oclif_core_lib_interfaces_parser_js from '@oclif/core/lib/interfaces/parser.js';
|
2
2
|
import { Command } from '@oclif/core';
|
3
|
-
import {
|
3
|
+
import { DeploymentConfig } from '../../deploy/types.js';
|
4
4
|
|
5
5
|
declare class Deploy extends Command {
|
6
6
|
static description: string;
|
7
7
|
static hidden: boolean;
|
8
8
|
static flags: {
|
9
|
-
token: _oclif_core_lib_interfaces_parser_js.OptionFlag<string
|
9
|
+
token: _oclif_core_lib_interfaces_parser_js.OptionFlag<string, _oclif_core_lib_interfaces_parser_js.CustomOptions>;
|
10
10
|
path: _oclif_core_lib_interfaces_parser_js.OptionFlag<string, _oclif_core_lib_interfaces_parser_js.CustomOptions>;
|
11
11
|
environmentTag: _oclif_core_lib_interfaces_parser_js.OptionFlag<string | undefined, _oclif_core_lib_interfaces_parser_js.CustomOptions>;
|
12
12
|
workerFolder: _oclif_core_lib_interfaces_parser_js.OptionFlag<string, _oclif_core_lib_interfaces_parser_js.CustomOptions>;
|
@@ -22,6 +22,6 @@ declare class Deploy extends Command {
|
|
22
22
|
static hasCustomBuildCommand: boolean;
|
23
23
|
run(): Promise<void>;
|
24
24
|
}
|
25
|
-
declare function runInit(
|
25
|
+
declare function runInit(config: DeploymentConfig): void;
|
26
26
|
|
27
27
|
export { Deploy, runInit };
|
@@ -12,7 +12,7 @@ class Deploy extends Command {
|
|
12
12
|
char: "t",
|
13
13
|
description: "Oxygen deployment token",
|
14
14
|
env: "OXYGEN_DEPLOYMENT_TOKEN",
|
15
|
-
required:
|
15
|
+
required: true
|
16
16
|
}),
|
17
17
|
path: Flags.string({
|
18
18
|
char: "p",
|
@@ -92,6 +92,7 @@ class Deploy extends Command {
|
|
92
92
|
const config = {
|
93
93
|
assetsDir: normalizePath(flags.assetsFolder),
|
94
94
|
buildCommand: flags.buildCommand,
|
95
|
+
buildOutput: true,
|
95
96
|
deploymentToken: parseToken(flags.token),
|
96
97
|
environmentTag: flags.environmentTag,
|
97
98
|
deploymentUrl,
|
@@ -121,8 +122,8 @@ class Deploy extends Command {
|
|
121
122
|
}
|
122
123
|
}
|
123
124
|
}
|
124
|
-
function runInit(
|
125
|
-
createDeploy(
|
125
|
+
function runInit(config) {
|
126
|
+
createDeploy({ config });
|
126
127
|
}
|
127
128
|
|
128
129
|
export { Deploy, runInit };
|
@@ -1,6 +1,13 @@
|
|
1
|
-
import {
|
1
|
+
import { Logger } from '@shopify/cli-kit/node/output';
|
2
|
+
import { DeploymentConfig } from './types.js';
|
2
3
|
import { BuildCancelResponse } from './graphql/build-cancel.js';
|
3
4
|
|
4
|
-
|
5
|
+
interface BuildCancelOptions {
|
6
|
+
config: DeploymentConfig;
|
7
|
+
buildId: string;
|
8
|
+
reason: string;
|
9
|
+
logger: Logger;
|
10
|
+
}
|
11
|
+
declare function buildCancel(options: BuildCancelOptions): Promise<BuildCancelResponse>;
|
5
12
|
|
6
13
|
export { buildCancel };
|
@@ -1,10 +1,11 @@
|
|
1
1
|
import { graphqlRequest } from '@shopify/cli-kit/node/api/graphql';
|
2
2
|
import { AbortError } from '@shopify/cli-kit/node/error';
|
3
3
|
import { outputInfo } from '@shopify/cli-kit/node/output';
|
4
|
-
import { Header,
|
4
|
+
import { Header, errorHandler } from '../utils/utils.js';
|
5
5
|
import { BuildCancelQuery } from './graphql/build-cancel.js';
|
6
6
|
|
7
|
-
async function buildCancel(
|
7
|
+
async function buildCancel(options) {
|
8
|
+
const { config, buildId, reason, logger } = options;
|
8
9
|
const variables = {
|
9
10
|
buildId,
|
10
11
|
reason
|
@@ -25,7 +26,7 @@ async function buildCancel(config, buildId, reason) {
|
|
25
26
|
`Failed to cancel build: ${response.buildCancel.userErrors[0]?.message}`
|
26
27
|
);
|
27
28
|
}
|
28
|
-
outputInfo(`Build with id ${buildId} cancelled.`,
|
29
|
+
outputInfo(`Build with id ${buildId} cancelled.`, logger);
|
29
30
|
return response.buildCancel;
|
30
31
|
} catch (error) {
|
31
32
|
errorHandler(error);
|
@@ -2,7 +2,7 @@ import { AbortError } from '@shopify/cli-kit/node/error';
|
|
2
2
|
import { graphqlRequest } from '@shopify/cli-kit/node/api/graphql';
|
3
3
|
import { vi, describe, test, expect } from 'vitest';
|
4
4
|
import { createTestConfig } from '../utils/test-helper.js';
|
5
|
-
import { Header } from '../utils/utils.js';
|
5
|
+
import { stderrLogger, Header } from '../utils/utils.js';
|
6
6
|
import { buildCancel } from './build-cancel.js';
|
7
7
|
|
8
8
|
vi.mock("@shopify/cli-kit/node/api/graphql");
|
@@ -20,7 +20,12 @@ describe("BuildCancel", () => {
|
|
20
20
|
}
|
21
21
|
};
|
22
22
|
vi.mocked(graphqlRequest).mockResolvedValueOnce(response);
|
23
|
-
const cancelResponse = await buildCancel(
|
23
|
+
const cancelResponse = await buildCancel({
|
24
|
+
config: testConfig,
|
25
|
+
buildId: "build-1",
|
26
|
+
reason: "because",
|
27
|
+
logger: stderrLogger
|
28
|
+
});
|
24
29
|
expect(cancelResponse).toEqual(response.buildCancel);
|
25
30
|
expect(graphqlRequest).toHaveBeenCalledWith({
|
26
31
|
query: expect.any(String),
|
@@ -47,7 +52,14 @@ describe("BuildCancel", () => {
|
|
47
52
|
}
|
48
53
|
};
|
49
54
|
vi.mocked(graphqlRequest).mockResolvedValueOnce(response);
|
50
|
-
await expect(
|
55
|
+
await expect(
|
56
|
+
buildCancel({
|
57
|
+
config: testConfig,
|
58
|
+
buildId: "build-1",
|
59
|
+
reason: "because",
|
60
|
+
logger: stderrLogger
|
61
|
+
})
|
62
|
+
).rejects.toThrow(
|
51
63
|
new AbortError(
|
52
64
|
`Failed to cancel build: ${response.buildCancel.userErrors[0]?.message}`
|
53
65
|
)
|
@@ -60,7 +72,12 @@ describe("BuildCancel", () => {
|
|
60
72
|
vi.mocked(graphqlRequest).mockRejectedValueOnce(error);
|
61
73
|
try {
|
62
74
|
await expect(
|
63
|
-
buildCancel(
|
75
|
+
buildCancel({
|
76
|
+
config: testConfig,
|
77
|
+
buildId: "build-1",
|
78
|
+
reason: "because",
|
79
|
+
logger: stderrLogger
|
80
|
+
})
|
64
81
|
).rejects.toThrow(
|
65
82
|
new AbortError(
|
66
83
|
"You are not authorized to perform this action. Please check your deployment token."
|
@@ -1,6 +1,13 @@
|
|
1
|
-
import {
|
1
|
+
import { Logger } from '@shopify/cli-kit/node/output';
|
2
|
+
import { DeploymentConfig, EnvironmentInput } from './types.js';
|
2
3
|
import { BuildInitiateResponse } from './graphql/build-initiate.js';
|
3
4
|
|
4
|
-
|
5
|
+
interface BuildInitiateOptions {
|
6
|
+
config: DeploymentConfig;
|
7
|
+
logger: Logger;
|
8
|
+
environment?: EnvironmentInput;
|
9
|
+
labels?: string[];
|
10
|
+
}
|
11
|
+
declare function buildInitiate(options: BuildInitiateOptions): Promise<BuildInitiateResponse>;
|
5
12
|
|
6
13
|
export { buildInitiate };
|
@@ -1,10 +1,11 @@
|
|
1
1
|
import { graphqlRequest } from '@shopify/cli-kit/node/api/graphql';
|
2
2
|
import { AbortError } from '@shopify/cli-kit/node/error';
|
3
3
|
import { outputCompleted } from '@shopify/cli-kit/node/output';
|
4
|
-
import { Header,
|
4
|
+
import { Header, errorHandler } from '../utils/utils.js';
|
5
5
|
import { BuildInitiateQuery } from './graphql/build-initiate.js';
|
6
6
|
|
7
|
-
async function buildInitiate(
|
7
|
+
async function buildInitiate(options) {
|
8
|
+
const { config, logger, environment, labels = [] } = options;
|
8
9
|
const variables = {
|
9
10
|
environment,
|
10
11
|
labels
|
@@ -27,7 +28,7 @@ async function buildInitiate(config, environment, labels = []) {
|
|
27
28
|
}
|
28
29
|
outputCompleted(
|
29
30
|
`Build initiated successfully with id ${response.buildInitiate.build.id}.`,
|
30
|
-
|
31
|
+
logger
|
31
32
|
);
|
32
33
|
return response.buildInitiate;
|
33
34
|
} catch (error) {
|
@@ -2,7 +2,7 @@ import { AbortError } from '@shopify/cli-kit/node/error';
|
|
2
2
|
import { graphqlRequest } from '@shopify/cli-kit/node/api/graphql';
|
3
3
|
import { outputCompleted } from '@shopify/cli-kit/node/output';
|
4
4
|
import { vi, describe, test, expect } from 'vitest';
|
5
|
-
import {
|
5
|
+
import { stderrLogger, Header } from '../utils/utils.js';
|
6
6
|
import { createTestConfig } from '../utils/test-helper.js';
|
7
7
|
import { buildInitiate } from './build-initiate.js';
|
8
8
|
|
@@ -20,13 +20,14 @@ describe("BuildInitiate", () => {
|
|
20
20
|
}
|
21
21
|
};
|
22
22
|
vi.mocked(graphqlRequest).mockResolvedValueOnce(response);
|
23
|
-
const initiateResponse = await buildInitiate(
|
24
|
-
testConfig,
|
25
|
-
{
|
23
|
+
const initiateResponse = await buildInitiate({
|
24
|
+
config: testConfig,
|
25
|
+
environment: {
|
26
26
|
tag: testConfig.environmentTag
|
27
27
|
},
|
28
|
-
[]
|
29
|
-
|
28
|
+
labels: [],
|
29
|
+
logger: stderrLogger
|
30
|
+
});
|
30
31
|
expect(initiateResponse).toEqual(response.buildInitiate);
|
31
32
|
expect(graphqlRequest).toHaveBeenCalledWith({
|
32
33
|
query: expect.any(String),
|
@@ -55,7 +56,12 @@ describe("BuildInitiate", () => {
|
|
55
56
|
};
|
56
57
|
vi.mocked(graphqlRequest).mockResolvedValueOnce(response);
|
57
58
|
await expect(
|
58
|
-
buildInitiate(
|
59
|
+
buildInitiate({
|
60
|
+
config: testConfig,
|
61
|
+
environment: { tag: "preview" },
|
62
|
+
labels: [],
|
63
|
+
logger: stderrLogger
|
64
|
+
})
|
59
65
|
).rejects.toThrow(
|
60
66
|
new AbortError(
|
61
67
|
`Failed to create build. ${response.buildInitiate.userErrors[0]?.message}`
|
@@ -69,7 +75,12 @@ describe("BuildInitiate", () => {
|
|
69
75
|
vi.mocked(graphqlRequest).mockRejectedValueOnce(error);
|
70
76
|
try {
|
71
77
|
await expect(
|
72
|
-
buildInitiate(
|
78
|
+
buildInitiate({
|
79
|
+
config: testConfig,
|
80
|
+
environment: { tag: "preview" },
|
81
|
+
labels: [],
|
82
|
+
logger: stderrLogger
|
83
|
+
})
|
73
84
|
).rejects.toThrow(
|
74
85
|
new AbortError(
|
75
86
|
"You are not authorized to perform this action. Please check your deployment token."
|
@@ -1,5 +1,10 @@
|
|
1
|
-
import {
|
1
|
+
import { DeploymentConfig, DeploymentHooks } from './types.js';
|
2
2
|
|
3
|
-
|
3
|
+
interface BuildProjectOptions {
|
4
|
+
config: DeploymentConfig;
|
5
|
+
assetPath?: string;
|
6
|
+
hooks?: DeploymentHooks;
|
7
|
+
}
|
8
|
+
declare function buildProject(options: BuildProjectOptions): Promise<void>;
|
4
9
|
|
5
10
|
export { buildProject };
|
@@ -1,28 +1,43 @@
|
|
1
1
|
import { spawn } from 'child_process';
|
2
2
|
|
3
|
-
async function buildProject(
|
3
|
+
async function buildProject(options) {
|
4
|
+
const { config, assetPath, hooks } = options;
|
5
|
+
hooks?.onBuildStart?.();
|
4
6
|
const assetPathEnvironment = assetPath ? { HYDROGEN_ASSET_BASE_URL: assetPath } : {};
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
if (
|
19
|
-
|
7
|
+
try {
|
8
|
+
await new Promise((resolve, reject) => {
|
9
|
+
const buildCommand = spawn(config.buildCommand, [], {
|
10
|
+
stdio: config.buildOutput ? ["inherit", "pipe", "inherit"] : ["ignore", "ignore", "pipe"],
|
11
|
+
env: {
|
12
|
+
// eslint-disable-next-line no-process-env
|
13
|
+
...process.env,
|
14
|
+
...assetPathEnvironment
|
15
|
+
},
|
16
|
+
cwd: config.rootPath,
|
17
|
+
shell: true
|
18
|
+
});
|
19
|
+
let stderrOutput = "";
|
20
|
+
if (buildCommand.stderr) {
|
21
|
+
buildCommand.stderr.on("data", (data) => {
|
22
|
+
stderrOutput += data;
|
23
|
+
});
|
24
|
+
}
|
25
|
+
if (config.buildOutput && buildCommand.stdout) {
|
26
|
+
buildCommand.stdout.pipe(process.stderr);
|
20
27
|
}
|
21
|
-
|
28
|
+
buildCommand.on("close", (code) => {
|
29
|
+
if (code !== 0) {
|
30
|
+
hooks?.onBuildError?.(new Error(stderrOutput));
|
31
|
+
reject(code);
|
32
|
+
return;
|
33
|
+
}
|
34
|
+
hooks?.onBuildComplete?.();
|
35
|
+
resolve(code);
|
36
|
+
});
|
22
37
|
});
|
23
|
-
}
|
38
|
+
} catch (error) {
|
24
39
|
throw new Error(`Build failed with error code: ${error}`);
|
25
|
-
}
|
40
|
+
}
|
26
41
|
}
|
27
42
|
|
28
43
|
export { buildProject };
|
@@ -30,7 +30,11 @@ test("BuildProject builds the project successfully", async () => {
|
|
30
30
|
buildCommand: "npm run build"
|
31
31
|
};
|
32
32
|
const assetPath = "https://example.com/assets";
|
33
|
-
|
33
|
+
const hooks = {
|
34
|
+
onBuildStart: vi.fn(),
|
35
|
+
onBuildComplete: vi.fn()
|
36
|
+
};
|
37
|
+
await buildProject({ config, assetPath, hooks });
|
34
38
|
expect(spawn).toBeCalledWith("npm run build", [], {
|
35
39
|
cwd: "rootFolder",
|
36
40
|
shell: true,
|
@@ -41,15 +45,17 @@ test("BuildProject builds the project successfully", async () => {
|
|
41
45
|
HYDROGEN_ASSET_BASE_URL: "https://example.com/assets"
|
42
46
|
}
|
43
47
|
});
|
48
|
+
expect(hooks.onBuildStart).toBeCalled();
|
49
|
+
expect(hooks.onBuildComplete).toBeCalled();
|
44
50
|
});
|
45
51
|
test("should throw error on build command failure", async () => {
|
46
52
|
returnCode = 1;
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
});
|
53
|
+
const hooks = {
|
54
|
+
onBuildError: vi.fn()
|
55
|
+
};
|
51
56
|
const assetPath = "https://example.com/assets";
|
52
|
-
await expect(
|
53
|
-
|
54
|
-
);
|
57
|
+
await expect(
|
58
|
+
() => buildProject({ config: testConfig, assetPath, hooks })
|
59
|
+
).rejects.toThrow("Build failed with error code: 1");
|
60
|
+
expect(hooks.onBuildError).toBeCalled();
|
55
61
|
});
|
@@ -1,10 +1,17 @@
|
|
1
|
-
import {
|
1
|
+
import { Logger } from '@shopify/cli-kit/node/output';
|
2
|
+
import { DeploymentConfig } from './types.js';
|
2
3
|
import { DeploymentCancelResponse } from './graphql/deployment-cancel.js';
|
3
4
|
|
4
5
|
declare enum DeploymentCancelReason {
|
5
6
|
Failed = "FAILED",
|
6
7
|
Cancelled = "CANCELLED"
|
7
8
|
}
|
8
|
-
|
9
|
+
interface DeploymentCancelOptions {
|
10
|
+
config: DeploymentConfig;
|
11
|
+
deploymentId: string;
|
12
|
+
reason: DeploymentCancelReason;
|
13
|
+
logger: Logger;
|
14
|
+
}
|
15
|
+
declare function deploymentCancel(options: DeploymentCancelOptions): Promise<DeploymentCancelResponse>;
|
9
16
|
|
10
17
|
export { DeploymentCancelReason, deploymentCancel };
|
@@ -1,7 +1,7 @@
|
|
1
1
|
import { graphqlRequest } from '@shopify/cli-kit/node/api/graphql';
|
2
2
|
import { AbortError } from '@shopify/cli-kit/node/error';
|
3
3
|
import { outputInfo } from '@shopify/cli-kit/node/output';
|
4
|
-
import { Header,
|
4
|
+
import { Header, errorHandler } from '../utils/utils.js';
|
5
5
|
import { DeploymentCancelQuery } from './graphql/deployment-cancel.js';
|
6
6
|
|
7
7
|
var DeploymentCancelReason = /* @__PURE__ */ ((DeploymentCancelReason2) => {
|
@@ -9,7 +9,8 @@ var DeploymentCancelReason = /* @__PURE__ */ ((DeploymentCancelReason2) => {
|
|
9
9
|
DeploymentCancelReason2["Cancelled"] = "CANCELLED";
|
10
10
|
return DeploymentCancelReason2;
|
11
11
|
})(DeploymentCancelReason || {});
|
12
|
-
async function deploymentCancel(
|
12
|
+
async function deploymentCancel(options) {
|
13
|
+
const { config, deploymentId, reason, logger } = options;
|
13
14
|
const variables = {
|
14
15
|
deploymentId,
|
15
16
|
reason
|
@@ -30,7 +31,7 @@ async function deploymentCancel(config, deploymentId, reason) {
|
|
30
31
|
`Failed to cancel deployment: ${response.deploymentCancel.userErrors[0]?.message}`
|
31
32
|
);
|
32
33
|
}
|
33
|
-
outputInfo(`Deployment with id ${deploymentId} cancelled.`,
|
34
|
+
outputInfo(`Deployment with id ${deploymentId} cancelled.`, logger);
|
34
35
|
return response.deploymentCancel;
|
35
36
|
} catch (error) {
|
36
37
|
errorHandler(error);
|
@@ -2,7 +2,7 @@ import { AbortError } from '@shopify/cli-kit/node/error';
|
|
2
2
|
import { graphqlRequest } from '@shopify/cli-kit/node/api/graphql';
|
3
3
|
import { vi, describe, test, expect } from 'vitest';
|
4
4
|
import { createTestConfig } from '../utils/test-helper.js';
|
5
|
-
import { Header } from '../utils/utils.js';
|
5
|
+
import { stderrLogger, Header } from '../utils/utils.js';
|
6
6
|
import { deploymentCancel, DeploymentCancelReason } from './deployment-cancel.js';
|
7
7
|
|
8
8
|
vi.mock("@shopify/cli-kit/node/api/graphql");
|
@@ -19,11 +19,12 @@ describe("DeploymentComplete", () => {
|
|
19
19
|
}
|
20
20
|
};
|
21
21
|
vi.mocked(graphqlRequest).mockResolvedValueOnce(response);
|
22
|
-
const completeResponse = await deploymentCancel(
|
23
|
-
testConfig,
|
24
|
-
"deployment-1",
|
25
|
-
DeploymentCancelReason.Failed
|
26
|
-
|
22
|
+
const completeResponse = await deploymentCancel({
|
23
|
+
config: testConfig,
|
24
|
+
deploymentId: "deployment-1",
|
25
|
+
reason: DeploymentCancelReason.Failed,
|
26
|
+
logger: stderrLogger
|
27
|
+
});
|
27
28
|
expect(completeResponse).toEqual(response.deploymentCancel);
|
28
29
|
expect(graphqlRequest).toHaveBeenCalledWith({
|
29
30
|
query: expect.any(String),
|
@@ -51,11 +52,12 @@ describe("DeploymentComplete", () => {
|
|
51
52
|
};
|
52
53
|
vi.mocked(graphqlRequest).mockResolvedValueOnce(response);
|
53
54
|
await expect(
|
54
|
-
deploymentCancel(
|
55
|
-
testConfig,
|
56
|
-
"deployment-1",
|
57
|
-
DeploymentCancelReason.Failed
|
58
|
-
|
55
|
+
deploymentCancel({
|
56
|
+
config: testConfig,
|
57
|
+
deploymentId: "deployment-1",
|
58
|
+
reason: DeploymentCancelReason.Failed,
|
59
|
+
logger: stderrLogger
|
60
|
+
})
|
59
61
|
).rejects.toThrow(
|
60
62
|
new AbortError(
|
61
63
|
`Failed to cancel deployment: ${response.deploymentCancel.userErrors[0]?.message}`
|
@@ -69,11 +71,12 @@ describe("DeploymentComplete", () => {
|
|
69
71
|
vi.mocked(graphqlRequest).mockRejectedValueOnce(error);
|
70
72
|
try {
|
71
73
|
await expect(
|
72
|
-
deploymentCancel(
|
73
|
-
testConfig,
|
74
|
-
"deployment-1",
|
75
|
-
DeploymentCancelReason.Failed
|
76
|
-
|
74
|
+
deploymentCancel({
|
75
|
+
config: testConfig,
|
76
|
+
deploymentId: "deployment-1",
|
77
|
+
reason: DeploymentCancelReason.Failed,
|
78
|
+
logger: stderrLogger
|
79
|
+
})
|
77
80
|
).rejects.toThrow(
|
78
81
|
new AbortError(
|
79
82
|
"You are not authorized to perform this action. Please check your deployment token."
|
@@ -1,6 +1,6 @@
|
|
1
1
|
import { DeploymentCompleteResponse } from './graphql/deployment-complete.js';
|
2
|
-
import {
|
2
|
+
import { DeploymentConfig } from './types.js';
|
3
3
|
|
4
|
-
declare function deploymentComplete(config:
|
4
|
+
declare function deploymentComplete(config: DeploymentConfig, deploymentId: string): Promise<DeploymentCompleteResponse>;
|
5
5
|
|
6
6
|
export { deploymentComplete };
|
@@ -1,17 +1,23 @@
|
|
1
|
-
import {
|
1
|
+
import { Logger } from '@shopify/cli-kit/node/output';
|
2
|
+
import { DeploymentConfig, DeploymentManifestFile, EnvironmentInput } from './types.js';
|
2
3
|
import { DeploymentInitiateResponse } from './graphql/deployment-initiate.js';
|
3
4
|
|
4
5
|
type DeploymentInitiateInput = {
|
5
6
|
buildId: string;
|
6
7
|
environment?: never;
|
7
|
-
manifest: DeploymentManifestFile[];
|
8
8
|
labels?: string[];
|
9
|
+
manifest: DeploymentManifestFile[];
|
9
10
|
} | {
|
10
11
|
environment?: EnvironmentInput;
|
11
12
|
buildId?: never;
|
12
|
-
manifest: DeploymentManifestFile[];
|
13
13
|
labels?: string[];
|
14
|
+
manifest: DeploymentManifestFile[];
|
14
15
|
};
|
15
|
-
|
16
|
+
interface DeploymentInitiateOptions {
|
17
|
+
config: DeploymentConfig;
|
18
|
+
input: DeploymentInitiateInput;
|
19
|
+
logger: Logger;
|
20
|
+
}
|
21
|
+
declare function deploymentInitiate(options: DeploymentInitiateOptions): Promise<DeploymentInitiateResponse>;
|
16
22
|
|
17
23
|
export { deploymentInitiate };
|
@@ -1,10 +1,11 @@
|
|
1
1
|
import { graphqlRequest } from '@shopify/cli-kit/node/api/graphql';
|
2
2
|
import { AbortError } from '@shopify/cli-kit/node/error';
|
3
3
|
import { outputCompleted } from '@shopify/cli-kit/node/output';
|
4
|
-
import { Header,
|
4
|
+
import { Header, errorHandler } from '../utils/utils.js';
|
5
5
|
import { DeploymentInitiateQuery } from './graphql/deployment-initiate.js';
|
6
6
|
|
7
|
-
async function deploymentInitiate(
|
7
|
+
async function deploymentInitiate(options) {
|
8
|
+
const { config, input, logger } = options;
|
8
9
|
const variables = {
|
9
10
|
buildId: input.buildId,
|
10
11
|
environment: input.environment,
|
@@ -30,7 +31,7 @@ async function deploymentInitiate(config, input) {
|
|
30
31
|
}
|
31
32
|
outputCompleted(
|
32
33
|
`Deployment initiated, ${response.deploymentInitiate.deploymentTargets.length} files to upload.`,
|
33
|
-
|
34
|
+
logger
|
34
35
|
);
|
35
36
|
return response.deploymentInitiate;
|
36
37
|
} catch (error) {
|
@@ -3,7 +3,7 @@ import { graphqlRequest } from '@shopify/cli-kit/node/api/graphql';
|
|
3
3
|
import { outputCompleted } from '@shopify/cli-kit/node/output';
|
4
4
|
import { vi, describe, test, expect } from 'vitest';
|
5
5
|
import { createTestConfig } from '../utils/test-helper.js';
|
6
|
-
import {
|
6
|
+
import { stderrLogger, Header } from '../utils/utils.js';
|
7
7
|
import { deploymentInitiate } from './deployment-initiate.js';
|
8
8
|
|
9
9
|
vi.mock("@shopify/cli-kit/node/api/graphql");
|
@@ -38,9 +38,13 @@ const testResponse = {
|
|
38
38
|
describe("DeploymentInitiate", () => {
|
39
39
|
test("should initiate a deployment with a buildId", async () => {
|
40
40
|
vi.mocked(graphqlRequest).mockResolvedValueOnce(testResponse);
|
41
|
-
const initiateResponse = await deploymentInitiate(
|
42
|
-
|
43
|
-
|
41
|
+
const initiateResponse = await deploymentInitiate({
|
42
|
+
config: testConfig,
|
43
|
+
input: {
|
44
|
+
buildId: "build-1",
|
45
|
+
manifest: testManifest
|
46
|
+
},
|
47
|
+
logger: stderrLogger
|
44
48
|
});
|
45
49
|
expect(initiateResponse).toEqual(testResponse.deploymentInitiate);
|
46
50
|
expect(graphqlRequest).toHaveBeenCalledWith({
|
@@ -65,10 +69,14 @@ describe("DeploymentInitiate", () => {
|
|
65
69
|
});
|
66
70
|
test("should initiate a deployment with an environmentName", async () => {
|
67
71
|
vi.mocked(graphqlRequest).mockResolvedValueOnce(testResponse);
|
68
|
-
const initiateResponse = await deploymentInitiate(
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
+
const initiateResponse = await deploymentInitiate({
|
73
|
+
config: testConfig,
|
74
|
+
input: {
|
75
|
+
buildId: void 0,
|
76
|
+
environment: { tag: "preview" },
|
77
|
+
manifest: testManifest
|
78
|
+
},
|
79
|
+
logger: stderrLogger
|
72
80
|
});
|
73
81
|
expect(initiateResponse).toEqual(testResponse.deploymentInitiate);
|
74
82
|
expect(graphqlRequest).toHaveBeenCalledWith({
|
@@ -108,7 +116,11 @@ describe("DeploymentInitiate", () => {
|
|
108
116
|
manifest: testManifest
|
109
117
|
};
|
110
118
|
await expect(
|
111
|
-
deploymentInitiate(
|
119
|
+
deploymentInitiate({
|
120
|
+
config: testConfig,
|
121
|
+
input: deploymentInitData,
|
122
|
+
logger: stderrLogger
|
123
|
+
})
|
112
124
|
).rejects.toThrow(
|
113
125
|
new AbortError(
|
114
126
|
`Failed to create deployment. ${response.deploymentInitiate.userErrors[0]?.message}`
|
@@ -127,7 +139,11 @@ describe("DeploymentInitiate", () => {
|
|
127
139
|
manifest: testManifest
|
128
140
|
};
|
129
141
|
await expect(
|
130
|
-
deploymentInitiate(
|
142
|
+
deploymentInitiate({
|
143
|
+
config: testConfig,
|
144
|
+
input: deploymentInitData,
|
145
|
+
logger: stderrLogger
|
146
|
+
})
|
131
147
|
).rejects.toThrow(
|
132
148
|
new AbortError(
|
133
149
|
"You are not authorized to perform this action. Please check your deployment token."
|
@@ -1,5 +1,5 @@
|
|
1
|
-
import {
|
1
|
+
import { DeploymentConfig, DeploymentManifestFile } from './types.js';
|
2
2
|
|
3
|
-
declare function getUploadFiles(config:
|
3
|
+
declare function getUploadFiles(config: DeploymentConfig): Promise<DeploymentManifestFile[]>;
|
4
4
|
|
5
5
|
export { getUploadFiles };
|
package/dist/deploy/index.d.ts
CHANGED
@@ -1,5 +1,12 @@
|
|
1
|
-
import {
|
1
|
+
import { Logger } from '@shopify/cli-kit/node/output';
|
2
|
+
import { DeploymentConfig, DeploymentHooks } from './types.js';
|
3
|
+
export { parseToken } from '../utils/utils.js';
|
2
4
|
|
3
|
-
|
5
|
+
interface CreateDeployOptions {
|
6
|
+
config: DeploymentConfig;
|
7
|
+
hooks?: DeploymentHooks;
|
8
|
+
logger?: Logger;
|
9
|
+
}
|
10
|
+
declare function createDeploy(options: CreateDeployOptions): Promise<string | undefined>;
|
4
11
|
|
5
|
-
export { createDeploy };
|
12
|
+
export { DeploymentConfig, DeploymentHooks, createDeploy };
|
package/dist/deploy/index.js
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
import { outputSuccess, outputInfo, outputWarn, consoleError } from '@shopify/cli-kit/node/output';
|
2
|
-
import {
|
2
|
+
import { stderrLogger, verifyConfig } from '../utils/utils.js';
|
3
|
+
export { parseToken } from '../utils/utils.js';
|
3
4
|
import { buildInitiate } from './build-initiate.js';
|
4
5
|
import { buildCancel } from './build-cancel.js';
|
5
6
|
import { getUploadFiles } from './get-upload-files.js';
|
@@ -10,32 +11,43 @@ import { uploadFiles } from './upload-files.js';
|
|
10
11
|
import { buildProject } from './build-project.js';
|
11
12
|
import { getMetadata, createLabels, getEnvironmentInput } from './metadata.js';
|
12
13
|
|
13
|
-
async function createDeploy(
|
14
|
+
async function createDeploy(options) {
|
15
|
+
const { config, hooks } = options;
|
16
|
+
const logger = options.logger ?? stderrLogger;
|
14
17
|
const build = {};
|
15
18
|
let buildCompleted;
|
16
19
|
let deployment;
|
17
20
|
try {
|
18
|
-
const metadata = await getMetadata(config);
|
21
|
+
const metadata = await getMetadata(config, logger);
|
19
22
|
const labels = createLabels(metadata);
|
20
23
|
const environment = getEnvironmentInput(config, metadata);
|
21
24
|
if (!config.workerOnly && !config.skipBuild) {
|
22
|
-
const buildInitiateResponse = await buildInitiate(
|
25
|
+
const buildInitiateResponse = await buildInitiate({
|
23
26
|
config,
|
24
27
|
environment,
|
25
|
-
labels
|
26
|
-
|
28
|
+
labels,
|
29
|
+
logger
|
30
|
+
});
|
27
31
|
build.id = buildInitiateResponse.build.id;
|
28
32
|
build.assetPath = buildInitiateResponse.build.assetPath;
|
29
33
|
}
|
30
34
|
if (!config.skipBuild) {
|
31
|
-
await buildProject(
|
35
|
+
await buildProject({
|
36
|
+
config,
|
37
|
+
assetPath: build.assetPath,
|
38
|
+
hooks
|
39
|
+
});
|
32
40
|
verifyConfig({ config, performedBuild: true });
|
33
41
|
}
|
34
42
|
buildCompleted = true;
|
35
43
|
const manifest = await getUploadFiles(config);
|
36
44
|
const deploymentInitiateInput = build.id ? { buildId: build.id, manifest } : { environment, manifest, labels };
|
37
|
-
deployment = await deploymentInitiate(
|
38
|
-
|
45
|
+
deployment = await deploymentInitiate({
|
46
|
+
config,
|
47
|
+
input: deploymentInitiateInput,
|
48
|
+
logger
|
49
|
+
});
|
50
|
+
await uploadFiles({ config, targets: deployment.deploymentTargets, logger });
|
39
51
|
const deploymentCompleteOp = await deploymentComplete(
|
40
52
|
config,
|
41
53
|
deployment.deployment.id
|
@@ -44,45 +56,50 @@ async function createDeploy(config) {
|
|
44
56
|
outputSuccess(
|
45
57
|
`Deployment complete.
|
46
58
|
${urlMessage} preview URL: ${deploymentCompleteOp.deployment.url}`,
|
47
|
-
|
59
|
+
logger
|
48
60
|
);
|
49
61
|
if (metadata.name !== "none") {
|
50
62
|
outputInfo(deploymentCompleteOp.deployment.url);
|
51
63
|
}
|
64
|
+
return deploymentCompleteOp.deployment.url;
|
52
65
|
} catch (error) {
|
53
66
|
if (!(error instanceof Error)) {
|
54
67
|
console.error("Unknown error", error);
|
55
|
-
return;
|
68
|
+
return Promise.reject(new Error("Unknown error"));
|
56
69
|
}
|
57
70
|
if (build.id && !buildCompleted) {
|
58
71
|
outputWarn(
|
59
72
|
`Build failed with: ${error.message}, cancelling build.`,
|
60
|
-
|
73
|
+
logger
|
61
74
|
);
|
62
|
-
await buildCancel(
|
75
|
+
await buildCancel({
|
76
|
+
config,
|
77
|
+
buildId: build.id,
|
78
|
+
reason: error.message,
|
79
|
+
logger
|
80
|
+
}).catch((err) => {
|
63
81
|
if (err instanceof Error) {
|
64
|
-
outputWarn(`Failed to cancel build: ${err.message}`,
|
82
|
+
outputWarn(`Failed to cancel build: ${err.message}`, logger);
|
65
83
|
}
|
66
84
|
});
|
67
85
|
} else if (deployment?.deployment.id) {
|
68
86
|
outputWarn(
|
69
87
|
`Deployment failed with: ${error.message}, cancelling deployment.`,
|
70
|
-
|
88
|
+
logger
|
71
89
|
);
|
72
|
-
await deploymentCancel(
|
90
|
+
await deploymentCancel({
|
73
91
|
config,
|
74
|
-
deployment.deployment.id,
|
75
|
-
DeploymentCancelReason.Failed
|
76
|
-
|
92
|
+
deploymentId: deployment.deployment.id,
|
93
|
+
reason: DeploymentCancelReason.Failed,
|
94
|
+
logger
|
95
|
+
}).catch((err) => {
|
77
96
|
if (err instanceof Error) {
|
78
|
-
outputWarn(
|
79
|
-
`Failed to cancel deployment: ${err.message}`,
|
80
|
-
stderrLogger
|
81
|
-
);
|
97
|
+
outputWarn(`Failed to cancel deployment: ${err.message}`, logger);
|
82
98
|
}
|
83
99
|
});
|
84
100
|
}
|
85
101
|
consoleError(error.message);
|
102
|
+
return Promise.reject(error);
|
86
103
|
}
|
87
104
|
}
|
88
105
|
|
@@ -1,11 +1,12 @@
|
|
1
1
|
import { CIMetadata } from '@shopify/cli-kit/node/context/local';
|
2
|
-
import {
|
2
|
+
import { Logger } from '@shopify/cli-kit/node/output';
|
3
|
+
import { DeploymentConfig, EnvironmentInput } from './types.js';
|
3
4
|
|
4
5
|
type Metadata = CIMetadata & {
|
5
6
|
name: string;
|
6
7
|
};
|
7
|
-
declare function getMetadata(config:
|
8
|
-
declare function getEnvironmentInput(config:
|
8
|
+
declare function getMetadata(config: DeploymentConfig, logger: Logger): Promise<Metadata>;
|
9
|
+
declare function getEnvironmentInput(config: DeploymentConfig, metadata: CIMetadata): EnvironmentInput | undefined;
|
9
10
|
declare function createLabels(metadata: Metadata): string[];
|
10
11
|
|
11
12
|
export { createLabels, getEnvironmentInput, getMetadata };
|
package/dist/deploy/metadata.js
CHANGED
@@ -1,9 +1,9 @@
|
|
1
1
|
import { ciPlatform } from '@shopify/cli-kit/node/context/local';
|
2
2
|
import { getLatestGitCommit } from '@shopify/cli-kit/node/git';
|
3
3
|
import { outputWarn } from '@shopify/cli-kit/node/output';
|
4
|
-
import {
|
4
|
+
import { maxLabelLength } from '../utils/utils.js';
|
5
5
|
|
6
|
-
async function getMetadata(config) {
|
6
|
+
async function getMetadata(config, logger) {
|
7
7
|
const ciInfo = ciPlatform();
|
8
8
|
let metadata = {};
|
9
9
|
if (ciInfo.isCI && ciInfo.name !== "unknown") {
|
@@ -19,7 +19,7 @@ async function getMetadata(config) {
|
|
19
19
|
commitMessage: gitCommit.message
|
20
20
|
};
|
21
21
|
} catch (error) {
|
22
|
-
outputWarn("No CI metadata loaded from environment",
|
22
|
+
outputWarn("No CI metadata loaded from environment", logger);
|
23
23
|
}
|
24
24
|
}
|
25
25
|
return {
|
@@ -1,7 +1,7 @@
|
|
1
1
|
import { getLatestGitCommit } from '@shopify/cli-kit/node/git';
|
2
2
|
import { ciPlatform } from '@shopify/cli-kit/node/context/local';
|
3
3
|
import { vi, describe, test, expect } from 'vitest';
|
4
|
-
import { maxLabelLength } from '../utils/utils.js';
|
4
|
+
import { stderrLogger, maxLabelLength } from '../utils/utils.js';
|
5
5
|
import { createTestConfig } from '../utils/test-helper.js';
|
6
6
|
import { getMetadata, getEnvironmentInput, createLabels } from './metadata.js';
|
7
7
|
|
@@ -19,7 +19,7 @@ describe("getMetadata", () => {
|
|
19
19
|
}
|
20
20
|
});
|
21
21
|
const testConfig = createTestConfig("/tmp/deploymentRoot/");
|
22
|
-
const metadataResult = await getMetadata(testConfig);
|
22
|
+
const metadataResult = await getMetadata(testConfig, stderrLogger);
|
23
23
|
expect(metadataResult.actor).toBe("circle_actor");
|
24
24
|
expect(metadataResult.commitSha).toBe("circle_sha");
|
25
25
|
expect(metadataResult.name).toBe("circle");
|
@@ -41,7 +41,7 @@ describe("getMetadata", () => {
|
|
41
41
|
version: "custom_version",
|
42
42
|
url: "custom_url"
|
43
43
|
};
|
44
|
-
const metadataResult = await getMetadata(testConfig);
|
44
|
+
const metadataResult = await getMetadata(testConfig, stderrLogger);
|
45
45
|
expect(metadataResult.actor).toBe("custom_user");
|
46
46
|
expect(metadataResult.commitSha).toBe("custom_version");
|
47
47
|
expect(metadataResult.name).toBe("circle");
|
@@ -61,7 +61,7 @@ describe("getMetadata", () => {
|
|
61
61
|
body: "gh_body"
|
62
62
|
});
|
63
63
|
const testConfig = createTestConfig("/tmp/deploymentRoot/");
|
64
|
-
const metadataResult = await getMetadata(testConfig);
|
64
|
+
const metadataResult = await getMetadata(testConfig, stderrLogger);
|
65
65
|
expect(metadataResult.actor).toBe("gh_author");
|
66
66
|
expect(metadataResult.commitSha).toBe("gh_hash");
|
67
67
|
expect(metadataResult.name).toBe("none");
|
package/dist/deploy/types.d.ts
CHANGED
@@ -5,9 +5,17 @@ interface Build {
|
|
5
5
|
interface ClientError extends Error {
|
6
6
|
statusCode: number;
|
7
7
|
}
|
8
|
-
interface
|
8
|
+
interface DeploymentHooks {
|
9
|
+
onBuildStart?: () => void;
|
10
|
+
onBuildComplete?: () => void;
|
11
|
+
onBuildError?: (error: Error) => void;
|
12
|
+
onUploadFilesStart?: () => void;
|
13
|
+
onUploadFilesComplete?: () => void;
|
14
|
+
}
|
15
|
+
interface DeploymentConfig {
|
9
16
|
assetsDir?: string;
|
10
17
|
buildCommand: string;
|
18
|
+
buildOutput: boolean;
|
11
19
|
deploymentToken: DeploymentToken;
|
12
20
|
deploymentUrl: string;
|
13
21
|
environmentTag?: string;
|
@@ -50,4 +58,4 @@ interface OxygenError {
|
|
50
58
|
message: string;
|
51
59
|
}
|
52
60
|
|
53
|
-
export { Build, ClientError,
|
61
|
+
export { Build, ClientError, DeploymentConfig, DeploymentHooks, DeploymentManifestFile, DeploymentToken, EnvironmentInput, FileType, OxygenError };
|
@@ -1,6 +1,13 @@
|
|
1
|
-
import {
|
1
|
+
import { Logger } from '@shopify/cli-kit/node/output';
|
2
|
+
import { DeploymentConfig, DeploymentHooks } from './types.js';
|
2
3
|
import { DeploymentTargetResponse } from './graphql/deployment-initiate.js';
|
3
4
|
|
4
|
-
|
5
|
+
interface UploadFilesOptions {
|
6
|
+
config: DeploymentConfig;
|
7
|
+
hooks?: DeploymentHooks;
|
8
|
+
logger: Logger;
|
9
|
+
targets: DeploymentTargetResponse[];
|
10
|
+
}
|
11
|
+
declare function uploadFiles(options: UploadFilesOptions): Promise<void>;
|
5
12
|
|
6
13
|
export { uploadFiles };
|
@@ -3,14 +3,17 @@ import { createFileReadStream } from '@shopify/cli-kit/node/fs';
|
|
3
3
|
import { outputInfo, outputCompleted } from '@shopify/cli-kit/node/output';
|
4
4
|
import { joinPath } from '@shopify/cli-kit/node/path';
|
5
5
|
import { mapLimit } from 'async';
|
6
|
-
import {
|
6
|
+
import { deployDefaults } from '../utils/utils.js';
|
7
7
|
|
8
|
-
async function uploadFiles(
|
9
|
-
|
8
|
+
async function uploadFiles(options) {
|
9
|
+
const { config, logger, targets, hooks } = options;
|
10
|
+
outputInfo(`Uploading ${targets.length} files...`, logger);
|
11
|
+
hooks?.onUploadFilesStart?.();
|
10
12
|
return mapLimit(targets, 6, async (target) => {
|
11
13
|
await uploadFile(config, target);
|
12
14
|
}).then(() => {
|
13
|
-
|
15
|
+
hooks?.onUploadFilesComplete?.();
|
16
|
+
outputCompleted(`Files uploaded successfully`, logger);
|
14
17
|
});
|
15
18
|
}
|
16
19
|
async function uploadFile(config, target) {
|
@@ -3,7 +3,7 @@ import { fetch } from '@shopify/cli-kit/node/http';
|
|
3
3
|
import { vi, describe, beforeEach, it, expect } from 'vitest';
|
4
4
|
import { Response } from 'node-fetch';
|
5
5
|
import { createTestConfig } from '../utils/test-helper.js';
|
6
|
-
import { deployDefaults } from '../utils/utils.js';
|
6
|
+
import { stderrLogger, deployDefaults } from '../utils/utils.js';
|
7
7
|
import { uploadFiles } from './upload-files.js';
|
8
8
|
|
9
9
|
class NamedReadable extends Readable {
|
@@ -29,22 +29,16 @@ vi.mock("@shopify/cli-kit/node/fs", () => {
|
|
29
29
|
})
|
30
30
|
};
|
31
31
|
});
|
32
|
-
vi.mock("fs", () => {
|
33
|
-
return {
|
34
|
-
createReadStream: vi.fn(() => {
|
35
|
-
const readable = new NamedReadable();
|
36
|
-
readable.push("dummy");
|
37
|
-
readable.emit("end");
|
38
|
-
return readable;
|
39
|
-
})
|
40
|
-
};
|
41
|
-
});
|
42
32
|
const testConfig = createTestConfig("/tmp/deploymentRoot");
|
43
33
|
describe("UploadFiles", () => {
|
44
34
|
beforeEach(() => {
|
45
35
|
vi.mocked(fetch).mockReset();
|
46
36
|
});
|
47
37
|
it("Performs a form upload", async () => {
|
38
|
+
const hooks = {
|
39
|
+
onUploadFilesStart: vi.fn(),
|
40
|
+
onUploadFilesComplete: vi.fn()
|
41
|
+
};
|
48
42
|
const response = new Response();
|
49
43
|
vi.mocked(fetch).mockResolvedValueOnce(response);
|
50
44
|
const testWorkerUpload = [
|
@@ -56,7 +50,12 @@ describe("UploadFiles", () => {
|
|
56
50
|
parameters: [{ name: "someName", value: "someValue" }]
|
57
51
|
}
|
58
52
|
];
|
59
|
-
await uploadFiles(
|
53
|
+
await uploadFiles({
|
54
|
+
config: testConfig,
|
55
|
+
targets: testWorkerUpload,
|
56
|
+
logger: stderrLogger,
|
57
|
+
hooks
|
58
|
+
});
|
60
59
|
expect(vi.mocked(fetch)).toHaveBeenCalledTimes(1);
|
61
60
|
expect(vi.mocked(fetch)).toHaveBeenCalledWith(
|
62
61
|
"https://storage.googleapis.com/the-bucket/",
|
@@ -73,6 +72,8 @@ describe("UploadFiles", () => {
|
|
73
72
|
})
|
74
73
|
})
|
75
74
|
);
|
75
|
+
expect(hooks.onUploadFilesStart).toBeCalled();
|
76
|
+
expect(hooks.onUploadFilesComplete).toBeCalled();
|
76
77
|
});
|
77
78
|
it("Retries a failed form upload until the max upload attempts then throws", async () => {
|
78
79
|
vi.mocked(fetch).mockRejectedValue(new Error("some error"));
|
@@ -85,9 +86,13 @@ describe("UploadFiles", () => {
|
|
85
86
|
parameters: [{ name: "someName", value: "someValue" }]
|
86
87
|
}
|
87
88
|
];
|
88
|
-
await expect(
|
89
|
-
|
90
|
-
|
89
|
+
await expect(
|
90
|
+
uploadFiles({
|
91
|
+
config: testConfig,
|
92
|
+
targets: testWorkerUpload,
|
93
|
+
logger: stderrLogger
|
94
|
+
})
|
95
|
+
).rejects.toThrow("Failed to upload file index.js");
|
91
96
|
expect(vi.mocked(fetch)).toHaveBeenCalledTimes(
|
92
97
|
Number(deployDefaults.maxUploadAttempts) + 1
|
93
98
|
);
|
@@ -108,7 +113,11 @@ describe("UploadFiles", () => {
|
|
108
113
|
parameters: null
|
109
114
|
}
|
110
115
|
];
|
111
|
-
await uploadFiles(
|
116
|
+
await uploadFiles({
|
117
|
+
config: testConfig,
|
118
|
+
targets: testWorkerUpload,
|
119
|
+
logger: stderrLogger
|
120
|
+
});
|
112
121
|
expect(vi.mocked(fetch)).toHaveBeenCalledTimes(2);
|
113
122
|
const secondCall = vi.mocked(fetch).mock.calls[1];
|
114
123
|
expect(secondCall[0]).toBe("https://upload-it-here.com/");
|
@@ -145,7 +154,11 @@ describe("UploadFiles", () => {
|
|
145
154
|
parameters: null
|
146
155
|
}
|
147
156
|
];
|
148
|
-
await uploadFiles(
|
157
|
+
await uploadFiles({
|
158
|
+
config: testConfig,
|
159
|
+
targets: testWorkerUpload,
|
160
|
+
logger: stderrLogger
|
161
|
+
});
|
149
162
|
expect(vi.mocked(fetch)).toHaveBeenCalledTimes(4);
|
150
163
|
const statusCall = vi.mocked(fetch).mock.calls[2];
|
151
164
|
expect(statusCall[0]).toBe("https://upload-it-here.com/");
|
@@ -183,7 +196,13 @@ describe("UploadFiles", () => {
|
|
183
196
|
parameters: null
|
184
197
|
}
|
185
198
|
];
|
186
|
-
await expect(
|
199
|
+
await expect(
|
200
|
+
uploadFiles({
|
201
|
+
config: testConfig,
|
202
|
+
targets: testWorkerUpload,
|
203
|
+
logger: stderrLogger
|
204
|
+
})
|
205
|
+
).rejects.toThrow(
|
187
206
|
`Failed to upload file index.js after ${deployDefaults.maxResumabeUploadAttempts} attempts`
|
188
207
|
);
|
189
208
|
expect(vi.mocked(fetch)).toHaveBeenCalledTimes(
|
@@ -1,4 +1,4 @@
|
|
1
|
-
import {
|
1
|
+
import { DeploymentConfig } from '../deploy/types.js';
|
2
2
|
|
3
3
|
declare const testToken: {
|
4
4
|
accessToken: string;
|
@@ -9,6 +9,6 @@ declare const testToken: {
|
|
9
9
|
namespace: string;
|
10
10
|
namespaceId: string;
|
11
11
|
};
|
12
|
-
declare function createTestConfig(rootFolder: string):
|
12
|
+
declare function createTestConfig(rootFolder: string): DeploymentConfig;
|
13
13
|
|
14
14
|
export { createTestConfig, testToken };
|
@@ -13,6 +13,7 @@ function createTestConfig(rootFolder) {
|
|
13
13
|
return {
|
14
14
|
assetsDir: "/assets/",
|
15
15
|
buildCommand: String(deployDefaults.buildCommandDefault),
|
16
|
+
buildOutput: true,
|
16
17
|
deploymentToken: testToken,
|
17
18
|
environmentTag: "environment",
|
18
19
|
deploymentUrl: "https://localhost:3000",
|
package/dist/utils/utils.d.ts
CHANGED
@@ -1,10 +1,10 @@
|
|
1
|
-
import {
|
1
|
+
import { DeploymentConfig, ClientError, DeploymentToken } from '../deploy/types.js';
|
2
2
|
|
3
3
|
declare const deployDefaults: {
|
4
4
|
[key: string]: string | number;
|
5
5
|
};
|
6
6
|
declare function errorHandler(error: any): void;
|
7
|
-
declare function getBuildCommandFromLockFile(config:
|
7
|
+
declare function getBuildCommandFromLockFile(config: DeploymentConfig): string;
|
8
8
|
declare enum Header {
|
9
9
|
OxygenNamespaceHandle = "X-Oxygen-Namespace-Handle"
|
10
10
|
}
|
@@ -13,7 +13,7 @@ declare function stderrLogger(log: string): void;
|
|
13
13
|
declare const maxLabelLength = 90;
|
14
14
|
declare function parseToken(inputToken: string): DeploymentToken;
|
15
15
|
interface VerifyConfigParams {
|
16
|
-
config:
|
16
|
+
config: DeploymentConfig;
|
17
17
|
performedBuild?: boolean;
|
18
18
|
}
|
19
19
|
declare function verifyConfig({ config, performedBuild, }: VerifyConfigParams): Promise<void>;
|
package/dist/utils/utils.js
CHANGED
@@ -72,11 +72,6 @@ function stderrLogger(log) {
|
|
72
72
|
}
|
73
73
|
const maxLabelLength = 90;
|
74
74
|
function parseToken(inputToken) {
|
75
|
-
if (!inputToken) {
|
76
|
-
throw new Error(
|
77
|
-
"No deployment token provided. Use the --token flag to set a deployment token."
|
78
|
-
);
|
79
|
-
}
|
80
75
|
try {
|
81
76
|
const decodedToken = Buffer.from(inputToken, "base64").toString("utf-8");
|
82
77
|
const rawToken = JSON.parse(decodedToken);
|
package/oclif.manifest.json
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
{
|
2
|
-
"version": "1.
|
2
|
+
"version": "1.5.0",
|
3
3
|
"commands": {
|
4
4
|
"oxygen:deploy": {
|
5
5
|
"id": "oxygen:deploy",
|
@@ -16,7 +16,7 @@
|
|
16
16
|
"type": "option",
|
17
17
|
"char": "t",
|
18
18
|
"description": "Oxygen deployment token",
|
19
|
-
"required":
|
19
|
+
"required": true,
|
20
20
|
"multiple": false
|
21
21
|
},
|
22
22
|
"path": {
|
package/package.json
CHANGED
@@ -5,7 +5,7 @@
|
|
5
5
|
"@shopify:registry": "https://registry.npmjs.org"
|
6
6
|
},
|
7
7
|
"license": "MIT",
|
8
|
-
"version": "1.
|
8
|
+
"version": "1.5.0",
|
9
9
|
"type": "module",
|
10
10
|
"scripts": {
|
11
11
|
"build": "tsup --clean --config ./tsup.config.ts && oclif manifest",
|
@@ -31,7 +31,7 @@
|
|
31
31
|
"/oclif.manifest.json"
|
32
32
|
],
|
33
33
|
"dependencies": {
|
34
|
-
"@oclif/core": "2.8.
|
34
|
+
"@oclif/core": "2.8.11",
|
35
35
|
"@shopify/cli-kit": "^3.46.5",
|
36
36
|
"async": "^3.2.4"
|
37
37
|
},
|
@@ -45,7 +45,7 @@
|
|
45
45
|
"eslint": "^8.43.0",
|
46
46
|
"node-fetch": "^3.3.1",
|
47
47
|
"oclif": "^3",
|
48
|
-
"tsup": "^
|
48
|
+
"tsup": "^7.1.0",
|
49
49
|
"typescript": "^5.1.3",
|
50
50
|
"vite": "^4.3.9",
|
51
51
|
"vitest": "^0.32.2"
|