@raisenow/tamaro-cli 1.0.6 → 1.0.10

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/readme.md ADDED
@@ -0,0 +1,227 @@
1
+ # Getting started
2
+
3
+ It’s a command-line interface for all operations with Tamaro customer configurations and _Tamaro Core_.
4
+
5
+ You don’t need to install it manually. The recommended way to run it is by using the `npx` command, which comes along with NPM.
6
+
7
+ # Usage
8
+
9
+ To see an overview of all possible commands just run the following command without any arguments.
10
+
11
+ ```bash
12
+ npx -y @raisenow/tamaro-cli
13
+ ```
14
+
15
+ To see the informoation about some particular command (for example `dev` command), prepend `help` before the command name:
16
+
17
+ ```bash
18
+ npx -y @raisenow/tamaro-cli help dev
19
+ ```
20
+
21
+ Substitute `dev` with the command you want to get information about.
22
+
23
+ # Commands
24
+
25
+ Available commands:
26
+
27
+ - [`dev`](#dev)
28
+ - [`build`](#build)
29
+ - [`deploy`](#deploy)
30
+ - [`serve`](#serve)
31
+ - [`list-deployed`](#list-deployed)
32
+ - [`deploy-email-config`](#deploy-email-config)
33
+
34
+ ## `dev`
35
+
36
+ Runs the local development server for _Tamaro Core_ or a particular customer configuration.
37
+
38
+ ### Options
39
+
40
+ - `--local-core` – Load _Tamaro Core_ from localhost instead of the CDN
41
+
42
+ ### Run local server using Tamaro Core from CDN
43
+
44
+ Run the local development server for the _example-02-typical-customisations_ customer configuration. You will be able to access Tamaro on http://localhost:1234 (port may differ, see console output).
45
+
46
+ ```bash
47
+ cd /path/to/tamaro-configurations/configs/example-02-typical-customisations
48
+ npx -y @raisenow/tamaro-cli dev
49
+ ```
50
+
51
+ ### Run local server using a locally running Tamaro Core
52
+
53
+ 1. Run the local development web server for _Tamaro Core_ in the first terminal tab. You will be able to access a default configuration of Tamaro on http://localhost:1234 (port may differ, see console output).
54
+
55
+ ```bash
56
+ cd /path/to/tamaro-core
57
+ npx -y @raisenow/tamaro-cli dev
58
+ ```
59
+
60
+ 2. Run the local development web server for the _example-02-typical-customisations_ customer configuration in the second terminal tab. After running this command, you will able to access the configuration on http://localhost:1235 (port may differ, see console output).
61
+
62
+ ```bash
63
+ cd /path/to/tamaro-configurations/configs/example-02-typical-customisations
64
+ npx -y @raisenow/tamaro-cli dev --local-core
65
+ ```
66
+
67
+ ## `build`
68
+
69
+ Build an optimised (minified) bundle of _Tamaro Core_ or a customer configuration.
70
+
71
+ ### Options
72
+
73
+ - `--local-core` – Load _Tamaro Core_ from localhost instead of the CDN
74
+ - `--analyze` – Generate bundle statistics to `reports` folder
75
+ - `--deploy` – Deploy _Tamaro Core_ or a customer configuration bundle to AWS S3
76
+ - `--serve` – Run the generated bundle with a local web server
77
+ - `--tag <tag>` – Tag which should be used for the deployment of the bundle (default: “latest”)
78
+ - `--profile <profile>` – AWS profile which should be used for the deployment of the bundle (default: “payments-prod-cs-deployer”)
79
+
80
+ ### Build and deploy a customer configuration
81
+
82
+ Build and deploy an optimised (minified) bundle of the _example-02-typical-customisations_ customer configuration.
83
+
84
+ ```bash
85
+ cd /path/to/tamaro-configurations/configs/example-02-typical-customisations
86
+ npx -y @raisenow/tamaro-cli build --deploy
87
+ ```
88
+
89
+ As a result, the bundle should be deployed to: https://tamaro.raisenow.com/example-02-typical-customisations/latest/
90
+
91
+ ### Build and deploy a customer configuration with a specific tag
92
+
93
+ Build and deploy an optimised (minified) bundle of the _example-02-typical-customisations_ customer configuration with the tag _WEB-123_.
94
+
95
+ ```bash
96
+ cd /path/to/tamaro-configurations/configs/example-02-typical-customisations
97
+ npx -y @raisenow/tamaro-cli build --deploy --tag WEB-123
98
+ ```
99
+
100
+ As a result, the bundle should be deployed to: https://tamaro.raisenow.com/example-02-typical-customisations/WEB-123/
101
+
102
+ ### Build and serve a customer configuration
103
+
104
+ Build and serve an optimised (minified) bundle of the _example-02-typical-customisations_ customer configuration.
105
+
106
+ After running this command, a local web server should be running on http://localhost:1234 (port may differ, see console output).
107
+
108
+ ```bash
109
+ cd /path/to/tamaro-configurations/configs/example-02-typical-customisations
110
+ npx -y @raisenow/tamaro-cli build --serve
111
+ ```
112
+
113
+ ## `deploy`
114
+
115
+ Deploy a pre-built _Tamaro Core_ or customer configuration bundle to AWS S3.
116
+
117
+ ### Options
118
+
119
+ - `--tag <tag>` – Tag which should be used for the deployment of the bundle (default: “latest”)
120
+ - `--profile <profile>` – AWS profile which should be used for the deployment of the bundle (default: “payments-prod-cs-deployer”)
121
+
122
+ Make sure you have built the bundle before deploying it with this command, otherwise you may mistakenly deploy the bundle from a previous build.
123
+
124
+ ### Example
125
+
126
+ 1. Build an optimised (minified) bundle of the _example-02-typical-customisations_ customer configuration
127
+
128
+ ```bash
129
+ cd /path/to/tamaro-configurations/configs/example-02-typical-customisations
130
+ npx -y @raisenow/tamaro-cli build
131
+ ```
132
+
133
+ 2. Deploy it
134
+
135
+ ```bash
136
+ npx -y @raisenow/tamaro-cli deploy
137
+ ```
138
+
139
+ 3. Optionally, deploy it with the _WEB-123_ tag
140
+
141
+ ```bash
142
+ npx -y @raisenow/tamaro-cli deploy --tag WEB-123
143
+ ```
144
+
145
+ ## `serve`
146
+
147
+ Run a local web server for pre-built bundle.
148
+
149
+ ### Example
150
+
151
+ 1. Build an optimised (minified) bundle of the _example-02-typical-customisations_ customer configuration
152
+
153
+ ```bash
154
+ cd /path/to/tamaro-configurations/configs/example-02-typical-customisations
155
+ npx -y @raisenow/tamaro-cli build
156
+ ```
157
+
158
+ 2. Serve it. After running this command, web-server should be running on http://localhost:1234 (port may differ, see console output).
159
+
160
+ ```bash
161
+ npx -y @raisenow/tamaro-cli serve
162
+ ```
163
+
164
+ ## `list-deployed`
165
+
166
+ List deployments of _Tamaro Core_ or a particular customer configuration.
167
+
168
+ ### Options
169
+
170
+ - `--config <config>` – Configuration name (default: current customer configuration)
171
+ - `--profile <profile>` – AWS profile which should be used for fetching deployments (default: “payments-prod-cs-deployer”)
172
+
173
+ ### Example
174
+
175
+ ```bash
176
+ cd /path/to/tamaro-configurations/configs/example-02-typical-customisations
177
+ npx -y @raisenow/tamaro-cli list-deployed
178
+ ```
179
+
180
+ ## `deploy-email-config`
181
+
182
+ Deploy a widget’s email configuration to AWS S3.
183
+
184
+ ### Options
185
+
186
+ - `--bucket <bucket>` – AWS S3 bucket where it should be deployed (default: “rnw-email-service”)
187
+ - `--profile <profile>` – AWS profile which should be used for the deployment of email configuration (default: “payments-prod-cs-deployer”)
188
+
189
+ ### Example
190
+
191
+ ```bash
192
+ cd /path/to/tamaro-configurations/configs/example-02-typical-customisations
193
+ npx -y @raisenow/tamaro-cli deploy-email-config
194
+ ```
195
+
196
+ # Development
197
+
198
+ Make sure you have installed and activated the proper `node` and `npm` versions.
199
+
200
+ - `node: ">= 16"`
201
+ - `npm: ">= 8"`
202
+
203
+ Clone the repository and install its dependencies:
204
+
205
+ ```bash
206
+ git clone git@bitbucket.org:raisenow/tamaro-cli.git
207
+ cd tamaro-cli
208
+ npm ci
209
+ ```
210
+
211
+ Link package source to be able to run its local version:
212
+
213
+ ```bash
214
+ npm link .
215
+ ```
216
+
217
+ Run the `dev` script to watch source files and automatically rebuild on changes. It must be running during the _Tamaro CLI_ development process.
218
+
219
+ ```bash
220
+ npm run dev
221
+ ```
222
+
223
+ To use the locally linked version of _Tamaro CLI_, use it without `@raisenow/` scope, `-y` flag is also not needed:
224
+
225
+ ```bash
226
+ npx tamaro-cli dev
227
+ ```
package/src/cli.ts CHANGED
@@ -2,10 +2,18 @@
2
2
 
3
3
  import {createCommand} from 'commander'
4
4
  import pkg from '../package.json'
5
+ import {logError} from 'lib/helpers'
5
6
  import {dev, DevOptions} from 'commands/dev'
6
7
  import {build, BuildOptions} from 'commands/build'
7
- import {deploy, DeployOptions} from 'commands/deploy'
8
+ import {DEFAULT_TAG, deploy, DeployOptions} from 'commands/deploy'
8
9
  import {serve} from 'commands/serve'
10
+ import {listDeployed, ListDeployedOptions} from 'commands/list-deployed'
11
+ import {
12
+ DEFAULT_AWS_S3_EMAIL_CONFIG_BUCKET,
13
+ deployEmailConfig,
14
+ DeployEmailConfigOptions,
15
+ } from 'commands/deploy-email-config'
16
+ import {DEFAULT_AWS_PROFILE} from 'lib/aws'
9
17
 
10
18
  ///////////////////////////////////////////////////////////////////////////////
11
19
 
@@ -18,7 +26,7 @@ process.on('unhandledRejection', (error) => {
18
26
 
19
27
  // Exit on ctrl+c
20
28
  process.on('SIGINT', () => {
21
- process.exit(0)
29
+ process.exit(1)
22
30
  })
23
31
 
24
32
  ///////////////////////////////////////////////////////////////////////////////
@@ -29,22 +37,46 @@ const cli = createCommand().name(pkg.name).version(pkg.version, '-v, --version')
29
37
 
30
38
  cli
31
39
  .command('dev')
32
- .description('Run dev web-server for Tamaro Core or customer configuration')
33
- .option('--local-core', 'Load Tamaro Core from localhost instead of CDN')
40
+ .description(
41
+ 'Run the local development server for Tamaro Core or a particular customer configuration',
42
+ )
43
+ .option(
44
+ '--local-core',
45
+ 'Load Tamaro Core from localhost instead of the CDN',
46
+ false,
47
+ )
34
48
  .action(async (options: DevOptions) => {
35
49
  await dev(options)
36
50
  })
37
51
 
38
52
  cli
39
53
  .command('build')
40
- .description('Build Tamaro Core or customer configuration for production')
41
- .option('--local-core', 'Load Tamaro Core from localhost instead of CDN')
42
- .option('--analyze', 'Generate build statistics to "reports" folder')
43
- .option('--deploy', 'Deploy to AWS')
44
- .option('--latest', 'Deploy with tag "latest"')
45
- .option('--serve', 'Run web-server for previously created build')
46
- .option('--tag <tag>', 'Deploy with a specific tag')
47
- .action(async (options: BuildOptions) => {
54
+ .description(
55
+ 'Build an optimised (minified) bundle of Tamaro Core or a customer configuration',
56
+ )
57
+ .option(
58
+ '--local-core',
59
+ 'Load Tamaro Core from localhost instead of the CDN',
60
+ false,
61
+ )
62
+ .option('--analyze', 'Generate bundle statistics to "reports" folder', false)
63
+ .option(
64
+ '--deploy',
65
+ 'Deploy Tamaro Core or a customer configuration bundle to AWS S3',
66
+ false,
67
+ )
68
+ .option('--serve', 'Run the generated bundle with a local web server', false)
69
+ .option(
70
+ '--tag <tag>',
71
+ 'Tag which should be used for the deployment of the bundle',
72
+ DEFAULT_TAG,
73
+ )
74
+ .option(
75
+ '--profile <profile>',
76
+ 'AWS profile which should be used for the deployment of the bundle',
77
+ DEFAULT_AWS_PROFILE,
78
+ )
79
+ .action(async (options: BuildOptions & DeployOptions) => {
48
80
  await build(options)
49
81
 
50
82
  if (options.deploy) {
@@ -58,21 +90,72 @@ cli
58
90
 
59
91
  cli
60
92
  .command('deploy')
61
- .description('Deploy Tamaro Core or customer configuration to AWS')
62
- .option('--latest', 'Deploy with tag "latest"')
63
- .option('--tag <tag>', 'Deploy with a specific tag')
93
+ .description(
94
+ 'Deploy a pre-built Tamaro Core or customer configuration bundle to AWS S3',
95
+ )
96
+ .option(
97
+ '--tag <tag>',
98
+ 'Tag which should be used for the deployment of the bundle',
99
+ DEFAULT_TAG,
100
+ )
101
+ .option(
102
+ '--profile <profile>',
103
+ 'AWS profile which should be used for the deployment of the bundle',
104
+ DEFAULT_AWS_PROFILE,
105
+ )
64
106
  .action(async (options: DeployOptions) => {
65
107
  await deploy(options)
66
108
  })
67
109
 
68
110
  cli
69
111
  .command('serve')
70
- .description('Run web-server for previously created build')
112
+ .description('Run a local web server for pre-built bundle')
71
113
  .action(async () => {
72
114
  await serve()
73
115
  })
74
116
 
117
+ cli
118
+ .command('list-deployed')
119
+ .description(
120
+ 'List deployments of Tamaro Core or a particular customer configuration',
121
+ )
122
+ .option(
123
+ '--config <config>',
124
+ 'Configuration name (default: current customer configuration)',
125
+ )
126
+ .option(
127
+ '--profile <profile>',
128
+ 'AWS profile which should be used for fetching deployments',
129
+ DEFAULT_AWS_PROFILE,
130
+ )
131
+ .action(async (options: ListDeployedOptions) => {
132
+ await listDeployed(options)
133
+ })
134
+
135
+ cli
136
+ .command('deploy-email-config')
137
+ .description('Deploy a widget’s email configuration to AWS S3')
138
+ .option(
139
+ '--bucket <bucket>',
140
+ 'AWS S3 bucket where it should be deployed',
141
+ DEFAULT_AWS_S3_EMAIL_CONFIG_BUCKET,
142
+ )
143
+ .option(
144
+ '--profile <profile>',
145
+ 'AWS profile which should be used for the deployment of email configuration',
146
+ DEFAULT_AWS_PROFILE,
147
+ )
148
+ .action(async (options: DeployEmailConfigOptions) => {
149
+ await deployEmailConfig(options)
150
+ })
151
+
75
152
  ///////////////////////////////////////////////////////////////////////////////
76
153
  ;(async () => {
77
- await cli.parseAsync(process.argv)
154
+ try {
155
+ await cli.parseAsync(process.argv)
156
+ } catch (error: any) {
157
+ if (error.signal === 'SIGINT' && error.signalDescription) {
158
+ logError(`\n${error.signalDescription}`)
159
+ }
160
+ }
78
161
  })()
@@ -0,0 +1,97 @@
1
+ import resolveBin from 'resolve-bin'
2
+ import {
3
+ fail,
4
+ getIfCoreFns,
5
+ getPaths,
6
+ getWidgetUuid,
7
+ logCommand,
8
+ logDataTable,
9
+ logTitle,
10
+ notify,
11
+ resolveOwn,
12
+ runCommandSync,
13
+ } from 'lib/helpers'
14
+ import {assertProfileValid} from 'lib/aws'
15
+ import {CORE_CONFIG_NAME, DeployOptions} from 'commands/deploy'
16
+
17
+ ///////////////////////////////////////////////////////////////////////////////
18
+
19
+ export type BuildOptions = {
20
+ localCore: boolean
21
+ analyze: boolean
22
+ deploy: boolean
23
+ serve: boolean
24
+ }
25
+
26
+ ///////////////////////////////////////////////////////////////////////////////
27
+
28
+ export const build = async (
29
+ options: BuildOptions & DeployOptions,
30
+ ): Promise<void> => {
31
+ assertOptionsValid(options)
32
+
33
+ const flags = prepareFlags(options)
34
+ const {ifCore} = getIfCoreFns()
35
+ const paths = getPaths(ifCore)
36
+ const configName = ifCore(CORE_CONFIG_NAME, getWidgetUuid())
37
+ const title = ifCore(
38
+ 'Building optimised (minified) bundle of Tamaro Core …',
39
+ `Building optimised (minified) bundle of “${configName}” customer configuration …`,
40
+ )
41
+
42
+ const wpBin = resolveBin.sync('webpack')
43
+ const wpConfig = resolveOwn('dist/webpack.config.js')
44
+ const cmd = `
45
+ ${wpBin}
46
+ --config ${wpConfig}
47
+ --env min
48
+ ${flags}
49
+ `
50
+
51
+ logTitle(title)
52
+ logCommand(cmd)
53
+ runCommandSync(cmd, {stdio: 'inherit'})
54
+
55
+ /////////////////////////////////////////////////////////////////////////////
56
+
57
+ logDataTable(
58
+ {'Path:': paths.appDist},
59
+ `Bundle for “${configName}” customer configuration is done.`,
60
+ )
61
+
62
+ /////////////////////////////////////////////////////////////////////////////
63
+
64
+ notify({
65
+ title: 'build',
66
+ message: `Bundle for “${configName}” customer configuration is done.`,
67
+ })
68
+ }
69
+
70
+ ///////////////////////////////////////////////////////////////////////////////
71
+
72
+ const assertOptionsValid = (options: BuildOptions & DeployOptions) => {
73
+ const {localCore, deploy, profile} = options
74
+ const {ifCore} = getIfCoreFns()
75
+
76
+ if (ifCore() && localCore) {
77
+ fail('Flag "--local-core" is redundant if running in Tamaro Core context.')
78
+ }
79
+
80
+ if (localCore && deploy) {
81
+ fail('Flags "--local-core" and "--deploy" must not be used together.')
82
+ }
83
+
84
+ assertProfileValid(profile)
85
+ }
86
+
87
+ ///////////////////////////////////////////////////////////////////////////////
88
+
89
+ const prepareFlags = (options: BuildOptions): string => {
90
+ const {localCore, analyze} = options
91
+ let flags: string[] = []
92
+
93
+ flags = localCore ? [...flags, '--env localCore'] : flags
94
+ flags = analyze ? [...flags, '--env analyze'] : flags
95
+
96
+ return flags.join(' ')
97
+ }
@@ -0,0 +1,107 @@
1
+ import {existsSync} from 'fs'
2
+ import {
3
+ fail,
4
+ getIfCoreFns,
5
+ getPaths,
6
+ getWidgetUuid,
7
+ logCommand,
8
+ logDataTable,
9
+ logTitle,
10
+ notify,
11
+ } from 'lib/helpers'
12
+ import {assertProfileValid, AwsOptions, runAwsCommandSync} from 'lib/aws'
13
+
14
+ ///////////////////////////////////////////////////////////////////////////////
15
+
16
+ export type DeployEmailConfigOptions = AwsOptions & {
17
+ bucket: string
18
+ }
19
+
20
+ ///////////////////////////////////////////////////////////////////////////////
21
+
22
+ export const DEFAULT_AWS_S3_EMAIL_CONFIG_BUCKET = 'rnw-email-service'
23
+
24
+ ///////////////////////////////////////////////////////////////////////////////
25
+
26
+ export const deployEmailConfig = async (
27
+ options: DeployEmailConfigOptions,
28
+ ): Promise<void> => {
29
+ const {ifCore} = getIfCoreFns()
30
+ const paths = getPaths(ifCore)
31
+ const emailConfigPath = `${paths.app}/email-config`
32
+
33
+ assertOptionsValid(options)
34
+ assertEmailConfigPathExists(emailConfigPath)
35
+ assertIsNotCore()
36
+
37
+ const {bucket} = options
38
+ const configName = getWidgetUuid()
39
+ const deployUrl = `s3://${bucket}/${configName}`
40
+
41
+ const cmd = `
42
+ aws s3 sync ${emailConfigPath} ${deployUrl}
43
+ --delete
44
+ --exact-timestamps
45
+ `
46
+ logTitle(
47
+ `Deploying email configuration for “${configName}” customer configuration to AWS S3 …`,
48
+ )
49
+ logCommand(cmd)
50
+
51
+ try {
52
+ runAwsCommandSync(cmd, {stdout: 'inherit'})
53
+ } catch (error: any) {
54
+ fail(error.stderr)
55
+ }
56
+
57
+ /////////////////////////////////////////////////////////////////////////////
58
+
59
+ logDataTable(
60
+ {'Deploy URL:': deployUrl},
61
+ `Email configuration for “${configName}” customer configuration is deployed.`,
62
+ )
63
+
64
+ /////////////////////////////////////////////////////////////////////////////
65
+
66
+ notify({
67
+ title: `deploy-email-config`,
68
+ message: `Email configuration for “${configName}” customer configuration is deployed.`,
69
+ })
70
+ }
71
+
72
+ ///////////////////////////////////////////////////////////////////////////////
73
+
74
+ const assertOptionsValid = (options: DeployEmailConfigOptions) => {
75
+ const {bucket, profile} = options
76
+
77
+ assertBucketValid(bucket)
78
+ assertProfileValid(profile)
79
+ }
80
+
81
+ ///////////////////////////////////////////////////////////////////////////////
82
+
83
+ const assertEmailConfigPathExists = (distPath: string) => {
84
+ if (!existsSync(distPath)) {
85
+ fail('Email config folder does not exists. Nothing to deploy.')
86
+ }
87
+ }
88
+
89
+ ///////////////////////////////////////////////////////////////////////////////
90
+
91
+ const assertBucketValid = (tag: string) => {
92
+ const regex = /^[a-zA-Z0-9-_]+$/
93
+
94
+ if (!regex.test(tag)) {
95
+ fail(`Flag "--bucket" has forbidden format. Allowed format: ${regex}.`)
96
+ }
97
+ }
98
+
99
+ ///////////////////////////////////////////////////////////////////////////////
100
+
101
+ const assertIsNotCore = () => {
102
+ const {ifCore} = getIfCoreFns()
103
+
104
+ if (ifCore()) {
105
+ fail('You cannot deploy widget email configuration for Tamaro Core.')
106
+ }
107
+ }