Skip to content

Commit a90d0b5

Browse files
feat(cli): on update process add flag to opt-out from publishing (#415)
* feat(CLI): on update process add flag to opt-out from publishing * feat(CLI): comment * feat(CLI): update help comment * Update packages/cli/src/main.ts Co-authored-by: Demetrius Feijóo <[email protected]> * feat(CLI): remove --publish * feat(CLI): test fix * feat(CLI): test regrouping + --no-publish test --------- Co-authored-by: Demetrius Feijóo <[email protected]>
1 parent da3abc4 commit a90d0b5

File tree

4 files changed

+100
-42
lines changed

4 files changed

+100
-42
lines changed

packages/cli/src/__tests__/main.test.ts

Lines changed: 53 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,53 @@
11
import { createCLI } from '../main'
22
import { create, add, deploy } from '../commands'
3-
import { vi } from 'vitest'
3+
import { describe, vi } from 'vitest'
44

55
vi.mock('../commands')
66

77
const DEFAULT_ARGS = ['node', 'main.ts'] // cli.parse() should receive the executable and its arget as its first two arguments.
88

99
describe('main', () => {
10-
describe('default arguments', () => {
11-
it('create command', () => {
12-
const cli = createCLI()
13-
cli.parse([...DEFAULT_ARGS, 'create'])
14-
expect(create).toHaveBeenCalledWith({ dir: '.' })
15-
})
16-
17-
it('add command', () => {
10+
describe('add command', () => {
11+
it('default arguments', () => {
1812
const cli = createCLI()
1913
cli.parse([...DEFAULT_ARGS, 'add'])
2014
expect(add).toHaveBeenCalledWith({ dir: '.' })
2115
})
2216

23-
it('deploy command', () => {
17+
it('full arguments', () => {
2418
const cli = createCLI()
25-
cli.parse([...DEFAULT_ARGS, 'deploy'])
26-
expect(deploy).toHaveBeenCalledWith({ dir: '.', skipPrompts: false })
19+
cli.parse([
20+
...DEFAULT_ARGS,
21+
'add',
22+
'--template',
23+
'react',
24+
'--name',
25+
'my-test-plugin',
26+
'--dir',
27+
'my-directory',
28+
'--structure',
29+
'standalone',
30+
'--packageManager',
31+
'npm',
32+
])
33+
expect(add).toHaveBeenCalledWith({
34+
template: 'react',
35+
name: 'my-test-plugin',
36+
dir: 'my-directory',
37+
structure: 'standalone',
38+
packageManager: 'npm',
39+
})
2740
})
2841
})
2942

30-
describe('full arguments', () => {
31-
it('create command', () => {
43+
describe('create command', () => {
44+
it('default arguments', () => {
45+
const cli = createCLI()
46+
cli.parse([...DEFAULT_ARGS, 'create'])
47+
expect(create).toHaveBeenCalledWith({ dir: '.' })
48+
})
49+
50+
it('full arguments', () => {
3251
const cli = createCLI()
3352
cli.parse([
3453
...DEFAULT_ARGS,
@@ -49,33 +68,30 @@ describe('main', () => {
4968
repoName: 'my-test-repo',
5069
})
5170
})
71+
})
5272

53-
it('add command', () => {
73+
describe('deploy command', () => {
74+
it('--no-publish', () => {
5475
const cli = createCLI()
55-
cli.parse([
56-
...DEFAULT_ARGS,
57-
'add',
58-
'--template',
59-
'react',
60-
'--name',
61-
'my-test-plugin',
62-
'--dir',
63-
'my-directory',
64-
'--structure',
65-
'standalone',
66-
'--packageManager',
67-
'npm',
68-
])
69-
expect(add).toHaveBeenCalledWith({
70-
template: 'react',
71-
name: 'my-test-plugin',
72-
dir: 'my-directory',
73-
structure: 'standalone',
74-
packageManager: 'npm',
76+
cli.parse([...DEFAULT_ARGS, 'deploy', '--no-publish'])
77+
expect(deploy).toHaveBeenCalledWith({
78+
dir: '.',
79+
publish: false,
80+
skipPrompts: false,
81+
})
82+
})
83+
84+
it('default options', () => {
85+
const cli = createCLI()
86+
cli.parse([...DEFAULT_ARGS, 'deploy'])
87+
expect(deploy).toHaveBeenCalledWith({
88+
dir: '.',
89+
skipPrompts: false,
90+
publish: true,
7591
})
7692
})
7793

78-
it('deploy command', () => {
94+
it('full arguments', () => {
7995
const cli = createCLI()
8096
cli.parse([
8197
...DEFAULT_ARGS,
@@ -100,6 +116,7 @@ describe('main', () => {
100116
name: 'my-test-plugin',
101117
output: './dist/index.js',
102118
dir: 'my-directory',
119+
publish: true,
103120
dotEnvPath: '.',
104121
scope: 'my-plugins',
105122
})

packages/cli/src/commands/deploy/helper.ts

Lines changed: 39 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -26,12 +26,13 @@ const packageNameMessage =
2626
'How would you like to call the deployed field-plugin?\n (Lowercase alphanumeric and dash are allowed.)'
2727

2828
type UpsertFieldPluginFunc = (args: {
29+
scope: Scope
30+
token: string
2931
dir: string
3032
packageName: string
31-
skipPrompts?: boolean
32-
token: string
3333
output: string
34-
scope: Scope
34+
skipPrompts: undefined | boolean
35+
publish: boolean
3536
}) => Promise<{ id: number }>
3637

3738
type GetPackageName = (params: {
@@ -42,7 +43,7 @@ type GetPackageName = (params: {
4243

4344
// TODO: move all side effects to the deploy function
4445
export const upsertFieldPlugin: UpsertFieldPluginFunc = async (args) => {
45-
const { packageName, skipPrompts, token, output, dir, scope } = args
46+
const { packageName, skipPrompts, token, output, dir, scope, publish } = args
4647

4748
const manifest = loadManifest()
4849

@@ -78,9 +79,11 @@ export const upsertFieldPlugin: UpsertFieldPluginFunc = async (args) => {
7879
await confirmOptionsUpdate(manifest?.options)
7980
}
8081

82+
const shouldPublish = await checkPublish({ publish, skipPrompts })
83+
8184
await storyblokClient.updateFieldType({
8285
id: fieldPluginFound.id,
83-
publish: true,
86+
publish: shouldPublish,
8487
field_type: {
8588
body: output,
8689
options: manifest?.options,
@@ -378,6 +381,7 @@ export const createFieldPlugin = async (
378381
//we need to force an update call right after the creation.
379382
//If no options is found, it's not going to be sent to the API since undefined
380383
//properties are not encoded.
384+
//NOTE: The `publish` property is set to true here because it is a part of the creation process and should provide a consistent flow.
381385
await client.updateFieldType({
382386
id: fieldPlugin.id,
383387
publish: true,
@@ -414,3 +418,33 @@ export const createFieldPlugin = async (
414418
)
415419
}
416420
}
421+
422+
// Publish Logic
423+
424+
type CheckPublish = (params: {
425+
publish: boolean
426+
skipPrompts: undefined | boolean
427+
}) => Promise<boolean>
428+
429+
export const checkPublish: CheckPublish = async ({ publish, skipPrompts }) => {
430+
if (skipPrompts === true || publish === false) {
431+
return publish
432+
}
433+
434+
//NOTE: In interactive mode where --no-publish is not provided, the user is asked to confirm the publish action.
435+
const publishConfirmation = await confirmPublish()
436+
return publishConfirmation
437+
}
438+
439+
const confirmPublish = async (): Promise<boolean> => {
440+
const { publish } = await betterPrompts<{
441+
publish: boolean
442+
}>({
443+
type: 'confirm',
444+
name: 'publish',
445+
message: 'Do you want to publish a new version of the field plugin?',
446+
initial: false,
447+
})
448+
449+
return publish
450+
}

packages/cli/src/commands/deploy/index.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import { Scope } from '../../storyblok/storyblok-client'
1515
export type DeployArgs = {
1616
skipPrompts: boolean
1717
dir: string
18+
publish: boolean
1819
name: undefined | string
1920
token: undefined | string
2021
output: undefined | string
@@ -25,7 +26,8 @@ export type DeployArgs = {
2526
type DeployFunc = (args: DeployArgs) => Promise<void>
2627

2728
export const deploy: DeployFunc = async (params) => {
28-
const { skipPrompts, token, name, dir, output, dotEnvPath, scope } = params
29+
const { skipPrompts, token, name, dir, output, publish, dotEnvPath, scope } =
30+
params
2931

3032
console.log(bold(cyan('\nWelcome!')))
3133
console.log("Let's deploy a field-plugin.\n")
@@ -106,6 +108,7 @@ export const deploy: DeployFunc = async (params) => {
106108
token: personalAccessTokenResult.token,
107109
output: outputFile,
108110
scope: apiScope,
111+
publish,
109112
})
110113

111114
console.log(

packages/cli/src/main.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,10 @@ export const createCLI = () => {
6060
'--name <value>',
6161
'name of plugin (Lowercase alphanumeric and dash)',
6262
)
63+
.option(
64+
'--no-publish',
65+
'This flag is only applied when a plugin is being updated! Uploads field plugin but does not publish a new version.',
66+
)
6367
.addOption(
6468
new Option(
6569
'--output <value>',

0 commit comments

Comments
 (0)