Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/hydrogen-deploy-allow-non-preview.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@shopify/cli-hydrogen': patch
---

Skip confirmation before deploying to non-preview environments with `--force`.
5 changes: 5 additions & 0 deletions .changeset/hydrogen-link-create-flags.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@shopify/cli-hydrogen': patch
---

Add noninteractive shop and storefront creation flags to `hydrogen link`.
36 changes: 35 additions & 1 deletion packages/cli/oclif.manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -353,7 +353,7 @@
},
"force": {
"char": "f",
"description": "Forces a deployment to proceed if there are uncommitted changes in its Git repository.",
"description": "Forces a deployment to proceed if there are uncommitted changes in its Git repository, and skips confirmation prompts for non-preview environments.",
"env": "SHOPIFY_HYDROGEN_FLAG_FORCE",
"name": "force",
"required": false,
Expand Down Expand Up @@ -1150,13 +1150,47 @@
"multiple": false,
"type": "option"
},
"shop": {
"char": "s",
"description": "Shop URL. It can be the shop prefix (janes-apparel) or the full myshopify.com URL (janes-apparel.myshopify.com, https://janes-apparel.myshopify.com).",
"env": "SHOPIFY_SHOP",
"name": "shop",
"hasDynamicHelp": false,
"multiple": false,
"type": "option"
},
"storefront": {
"description": "The name of a Hydrogen Storefront (e.g. \"Jane's Apparel\")",
"env": "SHOPIFY_HYDROGEN_STOREFRONT",
"exclusive": [
"create-storefront",
"name"
],
"name": "storefront",
"hasDynamicHelp": false,
"multiple": false,
"type": "option"
},
"create-storefront": {
"description": "Create a new Hydrogen storefront.",
"env": "SHOPIFY_HYDROGEN_FLAG_CREATE_STOREFRONT",
"exclusive": [
"storefront"
],
"name": "create-storefront",
"allowNo": false,
"type": "boolean"
},
"name": {
"description": "The name to use when creating a new Hydrogen storefront.",
"env": "SHOPIFY_HYDROGEN_FLAG_NAME",
"exclusive": [
"storefront"
],
"name": "name",
"hasDynamicHelp": false,
"multiple": false,
"type": "option"
}
},
"hasDynamicHelp": false,
Expand Down
75 changes: 51 additions & 24 deletions packages/cli/src/commands/hydrogen/deploy.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -201,13 +201,16 @@ describe('deploy', async () => {
defaultEnvironment: false,
deploymentUrl: 'https://oxygen.shopifyapps.com',
deploymentToken: mockToken,
environmentTag: undefined,
generateAuthBypassToken: true,
authBypassTokenDuration: undefined,
verificationMaxDuration: 180,
metadata: {
url: deployParams.metadataUrl,
user: deployParams.metadataUser,
version: deployParams.metadataVersion,
},
overriddenEnvironmentVariables: undefined,
skipVerification: true,
rootPath: deployParams.path,
skipBuild: false,
Expand All @@ -227,6 +230,16 @@ describe('deploy', async () => {
onUploadFilesError: expect.any(Function),
};

function expectDeployConfig({
metadata,
...rest
}: Record<string, unknown> & {metadata?: Record<string, unknown>}) {
return expect.objectContaining({
...rest,
...(metadata ? {metadata: expect.objectContaining(metadata)} : {}),
});
}

beforeEach(async () => {
process.exit = vi.fn() as any;
vi.mocked(login).mockResolvedValue({
Expand Down Expand Up @@ -276,7 +289,7 @@ describe('deploy', async () => {
await runDeploy(deployParams);

expect(vi.mocked(createDeploy)).toHaveBeenCalledWith({
config: expectedConfig,
config: expectDeployConfig(expectedConfig),
hooks: expectedHooks,
logger: deploymentLogger,
});
Expand All @@ -293,12 +306,12 @@ describe('deploy', async () => {
});

expect(vi.mocked(createDeploy)).toHaveBeenCalledWith({
config: {
config: expectDeployConfig({
...expectedConfig,
assetsDir: 'custom/client',
workerDir: 'custom/server',
buildCommand: 'node --run build',
},
}),
hooks,
logger: deploymentLogger,
});
Expand Down Expand Up @@ -386,7 +399,7 @@ describe('deploy', async () => {
});

expect(vi.mocked(createDeploy)).toHaveBeenCalledWith({
config: {
config: expectDeployConfig({
...expectedConfig,
overriddenEnvironmentVariables: [
{
Expand All @@ -395,7 +408,7 @@ describe('deploy', async () => {
isSecret: true,
},
],
},
}),
hooks: expectedHooks,
logger: deploymentLogger,
});
Expand Down Expand Up @@ -442,10 +455,10 @@ describe('deploy', async () => {
});

expect(vi.mocked(createDeploy)).toHaveBeenCalledWith({
config: {
config: expectDeployConfig({
...expectedConfig,
environmentTag: 'stage-1',
},
}),
hooks: expectedHooks,
logger: deploymentLogger,
});
Expand Down Expand Up @@ -473,10 +486,10 @@ describe('deploy', async () => {
});

expect(vi.mocked(createDeploy)).toHaveBeenCalledWith({
config: {
config: expectDeployConfig({
...expectedConfig,
environmentTag: 'stage-1',
},
}),
hooks: expectedHooks,
logger: deploymentLogger,
});
Expand All @@ -497,10 +510,10 @@ describe('deploy', async () => {
});

expect(vi.mocked(createDeploy)).toHaveBeenCalledWith({
config: {
config: expectDeployConfig({
...expectedConfig,
environmentTag: 'stage-1',
},
}),
hooks: expectedHooks,
logger: deploymentLogger,
});
Expand Down Expand Up @@ -610,14 +623,14 @@ describe('deploy', async () => {
body: expect.anything(),
});
expect(vi.mocked(createDeploy)).toHaveBeenCalledWith({
config: {
config: expectDeployConfig({
...expectedConfig,
environmentTag: 'main',
metadata: {
...expectedConfig.metadata,
description: '123 with additional changes',
},
},
}),
hooks: expectedHooks,
logger: deploymentLogger,
});
Expand Down Expand Up @@ -646,14 +659,14 @@ describe('deploy', async () => {

expect(vi.mocked(renderWarning)).not.toHaveBeenCalled;
expect(vi.mocked(createDeploy)).toHaveBeenCalledWith({
config: {
config: expectDeployConfig({
...expectedConfig,
environmentTag: 'main',
metadata: {
...expectedConfig.metadata,
description: 'cool new stuff',
},
},
}),
hooks: expectedHooks,
logger: deploymentLogger,
});
Expand All @@ -676,7 +689,7 @@ describe('deploy', async () => {
await runDeploy(deployParams);

expect(vi.mocked(createDeploy)).toHaveBeenCalledWith({
config: {...expectedConfig, environmentTag: 'main'},
config: expectDeployConfig({...expectedConfig, environmentTag: 'main'}),
hooks: expectedHooks,
logger: deploymentLogger,
});
Expand Down Expand Up @@ -758,11 +771,11 @@ describe('deploy', async () => {
await runDeploy(deployParams);

expect(vi.mocked(createDeploy)).toHaveBeenCalledWith({
config: {
config: expectDeployConfig({
...expectedConfig,
defaultEnvironment: true,
environmentTag: undefined,
},
}),
hooks: expectedHooks,
logger: deploymentLogger,
});
Expand Down Expand Up @@ -830,10 +843,10 @@ describe('deploy', async () => {
await runDeploy(params);

expect(vi.mocked(createDeploy)).toHaveBeenCalledWith({
config: {
config: expectDeployConfig({
...expectedConfig,
buildCommand: 'hocus pocus',
},
}),
hooks,
logger: deploymentLogger,
});
Expand All @@ -848,15 +861,15 @@ describe('deploy', async () => {
await runDeploy({...deployParams, path: root});

expect(vi.mocked(createDeploy)).toHaveBeenCalledWith({
config: {
config: expectDeployConfig({
...expectedConfig,
rootPath: root,
buildCommand: 'node --run build',
metadata: {
...expectedConfig.metadata,
hydrogenVersion,
},
},
}),
hooks,
logger: deploymentLogger,
});
Expand All @@ -879,7 +892,7 @@ describe('deploy', async () => {
await runDeploy(params);

expect(vi.mocked(createDeploy)).toHaveBeenCalledWith({
config: {
config: expectDeployConfig({
...expectedConfig,
rootPath: root,
assetsDir: 'xyz/client',
Expand All @@ -890,7 +903,7 @@ describe('deploy', async () => {
user: deployParams.metadataUser,
version: deployParams.metadataVersion,
},
},
}),
hooks,
logger: deploymentLogger,
});
Expand Down Expand Up @@ -1079,6 +1092,20 @@ describe('deploy', async () => {
message: expect.any(String),
});
});

it("doesn't render a user confirmation on deploy when the force flag is provided", async () => {
await runDeploy({
...deployParams,
env: 'production',
force: true,
});

expect(renderConfirmationPrompt).not.toHaveBeenCalledWith({
confirmationMessage: 'Yes, confirm deploy',
cancellationMessage: 'No, cancel deploy',
message: expect.any(String),
});
});
});

describe('user provides a preview environment', () => {
Expand Down
9 changes: 5 additions & 4 deletions packages/cli/src/commands/hydrogen/deploy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ export default class Deploy extends Command {
force: Flags.boolean({
char: 'f',
description:
'Forces a deployment to proceed if there are uncommitted changes in its Git repository.',
'Forces a deployment to proceed if there are uncommitted changes in its Git repository, and skips confirmation prompts for non-preview environments.',
default: false,
env: 'SHOPIFY_HYDROGEN_FLAG_FORCE',
required: false,
Expand Down Expand Up @@ -266,7 +266,7 @@ export async function runDeploy(
env: envHandle,
envBranch,
environmentFile,
force: forceOnUncommittedChanges,
force,
forceClientSourcemap = false,
noVerify,
lockfileCheck,
Expand All @@ -290,7 +290,7 @@ export async function runDeploy(
isCleanGit = false;
}

if (!forceOnUncommittedChanges && !isCleanGit) {
if (!force && !isCleanGit) {
let errorMessage = 'Uncommitted changes detected';
let changedFiles = undefined;

Expand Down Expand Up @@ -540,7 +540,8 @@ export async function runDeploy(
if (
!isCI &&
!config.defaultEnvironment &&
(userProvidedEnvironmentTag || userChosenEnvironmentTag)
(userProvidedEnvironmentTag || userChosenEnvironmentTag) &&
!force
) {
let chosenEnvironment = findEnvironmentByBranchOrThrow(
deploymentData!.environments!,
Expand Down
Loading
Loading