@shopify/oxygen-cli 5.0.1-unstable.202507092257.0 → 6.0.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/CHANGELOG.md +20 -0
- package/dist/commands/oxygen/deploy.js +3 -3
- package/dist/commands/oxygen/deploy.js.map +1 -1
- package/dist/commands/oxygen/deploy.test.d.ts +2 -0
- package/dist/commands/oxygen/deploy.test.js +104 -0
- package/dist/commands/oxygen/deploy.test.js.map +1 -0
- package/dist/deploy/build-project.js +2 -1
- package/dist/deploy/build-project.js.map +1 -1
- package/oclif.manifest.json +1 -1
- package/package.json +7 -6
package/CHANGELOG.md
CHANGED
@@ -1,5 +1,24 @@
|
|
1
1
|
# @shopify/oxygen-cli
|
2
2
|
|
3
|
+
## 6.0.0
|
4
|
+
|
5
|
+
### Major Changes
|
6
|
+
|
7
|
+
- 6bf94b8: Update vite from 6.3.5 to 7.0.0
|
8
|
+
- 56a2b48: Update eslint from 8.57.1 to 9.21.0
|
9
|
+
- be391b8: Update @shopify/eslint-plugin from 48.0.2 to 49.0.0
|
10
|
+
- df87def: Update @types/node from 22.15.21 to 24.0.12
|
11
|
+
|
12
|
+
### Minor Changes
|
13
|
+
|
14
|
+
- 5af26a7: Remove consoleError call, add missing test for deploy entrypoint
|
15
|
+
- 3031eb2: Update oclif from 4.17.46 to 4.18.0
|
16
|
+
- fadf06b: Update eslint from 9.30.1 to 9.32.0
|
17
|
+
|
18
|
+
### Patch Changes
|
19
|
+
|
20
|
+
- 8712abc: Bump eslint-plugin-prettier from 5.5.1 to 5.5.3
|
21
|
+
|
3
22
|
## 5.0.0
|
4
23
|
|
5
24
|
### Major Changes
|
@@ -15,6 +34,7 @@
|
|
15
34
|
|
16
35
|
### Patch Changes
|
17
36
|
|
37
|
+
- e4cd96d: returns AbortError instead of Error for build failures
|
18
38
|
- 7977fc5: Update changesets/action from 1.5.0 to 1.5.3
|
19
39
|
- 590b1b3: Update @types/node from 22.15.17 to 22.15.21
|
20
40
|
- 18c232a: Update brace-expansion from 1.1.11 to 1.1.12
|
@@ -1,5 +1,5 @@
|
|
1
1
|
import { Command, Flags } from '@oclif/core';
|
2
|
-
import {
|
2
|
+
import { outputWarn } from '@shopify/cli-kit/node/output';
|
3
3
|
import { normalizePath } from '@shopify/cli-kit/node/path';
|
4
4
|
import { readAndParseDotEnv } from '@shopify/cli-kit/node/dot-env';
|
5
5
|
import { initializeBugsnag, getBugsnag } from '../../utils/bugsnag.js';
|
@@ -172,9 +172,9 @@ class Deploy extends Command {
|
|
172
172
|
Bugsnag.notify(error);
|
173
173
|
}
|
174
174
|
if (error instanceof Error) {
|
175
|
-
|
175
|
+
outputWarn(error.message);
|
176
176
|
} else {
|
177
|
-
|
177
|
+
outputWarn(error);
|
178
178
|
}
|
179
179
|
this.exit(1);
|
180
180
|
}
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"sources":["../../../src/commands/oxygen/deploy.ts"],"names":[],"mappings":"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","file":"deploy.js","sourcesContent":["import {Command, Flags} from '@oclif/core';\nimport {consoleError} from '@shopify/cli-kit/node/output';\nimport {normalizePath} from '@shopify/cli-kit/node/path';\nimport {readAndParseDotEnv} from '@shopify/cli-kit/node/dot-env';\n\nimport {getBugsnag, initializeBugsnag} from '../../utils/bugsnag.js';\nimport {createDeploy} from '../../deploy/index.js';\nimport {\n deployDefaults,\n getBuildCommandFromLockFile,\n parseToken,\n verifyConfig,\n} from '../../utils/utils.js';\nimport type {\n DeploymentConfig,\n EnvironmentVariable,\n} from '../../deploy/types.js';\n\nexport class Deploy extends Command {\n static description = 'Creates a deployment to Oxygen';\n static hidden = false;\n static flags = {\n assetsFolder: Flags.string({\n char: 'a',\n description: 'Assets folder',\n default: String(deployDefaults.assetsDirDefault),\n required: false,\n }),\n buildCommand: Flags.string({\n char: 'b',\n description: 'Build command',\n required: false,\n default: String(deployDefaults.buildCommandDefault!),\n parse: (input): Promise<string> => {\n this.hasCustomBuildCommand = true;\n return Promise.resolve(input);\n },\n }),\n disableBugsnag: Flags.boolean({\n description: 'Disable Bugsnag error reporting',\n required: false,\n default: false,\n }),\n environmentTag: Flags.string({\n char: 'e',\n description: 'Tag of the environment to deploy to',\n required: false,\n }),\n path: Flags.string({\n char: 'p',\n description: 'Root path',\n default: './',\n required: false,\n }),\n defaultEnvironment: Flags.boolean({\n env: 'OXYGEN_DEFAULT_ENVIRONMENT',\n description: 'Deploys to the default environment of the app',\n required: false,\n default: false,\n }),\n skipBuild: Flags.boolean({\n char: 's',\n description: 'Skip running build command',\n required: false,\n default: false,\n }),\n token: Flags.string({\n char: 't',\n description: 'Oxygen deployment token',\n env: 'OXYGEN_DEPLOYMENT_TOKEN',\n required: true,\n }),\n workerFolder: Flags.string({\n char: 'w',\n description: 'Worker folder',\n default: String(deployDefaults.workerDirDefault),\n required: false,\n }),\n workerOnly: Flags.boolean({\n char: 'o',\n description: 'Worker only deployment',\n default: false,\n required: false,\n }),\n metadataDescription: Flags.string({\n description:\n 'Description of the deployment. Will be saved and displayed in the Shopify admin',\n required: false,\n env: 'OXYGEN_METADATA_DESCRIPTION',\n }),\n metadataHydrogenVersion: Flags.string({\n description: 'The Hydrogen version of the deployment from package.json',\n required: false,\n env: 'OXYGEN_METADATA_HYDROGEN_VERSION',\n }),\n metadataUrl: Flags.string({\n description:\n 'URL that links to the deployment. Will be saved and displayed in the Shopify admin',\n required: false,\n env: 'OXYGEN_METADATA_URL',\n }),\n metadataUser: Flags.string({\n description:\n 'User that initiated the deployment. Will be saved and displayed in the Shopify admin',\n required: false,\n env: 'OXYGEN_METADATA_USER',\n }),\n metadataVersion: Flags.string({\n description:\n 'A version identifier for the deployment. Will be saved and displayed in the Shopify admin',\n required: false,\n env: 'OXYGEN_METADATA_VERSION',\n }),\n generateAuthBypassToken: Flags.boolean({\n description:\n 'Generate an auth bypass token used to perform end-to-end testing against the deployment.',\n required: false,\n default: false,\n }),\n authBypassTokenDuration: Flags.string({\n description:\n 'Specify the duration (in hours) up to 12 hours for the authentication bypass token. Defaults to `2`.',\n required: false,\n dependsOn: ['generateAuthBypassToken'],\n }),\n environmentFile: Flags.string({\n description:\n 'Path to an environment file to override existing environment variables for the deployment.',\n required: false,\n }),\n };\n\n static hasCustomBuildCommand = false;\n\n async run() {\n try {\n const {flags} = await this.parse(Deploy);\n const rootPath = normalizePath(flags.path);\n\n let overriddenEnvironmentVariables: EnvironmentVariable[] | undefined;\n\n if (flags.environmentFile) {\n const file = await readAndParseDotEnv(flags.environmentFile);\n\n overriddenEnvironmentVariables = Object.entries(file.variables).map(\n ([key, value]) => ({\n isSecret: true,\n key,\n value,\n }),\n );\n }\n\n initializeBugsnag(flags.disableBugsnag);\n const Bugsnag = getBugsnag();\n\n const deploymentUrl =\n // eslint-disable-next-line no-process-env\n process.env.UNSAFE_OXYGEN_DEPLOYMENT_URL ||\n 'https://oxygen.shopifyapps.com';\n Bugsnag?.addMetadata('flags', {\n flags: {...flags, token: '***'},\n deploymentUrl,\n });\n\n const config: DeploymentConfig = {\n assetsDir: normalizePath(flags.assetsFolder),\n bugsnag: !flags.disableBugsnag,\n buildCommand: flags.buildCommand!,\n deploymentToken: parseToken(flags.token!),\n environmentTag: flags.environmentTag,\n deploymentUrl,\n metadata: {\n description: flags.metadataDescription,\n hydrogenVersion: flags.metadataHydrogenVersion,\n url: flags.metadataUrl,\n user: flags.metadataUser,\n version: flags.metadataVersion,\n },\n defaultEnvironment: flags.defaultEnvironment,\n rootPath,\n skipBuild: flags.skipBuild,\n workerDir: normalizePath(flags.workerFolder),\n workerOnly: flags.workerOnly,\n generateAuthBypassToken: flags.generateAuthBypassToken,\n authBypassTokenDuration: flags.authBypassTokenDuration,\n overriddenEnvironmentVariables,\n };\n\n await verifyConfig({config});\n if (!Deploy.hasCustomBuildCommand && !config.skipBuild) {\n config.buildCommand = getBuildCommandFromLockFile(config);\n }\n await createDeploy({config});\n } catch (error) {\n const Bugsnag = getBugsnag();\n if (Bugsnag && (error instanceof Error || typeof error === 'string')) {\n Bugsnag.notify(error);\n }\n\n if (error instanceof Error) {\n consoleError(error.message);\n } else {\n consoleError(error as string);\n }\n\n this.exit(1);\n }\n }\n}\n"]}
|
1
|
+
{"version":3,"sources":["../../../src/commands/oxygen/deploy.ts"],"names":[],"mappings":"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","file":"deploy.js","sourcesContent":["import {Command, Flags} from '@oclif/core';\nimport {outputWarn} from '@shopify/cli-kit/node/output';\nimport {normalizePath} from '@shopify/cli-kit/node/path';\nimport {readAndParseDotEnv} from '@shopify/cli-kit/node/dot-env';\n\nimport {getBugsnag, initializeBugsnag} from '../../utils/bugsnag.js';\nimport {createDeploy} from '../../deploy/index.js';\nimport {\n deployDefaults,\n getBuildCommandFromLockFile,\n parseToken,\n verifyConfig,\n} from '../../utils/utils.js';\nimport type {\n DeploymentConfig,\n EnvironmentVariable,\n} from '../../deploy/types.js';\n\nexport class Deploy extends Command {\n static description = 'Creates a deployment to Oxygen';\n static hidden = false;\n static flags = {\n assetsFolder: Flags.string({\n char: 'a',\n description: 'Assets folder',\n default: String(deployDefaults.assetsDirDefault),\n required: false,\n }),\n buildCommand: Flags.string({\n char: 'b',\n description: 'Build command',\n required: false,\n default: String(deployDefaults.buildCommandDefault!),\n parse: (input): Promise<string> => {\n this.hasCustomBuildCommand = true;\n return Promise.resolve(input);\n },\n }),\n disableBugsnag: Flags.boolean({\n description: 'Disable Bugsnag error reporting',\n required: false,\n default: false,\n }),\n environmentTag: Flags.string({\n char: 'e',\n description: 'Tag of the environment to deploy to',\n required: false,\n }),\n path: Flags.string({\n char: 'p',\n description: 'Root path',\n default: './',\n required: false,\n }),\n defaultEnvironment: Flags.boolean({\n env: 'OXYGEN_DEFAULT_ENVIRONMENT',\n description: 'Deploys to the default environment of the app',\n required: false,\n default: false,\n }),\n skipBuild: Flags.boolean({\n char: 's',\n description: 'Skip running build command',\n required: false,\n default: false,\n }),\n token: Flags.string({\n char: 't',\n description: 'Oxygen deployment token',\n env: 'OXYGEN_DEPLOYMENT_TOKEN',\n required: true,\n }),\n workerFolder: Flags.string({\n char: 'w',\n description: 'Worker folder',\n default: String(deployDefaults.workerDirDefault),\n required: false,\n }),\n workerOnly: Flags.boolean({\n char: 'o',\n description: 'Worker only deployment',\n default: false,\n required: false,\n }),\n metadataDescription: Flags.string({\n description:\n 'Description of the deployment. Will be saved and displayed in the Shopify admin',\n required: false,\n env: 'OXYGEN_METADATA_DESCRIPTION',\n }),\n metadataHydrogenVersion: Flags.string({\n description: 'The Hydrogen version of the deployment from package.json',\n required: false,\n env: 'OXYGEN_METADATA_HYDROGEN_VERSION',\n }),\n metadataUrl: Flags.string({\n description:\n 'URL that links to the deployment. Will be saved and displayed in the Shopify admin',\n required: false,\n env: 'OXYGEN_METADATA_URL',\n }),\n metadataUser: Flags.string({\n description:\n 'User that initiated the deployment. Will be saved and displayed in the Shopify admin',\n required: false,\n env: 'OXYGEN_METADATA_USER',\n }),\n metadataVersion: Flags.string({\n description:\n 'A version identifier for the deployment. Will be saved and displayed in the Shopify admin',\n required: false,\n env: 'OXYGEN_METADATA_VERSION',\n }),\n generateAuthBypassToken: Flags.boolean({\n description:\n 'Generate an auth bypass token used to perform end-to-end testing against the deployment.',\n required: false,\n default: false,\n }),\n authBypassTokenDuration: Flags.string({\n description:\n 'Specify the duration (in hours) up to 12 hours for the authentication bypass token. Defaults to `2`.',\n required: false,\n dependsOn: ['generateAuthBypassToken'],\n }),\n environmentFile: Flags.string({\n description:\n 'Path to an environment file to override existing environment variables for the deployment.',\n required: false,\n }),\n };\n\n static hasCustomBuildCommand = false;\n\n async run() {\n try {\n const {flags} = await this.parse(Deploy);\n const rootPath = normalizePath(flags.path);\n\n let overriddenEnvironmentVariables: EnvironmentVariable[] | undefined;\n\n if (flags.environmentFile) {\n const file = await readAndParseDotEnv(flags.environmentFile);\n\n overriddenEnvironmentVariables = Object.entries(file.variables).map(\n ([key, value]) => ({\n isSecret: true,\n key,\n value,\n }),\n );\n }\n\n initializeBugsnag(flags.disableBugsnag);\n const Bugsnag = getBugsnag();\n\n const deploymentUrl =\n // eslint-disable-next-line no-process-env\n process.env.UNSAFE_OXYGEN_DEPLOYMENT_URL ||\n 'https://oxygen.shopifyapps.com';\n Bugsnag?.addMetadata('flags', {\n flags: {...flags, token: '***'},\n deploymentUrl,\n });\n\n const config: DeploymentConfig = {\n assetsDir: normalizePath(flags.assetsFolder),\n bugsnag: !flags.disableBugsnag,\n buildCommand: flags.buildCommand!,\n deploymentToken: parseToken(flags.token!),\n environmentTag: flags.environmentTag,\n deploymentUrl,\n metadata: {\n description: flags.metadataDescription,\n hydrogenVersion: flags.metadataHydrogenVersion,\n url: flags.metadataUrl,\n user: flags.metadataUser,\n version: flags.metadataVersion,\n },\n defaultEnvironment: flags.defaultEnvironment,\n rootPath,\n skipBuild: flags.skipBuild,\n workerDir: normalizePath(flags.workerFolder),\n workerOnly: flags.workerOnly,\n generateAuthBypassToken: flags.generateAuthBypassToken,\n authBypassTokenDuration: flags.authBypassTokenDuration,\n overriddenEnvironmentVariables,\n };\n\n await verifyConfig({config});\n if (!Deploy.hasCustomBuildCommand && !config.skipBuild) {\n config.buildCommand = getBuildCommandFromLockFile(config);\n }\n await createDeploy({config});\n } catch (error) {\n const Bugsnag = getBugsnag();\n if (Bugsnag && (error instanceof Error || typeof error === 'string')) {\n Bugsnag.notify(error);\n }\n\n if (error instanceof Error) {\n outputWarn(error.message);\n } else {\n outputWarn(error as string);\n }\n\n this.exit(1);\n }\n }\n}\n"]}
|
@@ -0,0 +1,104 @@
|
|
1
|
+
import { vi, describe, beforeEach, test, expect } from 'vitest';
|
2
|
+
import { outputWarn } from '@shopify/cli-kit/node/output';
|
3
|
+
import { createDeploy } from '../../deploy/index.js';
|
4
|
+
import { verifyConfig } from '../../utils/utils.js';
|
5
|
+
import { getBugsnag } from '../../utils/bugsnag.js';
|
6
|
+
import { Deploy } from './deploy.js';
|
7
|
+
|
8
|
+
vi.mock("@shopify/cli-kit/node/output");
|
9
|
+
vi.mock("../../deploy/index.js");
|
10
|
+
vi.mock("../../utils/utils.js");
|
11
|
+
const mockBugsnag = {
|
12
|
+
notify: vi.fn(),
|
13
|
+
addMetadata: vi.fn()
|
14
|
+
};
|
15
|
+
vi.mock("../../utils/bugsnag.js", () => ({
|
16
|
+
getBugsnag: vi.fn().mockReturnValue(void 0),
|
17
|
+
initializeBugsnag: vi.fn()
|
18
|
+
}));
|
19
|
+
vi.mock("@shopify/cli-kit/node/path", () => ({
|
20
|
+
normalizePath: vi.fn((path) => path)
|
21
|
+
}));
|
22
|
+
vi.mock("@shopify/cli-kit/node/dot-env", () => ({
|
23
|
+
readAndParseDotEnv: vi.fn()
|
24
|
+
}));
|
25
|
+
describe("Deploy command", () => {
|
26
|
+
let deploy;
|
27
|
+
beforeEach(() => {
|
28
|
+
deploy = new Deploy([], {
|
29
|
+
runHook: vi.fn()
|
30
|
+
});
|
31
|
+
vi.clearAllMocks();
|
32
|
+
mockBugsnag.notify.mockClear();
|
33
|
+
mockBugsnag.addMetadata.mockClear();
|
34
|
+
vi.mocked(getBugsnag).mockReturnValue(void 0);
|
35
|
+
});
|
36
|
+
test("should handle errors and call outputWarn", async () => {
|
37
|
+
const errorMessage = "Test deployment error";
|
38
|
+
const error = new Error(errorMessage);
|
39
|
+
vi.spyOn(deploy, "parse").mockResolvedValue({
|
40
|
+
flags: { token: "test-token", path: "./" }
|
41
|
+
});
|
42
|
+
vi.mocked(verifyConfig).mockRejectedValueOnce(error);
|
43
|
+
const exitSpy = vi.spyOn(deploy, "exit").mockImplementation(() => {
|
44
|
+
throw new Error("Process exit called");
|
45
|
+
});
|
46
|
+
await expect(deploy.run()).rejects.toThrow("Process exit called");
|
47
|
+
expect(outputWarn).toHaveBeenCalledWith(errorMessage);
|
48
|
+
expect(exitSpy).toHaveBeenCalledWith(1);
|
49
|
+
});
|
50
|
+
test("should handle string errors and call outputWarn", async () => {
|
51
|
+
const errorMessage = "String error message";
|
52
|
+
vi.spyOn(deploy, "parse").mockResolvedValue({
|
53
|
+
flags: { token: "test-token", path: "./" }
|
54
|
+
});
|
55
|
+
vi.mocked(verifyConfig).mockRejectedValueOnce(errorMessage);
|
56
|
+
const exitSpy = vi.spyOn(deploy, "exit").mockImplementation(() => {
|
57
|
+
throw new Error("Process exit called");
|
58
|
+
});
|
59
|
+
await expect(deploy.run()).rejects.toThrow("Process exit called");
|
60
|
+
expect(outputWarn).toHaveBeenCalledWith(errorMessage);
|
61
|
+
expect(exitSpy).toHaveBeenCalledWith(1);
|
62
|
+
});
|
63
|
+
test("should succeed when deployment completes without errors", async () => {
|
64
|
+
vi.spyOn(deploy, "parse").mockResolvedValue({
|
65
|
+
flags: { token: "test-token", path: "./" }
|
66
|
+
});
|
67
|
+
vi.mocked(verifyConfig).mockResolvedValueOnce(void 0);
|
68
|
+
vi.mocked(createDeploy).mockResolvedValueOnce(void 0);
|
69
|
+
await deploy.run();
|
70
|
+
expect(outputWarn).not.toHaveBeenCalled();
|
71
|
+
});
|
72
|
+
test("should notify Observe when enabled and error occurs", async () => {
|
73
|
+
const errorMessage = "Bugsnag test error";
|
74
|
+
const error = new Error(errorMessage);
|
75
|
+
vi.spyOn(deploy, "parse").mockResolvedValue({
|
76
|
+
flags: { token: "test-token", path: "./", disableBugsnag: false }
|
77
|
+
});
|
78
|
+
vi.mocked(getBugsnag).mockReturnValue(mockBugsnag);
|
79
|
+
vi.mocked(verifyConfig).mockRejectedValueOnce(error);
|
80
|
+
vi.spyOn(deploy, "exit").mockImplementation(() => {
|
81
|
+
throw new Error("Process exit called");
|
82
|
+
});
|
83
|
+
await expect(deploy.run()).rejects.toThrow("Process exit called");
|
84
|
+
expect(mockBugsnag.notify).toHaveBeenCalledWith(error);
|
85
|
+
expect(outputWarn).toHaveBeenCalledWith(errorMessage);
|
86
|
+
});
|
87
|
+
test("should not notify Observe when disabled", async () => {
|
88
|
+
const errorMessage = "No Bugsnag test error";
|
89
|
+
const error = new Error(errorMessage);
|
90
|
+
vi.spyOn(deploy, "parse").mockResolvedValue({
|
91
|
+
flags: { token: "test-token", path: "./", disableBugsnag: true }
|
92
|
+
});
|
93
|
+
vi.mocked(getBugsnag).mockReturnValue(void 0);
|
94
|
+
vi.mocked(verifyConfig).mockRejectedValueOnce(error);
|
95
|
+
vi.spyOn(deploy, "exit").mockImplementation(() => {
|
96
|
+
throw new Error("Process exit called");
|
97
|
+
});
|
98
|
+
await expect(deploy.run()).rejects.toThrow("Process exit called");
|
99
|
+
expect(mockBugsnag.notify).not.toHaveBeenCalled();
|
100
|
+
expect(outputWarn).toHaveBeenCalledWith(errorMessage);
|
101
|
+
});
|
102
|
+
});
|
103
|
+
//# sourceMappingURL=deploy.test.js.map
|
104
|
+
//# sourceMappingURL=deploy.test.js.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"sources":["../../../src/commands/oxygen/deploy.test.ts"],"names":[],"mappings":"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","file":"deploy.test.js","sourcesContent":["import {expect, describe, test, vi, beforeEach} from 'vitest';\nimport {outputWarn} from '@shopify/cli-kit/node/output';\n\nimport {createDeploy} from '../../deploy/index.js';\nimport {verifyConfig} from '../../utils/utils.js';\nimport {getBugsnag} from '../../utils/bugsnag.js';\n\nimport {Deploy} from './deploy.js';\n\nvi.mock('@shopify/cli-kit/node/output');\nvi.mock('../../deploy/index.js');\nvi.mock('../../utils/utils.js');\nconst mockBugsnag = {\n notify: vi.fn(),\n addMetadata: vi.fn(),\n};\n\nvi.mock('../../utils/bugsnag.js', () => ({\n getBugsnag: vi.fn().mockReturnValue(undefined),\n initializeBugsnag: vi.fn(),\n}));\nvi.mock('@shopify/cli-kit/node/path', () => ({\n normalizePath: vi.fn((path: string) => path),\n}));\nvi.mock('@shopify/cli-kit/node/dot-env', () => ({\n readAndParseDotEnv: vi.fn(),\n}));\n\ndescribe('Deploy command', () => {\n let deploy: Deploy;\n\n beforeEach(() => {\n deploy = new Deploy([], {\n runHook: vi.fn(),\n } as any);\n vi.clearAllMocks();\n mockBugsnag.notify.mockClear();\n mockBugsnag.addMetadata.mockClear();\n\n vi.mocked(getBugsnag).mockReturnValue(undefined);\n });\n\n test('should handle errors and call outputWarn', async () => {\n const errorMessage = 'Test deployment error';\n const error = new Error(errorMessage);\n\n vi.spyOn(deploy, 'parse' as any).mockResolvedValue({\n flags: {token: 'test-token', path: './'},\n } as any);\n\n vi.mocked(verifyConfig).mockRejectedValueOnce(error);\n\n const exitSpy = vi.spyOn(deploy, 'exit').mockImplementation(() => {\n throw new Error('Process exit called');\n });\n\n await expect(deploy.run()).rejects.toThrow('Process exit called');\n\n expect(outputWarn).toHaveBeenCalledWith(errorMessage);\n expect(exitSpy).toHaveBeenCalledWith(1);\n });\n\n test('should handle string errors and call outputWarn', async () => {\n const errorMessage = 'String error message';\n\n vi.spyOn(deploy, 'parse' as any).mockResolvedValue({\n flags: {token: 'test-token', path: './'},\n } as any);\n\n vi.mocked(verifyConfig).mockRejectedValueOnce(errorMessage);\n\n const exitSpy = vi.spyOn(deploy, 'exit').mockImplementation(() => {\n throw new Error('Process exit called');\n });\n\n await expect(deploy.run()).rejects.toThrow('Process exit called');\n\n expect(outputWarn).toHaveBeenCalledWith(errorMessage);\n expect(exitSpy).toHaveBeenCalledWith(1);\n });\n\n test('should succeed when deployment completes without errors', async () => {\n vi.spyOn(deploy, 'parse' as any).mockResolvedValue({\n flags: {token: 'test-token', path: './'},\n } as any);\n\n vi.mocked(verifyConfig).mockResolvedValueOnce(undefined);\n vi.mocked(createDeploy).mockResolvedValueOnce(undefined);\n\n await deploy.run();\n\n expect(outputWarn).not.toHaveBeenCalled();\n });\n\n test('should notify Observe when enabled and error occurs', async () => {\n const errorMessage = 'Bugsnag test error';\n const error = new Error(errorMessage);\n\n vi.spyOn(deploy, 'parse' as any).mockResolvedValue({\n flags: {token: 'test-token', path: './', disableBugsnag: false},\n } as any);\n\n vi.mocked(getBugsnag).mockReturnValue(mockBugsnag as any);\n vi.mocked(verifyConfig).mockRejectedValueOnce(error);\n\n vi.spyOn(deploy, 'exit').mockImplementation(() => {\n throw new Error('Process exit called');\n });\n\n await expect(deploy.run()).rejects.toThrow('Process exit called');\n\n expect(mockBugsnag.notify).toHaveBeenCalledWith(error);\n expect(outputWarn).toHaveBeenCalledWith(errorMessage);\n });\n\n test('should not notify Observe when disabled', async () => {\n const errorMessage = 'No Bugsnag test error';\n const error = new Error(errorMessage);\n\n vi.spyOn(deploy, 'parse' as any).mockResolvedValue({\n flags: {token: 'test-token', path: './', disableBugsnag: true},\n } as any);\n\n vi.mocked(getBugsnag).mockReturnValue(undefined);\n vi.mocked(verifyConfig).mockRejectedValueOnce(error);\n\n vi.spyOn(deploy, 'exit').mockImplementation(() => {\n throw new Error('Process exit called');\n });\n\n await expect(deploy.run()).rejects.toThrow('Process exit called');\n\n expect(mockBugsnag.notify).not.toHaveBeenCalled();\n expect(outputWarn).toHaveBeenCalledWith(errorMessage);\n });\n});\n"]}
|
@@ -1,5 +1,6 @@
|
|
1
1
|
import { spawn } from 'child_process';
|
2
2
|
import { PassThrough } from 'stream';
|
3
|
+
import { AbortError } from '@shopify/cli-kit/node/error';
|
3
4
|
import { getBugsnag } from '../utils/bugsnag.js';
|
4
5
|
import { MetricName } from '../utils/metrics-exporter.js';
|
5
6
|
|
@@ -14,7 +15,7 @@ async function buildProject(options) {
|
|
14
15
|
performance.now() - startTime
|
15
16
|
);
|
16
17
|
}).catch((error) => {
|
17
|
-
throw new
|
18
|
+
throw new AbortError(`Build function failed with error: ${error}`);
|
18
19
|
});
|
19
20
|
}
|
20
21
|
const assetPathEnvironment = assetPath ? { HYDROGEN_ASSET_BASE_URL: assetPath } : {};
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"sources":["../../src/deploy/build-project.ts"],"names":[],"mappings":"
|
1
|
+
{"version":3,"sources":["../../src/deploy/build-project.ts"],"names":[],"mappings":";;;;;;AAiBA,eAAsB,aAAa,OAA8B,EAAA;AAC/D,EAAA,MAAM,EAAC,MAAA,EAAQ,SAAW,EAAA,KAAA,EAAS,GAAA,OAAA;AACnC,EAAA,MAAM,UAAU,UAAW,EAAA;AAE3B,EAAA,IAAI,OAAO,aAAe,EAAA;AACxB,IAAM,MAAA,SAAA,GAAY,YAAY,GAAI,EAAA;AAClC,IAAA,OAAO,KACJ,CAAA,aAAA,CAAc,SAAS,CAAA,CACvB,KAAK,MAAM;AACV,MAAA,OAAA,CAAQ,eAAiB,EAAA,GAAA;AAAA,QACvB,UAAW,CAAA,SAAA;AAAA,QACX,WAAA,CAAY,KAAQ,GAAA;AAAA,OACtB;AAAA,KACD,CAAA,CACA,KAAM,CAAA,CAAC,KAAU,KAAA;AAChB,MAAA,MAAM,IAAI,UAAA,CAAW,CAAqC,kCAAA,EAAA,KAAK,CAAE,CAAA,CAAA;AAAA,KAClE,CAAA;AAAA;AAGL,EAAA,MAAM,uBAAuB,SACzB,GAAA,EAAC,uBAAyB,EAAA,SAAA,KAC1B,EAAC;AACL,EAAI,IAAA;AACF,IAAA,MAAM,IAAI,OAAA,CAAQ,CAAC,OAAA,EAAS,MAAW,KAAA;AACrC,MAAA,IAAI,MAAS,GAAA,EAAA;AACb,MAAM,MAAA,YAAA,GAAe,IAAI,WAAY,EAAA;AAErC,MAAa,YAAA,CAAA,EAAA,CAAG,MAAQ,EAAA,CAAC,KAAU,KAAA;AACjC,QAAU,MAAA,IAAA,KAAA;AACV,QAAQ,OAAA,CAAA,MAAA,CAAO,MAAM,KAAK,CAAA;AAAA,OAC3B,CAAA;AAED,MAAM,MAAA,SAAA,GAAY,YAAY,GAAI,EAAA;AAClC,MAAA,MAAM,YAAe,GAAA,KAAA,CAAM,MAAO,CAAA,YAAA,EAAe,EAAI,EAAA;AAAA,QACnD,KAAO,EAAA,CAAC,SAAW,EAAA,MAAA,EAAQ,MAAM,CAAA;AAAA,QACjC,GAAK,EAAA;AAAA;AAAA,UAEH,GAAG,OAAQ,CAAA,GAAA;AAAA,UACX,GAAG;AAAA,SACL;AAAA,QACA,KAAK,MAAO,CAAA,QAAA;AAAA,QACZ,KAAO,EAAA;AAAA,OACR,CAAA;AAED,MAAC,YAAA,CAAa,MAA4B,EAAA,IAAA,CAAK,YAAY,CAAA;AAC3D,MAAC,YAAA,CAAa,MAA4B,EAAA,IAAA,CAAK,YAAY,CAAA;AAE3D,MAAa,YAAA,CAAA,EAAA,CAAG,OAAS,EAAA,CAAC,IAAS,KAAA;AACjC,QAAA,IAAI,SAAS,CAAG,EAAA;AACd,UAAA,OAAA,CAAQ,eAAiB,EAAA,GAAA;AAAA,YACvB,UAAW,CAAA,SAAA;AAAA,YACX,WAAA,CAAY,KAAQ,GAAA;AAAA,WACtB;AAAA;AAEF,QAAA,OAAA,EAAS,YAAY,cAAgB,EAAA;AAAA,UACnC,SAAS,MAAO,CAAA,YAAA;AAAA,UAChB,MAAA;AAAA,UACA;AAAA,SACD,CAAA;AACD,QAAA,IAAI,SAAS,CAAG,EAAA;AACd,UAAA,MAAA,CAAO,IAAI,CAAA;AACX,UAAA;AAAA;AAEF,QAAA,OAAA,CAAQ,IAAI,CAAA;AAAA,OACb,CAAA;AAAA,KACF,CAAA;AAAA,WACM,KAAO,EAAA;AACd,IAAA,MAAM,IAAI,KAAA,CAAM,CAAiC,8BAAA,EAAA,KAAK,CAAE,CAAA,CAAA;AAAA;AAE5D","file":"build-project.js","sourcesContent":["import {spawn} from 'child_process';\nimport {PassThrough, Readable} from 'stream';\n\nimport {AbortError} from '@shopify/cli-kit/node/error';\n\nimport {getBugsnag} from '../utils/bugsnag.js';\nimport {MetricsExporter, MetricName} from '../utils/metrics-exporter.js';\n\nimport {DeploymentConfig, DeploymentHooks} from './types.js';\n\ninterface BuildProjectOptions {\n config: DeploymentConfig;\n assetPath?: string;\n hooks?: DeploymentHooks;\n metricsExporter?: MetricsExporter;\n}\n\nexport async function buildProject(options: BuildProjectOptions) {\n const {config, assetPath, hooks} = options;\n const Bugsnag = getBugsnag();\n\n if (hooks?.buildFunction) {\n const startTime = performance.now();\n return hooks\n .buildFunction(assetPath)\n .then(() => {\n options.metricsExporter?.add(\n MetricName.BuildTime,\n performance.now() - startTime,\n );\n })\n .catch((error) => {\n throw new AbortError(`Build function failed with error: ${error}`);\n });\n }\n\n const assetPathEnvironment = assetPath\n ? {HYDROGEN_ASSET_BASE_URL: assetPath}\n : {};\n try {\n await new Promise((resolve, reject) => {\n let stderr = '';\n const stderrStream = new PassThrough();\n\n stderrStream.on('data', (chunk) => {\n stderr += chunk;\n process.stderr.write(chunk);\n });\n\n const startTime = performance.now();\n const buildCommand = spawn(config.buildCommand!, [], {\n stdio: ['inherit', 'pipe', 'pipe'],\n env: {\n // eslint-disable-next-line no-process-env\n ...process.env,\n ...assetPathEnvironment,\n },\n cwd: config.rootPath,\n shell: true,\n });\n\n (buildCommand.stderr as Readable | null)?.pipe(stderrStream);\n (buildCommand.stdout as Readable | null)?.pipe(stderrStream);\n\n buildCommand.on('close', (code) => {\n if (code === 0) {\n options.metricsExporter?.add(\n MetricName.BuildTime,\n performance.now() - startTime,\n );\n }\n Bugsnag?.addMetadata('buildCommand', {\n command: config.buildCommand,\n stderr,\n code,\n });\n if (code !== 0) {\n reject(code);\n return;\n }\n resolve(code);\n });\n });\n } catch (error) {\n throw new Error(`Build failed with error code: ${error}`);\n }\n}\n"]}
|
package/oclif.manifest.json
CHANGED
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": "6.0.0",
|
9
9
|
"type": "module",
|
10
10
|
"scripts": {
|
11
11
|
"build": "tsup --sourcemap --clean --config ./tsup.config.ts && oclif manifest",
|
@@ -49,18 +49,19 @@
|
|
49
49
|
"devDependencies": {
|
50
50
|
"@bugsnag/source-maps": "^2.3.3",
|
51
51
|
"@changesets/cli": "^2.29.5",
|
52
|
-
"@shopify/eslint-plugin": "^
|
52
|
+
"@shopify/eslint-plugin": "^50.0.0",
|
53
53
|
"@shopify/prettier-config": "^1.1.4",
|
54
54
|
"@types/async": "^3.2.24",
|
55
|
-
"@types/node": "^
|
56
|
-
"eslint": "^
|
55
|
+
"@types/node": "^24.1.0",
|
56
|
+
"eslint": "^9.32.0",
|
57
|
+
"eslint-import-resolver-node": "^0.3.9",
|
57
58
|
"eslint-plugin-node": "^11.1.0",
|
58
|
-
"eslint-plugin-prettier": "^5.5.
|
59
|
+
"eslint-plugin-prettier": "^5.5.3",
|
59
60
|
"node-fetch": "^3.3.2",
|
60
61
|
"oclif": "^4",
|
61
62
|
"tsup": "^8.5.0",
|
62
63
|
"typescript": "^5.8.3",
|
63
|
-
"vite": "^
|
64
|
+
"vite": "^7.0.3",
|
64
65
|
"vitest": "^3.2.4"
|
65
66
|
},
|
66
67
|
"prettier": "@shopify/prettier-config",
|