@adobe/aio-cli-plugin-app 12.2.4 → 13.1.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/README.md CHANGED
@@ -72,7 +72,7 @@ DESCRIPTION
72
72
  Create, run, test, and deploy Adobe I/O Apps
73
73
  ```
74
74
 
75
- _See code: [src/commands/app/index.js](https://github.com/adobe/aio-cli-plugin-app/blob/12.2.4/src/commands/app/index.js)_
75
+ _See code: [src/commands/app/index.js](https://github.com/adobe/aio-cli-plugin-app/blob/13.1.0/src/commands/app/index.js)_
76
76
 
77
77
  ## `aio app add`
78
78
 
@@ -90,7 +90,7 @@ DESCRIPTION
90
90
  Add a new component to an existing Adobe I/O App
91
91
  ```
92
92
 
93
- _See code: [src/commands/app/add/index.js](https://github.com/adobe/aio-cli-plugin-app/blob/12.2.4/src/commands/app/add/index.js)_
93
+ _See code: [src/commands/app/add/index.js](https://github.com/adobe/aio-cli-plugin-app/blob/13.1.0/src/commands/app/add/index.js)_
94
94
 
95
95
  ## `aio app add action`
96
96
 
@@ -115,7 +115,7 @@ ALIASES
115
115
  $ aio app add actions
116
116
  ```
117
117
 
118
- _See code: [src/commands/app/add/action.js](https://github.com/adobe/aio-cli-plugin-app/blob/12.2.4/src/commands/app/add/action.js)_
118
+ _See code: [src/commands/app/add/action.js](https://github.com/adobe/aio-cli-plugin-app/blob/13.1.0/src/commands/app/add/action.js)_
119
119
 
120
120
  ## `aio app add ci`
121
121
 
@@ -133,7 +133,7 @@ DESCRIPTION
133
133
  Add CI files
134
134
  ```
135
135
 
136
- _See code: [src/commands/app/add/ci.js](https://github.com/adobe/aio-cli-plugin-app/blob/12.2.4/src/commands/app/add/ci.js)_
136
+ _See code: [src/commands/app/add/ci.js](https://github.com/adobe/aio-cli-plugin-app/blob/13.1.0/src/commands/app/add/ci.js)_
137
137
 
138
138
  ## `aio app add event`
139
139
 
@@ -158,7 +158,7 @@ ALIASES
158
158
  $ aio app add events
159
159
  ```
160
160
 
161
- _See code: [src/commands/app/add/event.js](https://github.com/adobe/aio-cli-plugin-app/blob/12.2.4/src/commands/app/add/event.js)_
161
+ _See code: [src/commands/app/add/event.js](https://github.com/adobe/aio-cli-plugin-app/blob/13.1.0/src/commands/app/add/event.js)_
162
162
 
163
163
  ## `aio app add extension`
164
164
 
@@ -184,7 +184,7 @@ ALIASES
184
184
  $ aio app add extensions
185
185
  ```
186
186
 
187
- _See code: [src/commands/app/add/extension.js](https://github.com/adobe/aio-cli-plugin-app/blob/12.2.4/src/commands/app/add/extension.js)_
187
+ _See code: [src/commands/app/add/extension.js](https://github.com/adobe/aio-cli-plugin-app/blob/13.1.0/src/commands/app/add/extension.js)_
188
188
 
189
189
  ## `aio app add service`
190
190
 
@@ -208,7 +208,7 @@ ALIASES
208
208
  $ aio app add services
209
209
  ```
210
210
 
211
- _See code: [src/commands/app/add/service.js](https://github.com/adobe/aio-cli-plugin-app/blob/12.2.4/src/commands/app/add/service.js)_
211
+ _See code: [src/commands/app/add/service.js](https://github.com/adobe/aio-cli-plugin-app/blob/13.1.0/src/commands/app/add/service.js)_
212
212
 
213
213
  ## `aio app add web-assets`
214
214
 
@@ -229,7 +229,7 @@ DESCRIPTION
229
229
  Add web assets support
230
230
  ```
231
231
 
232
- _See code: [src/commands/app/add/web-assets.js](https://github.com/adobe/aio-cli-plugin-app/blob/12.2.4/src/commands/app/add/web-assets.js)_
232
+ _See code: [src/commands/app/add/web-assets.js](https://github.com/adobe/aio-cli-plugin-app/blob/13.1.0/src/commands/app/add/web-assets.js)_
233
233
 
234
234
  ## `aio app build`
235
235
 
@@ -247,7 +247,7 @@ FLAGS
247
247
  -v, --verbose Verbose output
248
248
  --[no-]actions [default: true] Build actions if any
249
249
  --[no-]content-hash [default: true] Enable content hashing in browser code
250
- --[no-]force-build [default: true] Force a build even if one already exists
250
+ --[no-]force-build [default: false] Force a build even if one already exists
251
251
  --version Show version
252
252
  --[no-]web-assets [default: true] Build web-assets if any
253
253
  --web-optimize [default: false] Enable optimization (minification) of js/css/html
@@ -255,10 +255,11 @@ FLAGS
255
255
  DESCRIPTION
256
256
  Build an Adobe I/O App
257
257
 
258
- This will always force a rebuild unless --no-force-build is set.
258
+ Build the actions and web assets for an Adobe I/O App. Build is optimized to only build what is necessary.
259
+ Use the --force-build flag to force a build even if one already exists.
259
260
  ```
260
261
 
261
- _See code: [src/commands/app/build.js](https://github.com/adobe/aio-cli-plugin-app/blob/12.2.4/src/commands/app/build.js)_
262
+ _See code: [src/commands/app/build.js](https://github.com/adobe/aio-cli-plugin-app/blob/13.1.0/src/commands/app/build.js)_
262
263
 
263
264
  ## `aio app create [PATH]`
264
265
 
@@ -280,7 +281,7 @@ DESCRIPTION
280
281
  Create a new Adobe I/O App with default parameters
281
282
  ```
282
283
 
283
- _See code: [src/commands/app/create.js](https://github.com/adobe/aio-cli-plugin-app/blob/12.2.4/src/commands/app/create.js)_
284
+ _See code: [src/commands/app/create.js](https://github.com/adobe/aio-cli-plugin-app/blob/13.1.0/src/commands/app/create.js)_
284
285
 
285
286
  ## `aio app delete`
286
287
 
@@ -298,7 +299,7 @@ DESCRIPTION
298
299
  Delete a component from an existing Adobe I/O App
299
300
  ```
300
301
 
301
- _See code: [src/commands/app/delete/index.js](https://github.com/adobe/aio-cli-plugin-app/blob/12.2.4/src/commands/app/delete/index.js)_
302
+ _See code: [src/commands/app/delete/index.js](https://github.com/adobe/aio-cli-plugin-app/blob/13.1.0/src/commands/app/delete/index.js)_
302
303
 
303
304
  ## `aio app delete action [ACTION-NAME]`
304
305
 
@@ -324,7 +325,7 @@ ALIASES
324
325
  $ aio app delete actions
325
326
  ```
326
327
 
327
- _See code: [src/commands/app/delete/action.js](https://github.com/adobe/aio-cli-plugin-app/blob/12.2.4/src/commands/app/delete/action.js)_
328
+ _See code: [src/commands/app/delete/action.js](https://github.com/adobe/aio-cli-plugin-app/blob/13.1.0/src/commands/app/delete/action.js)_
328
329
 
329
330
  ## `aio app delete ci`
330
331
 
@@ -343,7 +344,7 @@ DESCRIPTION
343
344
  Delete existing CI files
344
345
  ```
345
346
 
346
- _See code: [src/commands/app/delete/ci.js](https://github.com/adobe/aio-cli-plugin-app/blob/12.2.4/src/commands/app/delete/ci.js)_
347
+ _See code: [src/commands/app/delete/ci.js](https://github.com/adobe/aio-cli-plugin-app/blob/13.1.0/src/commands/app/delete/ci.js)_
347
348
 
348
349
  ## `aio app delete extension`
349
350
 
@@ -369,7 +370,7 @@ ALIASES
369
370
  $ aio app delete extensions
370
371
  ```
371
372
 
372
- _See code: [src/commands/app/delete/extension.js](https://github.com/adobe/aio-cli-plugin-app/blob/12.2.4/src/commands/app/delete/extension.js)_
373
+ _See code: [src/commands/app/delete/extension.js](https://github.com/adobe/aio-cli-plugin-app/blob/13.1.0/src/commands/app/delete/extension.js)_
373
374
 
374
375
  ## `aio app delete service`
375
376
 
@@ -393,7 +394,7 @@ ALIASES
393
394
  $ aio app delete services
394
395
  ```
395
396
 
396
- _See code: [src/commands/app/delete/service.js](https://github.com/adobe/aio-cli-plugin-app/blob/12.2.4/src/commands/app/delete/service.js)_
397
+ _See code: [src/commands/app/delete/service.js](https://github.com/adobe/aio-cli-plugin-app/blob/13.1.0/src/commands/app/delete/service.js)_
397
398
 
398
399
  ## `aio app delete web-assets`
399
400
 
@@ -412,11 +413,11 @@ DESCRIPTION
412
413
  Delete existing web assets
413
414
  ```
414
415
 
415
- _See code: [src/commands/app/delete/web-assets.js](https://github.com/adobe/aio-cli-plugin-app/blob/12.2.4/src/commands/app/delete/web-assets.js)_
416
+ _See code: [src/commands/app/delete/web-assets.js](https://github.com/adobe/aio-cli-plugin-app/blob/13.1.0/src/commands/app/delete/web-assets.js)_
416
417
 
417
418
  ## `aio app deploy`
418
419
 
419
- Build and deploy an Adobe I/O App
420
+ Deploy an Adobe I/O App
420
421
 
421
422
  ```
422
423
  USAGE
@@ -448,12 +449,17 @@ FLAGS
448
449
  --web-optimize [default: false] Enable optimization (minification) of web js/css/html
449
450
 
450
451
  DESCRIPTION
451
- Build and deploy an Adobe I/O App
452
+ Deploy an Adobe I/O App
452
453
 
453
- This will always force a rebuild unless --no-force-build is set.
454
+ Deploys the actions and web assets for an Adobe I/O App.
455
+ This will also build any changed actions or web assets before deploying.
456
+ Use the --force-build flag to force a build even if one already exists.
457
+ Deploy is optimized to only deploy what is necessary. Be aware that deploying actions will overwrite any previous
458
+ deployments.
459
+ Use the --force-deploy flag to force deploy changes, regardless of production Workspace being published in Exchange.
454
460
  ```
455
461
 
456
- _See code: [src/commands/app/deploy.js](https://github.com/adobe/aio-cli-plugin-app/blob/12.2.4/src/commands/app/deploy.js)_
462
+ _See code: [src/commands/app/deploy.js](https://github.com/adobe/aio-cli-plugin-app/blob/13.1.0/src/commands/app/deploy.js)_
457
463
 
458
464
  ## `aio app get-url [ACTION]`
459
465
 
@@ -476,7 +482,7 @@ DESCRIPTION
476
482
  Get action URLs
477
483
  ```
478
484
 
479
- _See code: [src/commands/app/get-url.js](https://github.com/adobe/aio-cli-plugin-app/blob/12.2.4/src/commands/app/get-url.js)_
485
+ _See code: [src/commands/app/get-url.js](https://github.com/adobe/aio-cli-plugin-app/blob/13.1.0/src/commands/app/get-url.js)_
480
486
 
481
487
  ## `aio app info`
482
488
 
@@ -498,7 +504,7 @@ DESCRIPTION
498
504
  Display settings/configuration in use by an Adobe I/O App
499
505
  ```
500
506
 
501
- _See code: [src/commands/app/info.js](https://github.com/adobe/aio-cli-plugin-app/blob/12.2.4/src/commands/app/info.js)_
507
+ _See code: [src/commands/app/info.js](https://github.com/adobe/aio-cli-plugin-app/blob/13.1.0/src/commands/app/info.js)_
502
508
 
503
509
  ## `aio app init [PATH]`
504
510
 
@@ -537,7 +543,7 @@ DESCRIPTION
537
543
  Create a new Adobe I/O App
538
544
  ```
539
545
 
540
- _See code: [src/commands/app/init.js](https://github.com/adobe/aio-cli-plugin-app/blob/12.2.4/src/commands/app/init.js)_
546
+ _See code: [src/commands/app/init.js](https://github.com/adobe/aio-cli-plugin-app/blob/13.1.0/src/commands/app/init.js)_
541
547
 
542
548
  ## `aio app install PATH`
543
549
 
@@ -560,7 +566,7 @@ DESCRIPTION
560
566
  This command will support installing apps packaged by 'aio app pack'.
561
567
  ```
562
568
 
563
- _See code: [src/commands/app/install.js](https://github.com/adobe/aio-cli-plugin-app/blob/12.2.4/src/commands/app/install.js)_
569
+ _See code: [src/commands/app/install.js](https://github.com/adobe/aio-cli-plugin-app/blob/13.1.0/src/commands/app/install.js)_
564
570
 
565
571
  ## `aio app list`
566
572
 
@@ -578,7 +584,7 @@ DESCRIPTION
578
584
  List components for Adobe I/O App
579
585
  ```
580
586
 
581
- _See code: [src/commands/app/list/index.js](https://github.com/adobe/aio-cli-plugin-app/blob/12.2.4/src/commands/app/list/index.js)_
587
+ _See code: [src/commands/app/list/index.js](https://github.com/adobe/aio-cli-plugin-app/blob/13.1.0/src/commands/app/list/index.js)_
582
588
 
583
589
  ## `aio app list extension`
584
590
 
@@ -603,7 +609,7 @@ ALIASES
603
609
  $ aio app list extensions
604
610
  ```
605
611
 
606
- _See code: [src/commands/app/list/extension.js](https://github.com/adobe/aio-cli-plugin-app/blob/12.2.4/src/commands/app/list/extension.js)_
612
+ _See code: [src/commands/app/list/extension.js](https://github.com/adobe/aio-cli-plugin-app/blob/13.1.0/src/commands/app/list/extension.js)_
607
613
 
608
614
  ## `aio app logs`
609
615
 
@@ -627,7 +633,7 @@ DESCRIPTION
627
633
  Fetch logs for an Adobe I/O App
628
634
  ```
629
635
 
630
- _See code: [src/commands/app/logs.js](https://github.com/adobe/aio-cli-plugin-app/blob/12.2.4/src/commands/app/logs.js)_
636
+ _See code: [src/commands/app/logs.js](https://github.com/adobe/aio-cli-plugin-app/blob/13.1.0/src/commands/app/logs.js)_
631
637
 
632
638
  ## `aio app pack [PATH]`
633
639
 
@@ -649,7 +655,7 @@ DESCRIPTION
649
655
  This command will support packaging apps for redistribution.
650
656
  ```
651
657
 
652
- _See code: [src/commands/app/pack.js](https://github.com/adobe/aio-cli-plugin-app/blob/12.2.4/src/commands/app/pack.js)_
658
+ _See code: [src/commands/app/pack.js](https://github.com/adobe/aio-cli-plugin-app/blob/13.1.0/src/commands/app/pack.js)_
653
659
 
654
660
  ## `aio app run`
655
661
 
@@ -673,7 +679,7 @@ DESCRIPTION
673
679
  Run an Adobe I/O App
674
680
  ```
675
681
 
676
- _See code: [src/commands/app/run.js](https://github.com/adobe/aio-cli-plugin-app/blob/12.2.4/src/commands/app/run.js)_
682
+ _See code: [src/commands/app/run.js](https://github.com/adobe/aio-cli-plugin-app/blob/13.1.0/src/commands/app/run.js)_
677
683
 
678
684
  ## `aio app test`
679
685
 
@@ -701,7 +707,7 @@ DESCRIPTION
701
707
  If the extension has a hook called 'test' in its 'ext.config.yaml', the script specified will be run instead.
702
708
  ```
703
709
 
704
- _See code: [src/commands/app/test.js](https://github.com/adobe/aio-cli-plugin-app/blob/12.2.4/src/commands/app/test.js)_
710
+ _See code: [src/commands/app/test.js](https://github.com/adobe/aio-cli-plugin-app/blob/13.1.0/src/commands/app/test.js)_
705
711
 
706
712
  ## `aio app undeploy`
707
713
 
@@ -726,7 +732,7 @@ DESCRIPTION
726
732
  Undeploys an Adobe I/O App
727
733
  ```
728
734
 
729
- _See code: [src/commands/app/undeploy.js](https://github.com/adobe/aio-cli-plugin-app/blob/12.2.4/src/commands/app/undeploy.js)_
735
+ _See code: [src/commands/app/undeploy.js](https://github.com/adobe/aio-cli-plugin-app/blob/13.1.0/src/commands/app/undeploy.js)_
730
736
 
731
737
  ## `aio app use [CONFIG_FILE_PATH]`
732
738
 
@@ -773,5 +779,5 @@ DESCRIPTION
773
779
  page in https://developer.adobe.com/console/
774
780
  ```
775
781
 
776
- _See code: [src/commands/app/use.js](https://github.com/adobe/aio-cli-plugin-app/blob/12.2.4/src/commands/app/use.js)_
782
+ _See code: [src/commands/app/use.js](https://github.com/adobe/aio-cli-plugin-app/blob/13.1.0/src/commands/app/use.js)_
777
783
  <!-- commandsstop -->
@@ -1,9 +1,9 @@
1
1
  {
2
- "version": "12.2.4",
2
+ "version": "13.1.0",
3
3
  "commands": {
4
4
  "app:build": {
5
5
  "id": "app:build",
6
- "description": "Build an Adobe I/O App\n\nThis will always force a rebuild unless --no-force-build is set.\n",
6
+ "description": "Build an Adobe I/O App\n\nBuild the actions and web assets for an Adobe I/O App. Build is optimized to only build what is necessary.\nUse the --force-build flag to force a build even if one already exists.\n",
7
7
  "strict": true,
8
8
  "pluginName": "@adobe/aio-cli-plugin-app",
9
9
  "pluginAlias": "@adobe/aio-cli-plugin-app",
@@ -52,7 +52,7 @@
52
52
  "force-build": {
53
53
  "name": "force-build",
54
54
  "type": "boolean",
55
- "description": "[default: true] Force a build even if one already exists",
55
+ "description": "[default: false] Force a build even if one already exists",
56
56
  "allowNo": true
57
57
  },
58
58
  "content-hash": {
@@ -121,7 +121,7 @@
121
121
  },
122
122
  "app:deploy": {
123
123
  "id": "app:deploy",
124
- "description": "Build and deploy an Adobe I/O App\n\nThis will always force a rebuild unless --no-force-build is set.\n",
124
+ "description": "Deploy an Adobe I/O App\n\nDeploys the actions and web assets for an Adobe I/O App.\nThis will also build any changed actions or web assets before deploying.\nUse the --force-build flag to force a build even if one already exists.\nDeploy is optimized to only deploy what is necessary. Be aware that deploying actions will overwrite any previous deployments.\nUse the --force-deploy flag to force deploy changes, regardless of production Workspace being published in Exchange.\n",
125
125
  "strict": true,
126
126
  "pluginName": "@adobe/aio-cli-plugin-app",
127
127
  "pluginAlias": "@adobe/aio-cli-plugin-app",
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@adobe/aio-cli-plugin-app",
3
3
  "description": "Create, Build and Deploy Adobe I/O Applications",
4
- "version": "12.2.4",
4
+ "version": "13.1.0",
5
5
  "author": "Adobe Inc.",
6
6
  "bugs": "https://github.com/adobe/aio-cli-plugin-app/issues",
7
7
  "dependencies": {
@@ -12,7 +12,7 @@
12
12
  "@adobe/aio-lib-core-networking": "^5",
13
13
  "@adobe/aio-lib-env": "^3",
14
14
  "@adobe/aio-lib-ims": "^7",
15
- "@adobe/aio-lib-runtime": "^6",
15
+ "@adobe/aio-lib-runtime": "^7.0.0",
16
16
  "@adobe/aio-lib-templates": "^3",
17
17
  "@adobe/aio-lib-web": "^7",
18
18
  "@adobe/generator-aio-app": "^7",
@@ -42,6 +42,13 @@ class BaseCommand extends Command {
42
42
  await super.init()
43
43
  // setup a prompt that outputs to stderr
44
44
  this.prompt = inquirer.createPromptModule({ output: process.stderr })
45
+
46
+ // set User-Agent for runtime calls
47
+ // ex. aio-cli-plugin-app/@adobe/aio-cli/10.3.1 (darwin-arm64; node-v18.20.4; zsh)
48
+ const vs = this.config.versionDetails
49
+ // some tests might not have this set, so we use ? nullish coalescing
50
+ process.env.__OW_USER_AGENT =
51
+ `aio-cli-plugin-app/${vs?.cliVersion} (${vs?.architecture}; ${vs?.nodeVersion}; ${vs?.shell})`
45
52
  }
46
53
 
47
54
  async getLibConsoleCLI () {
@@ -70,14 +70,16 @@ class Build extends BaseCommand {
70
70
  }
71
71
 
72
72
  if (flags.actions) {
73
- if (config.app.hasBackend && (flags['force-build'] || !fs.existsSync(config.actions.dist))) {
73
+ // removed flags['force-build'] || as it is always forced at this point, we need to check to decide what to build
74
+ // if no backend, we skip the build
75
+ if (config.app.hasBackend) {
74
76
  try {
75
77
  let builtList = []
76
78
  const script = await runInProcess(config.hooks['build-actions'], config)
77
79
  aioLogger.debug(`run hook for 'build-actions' for actions in '${name}' returned ${script}`)
78
80
  spinner.start(`Building actions for '${name}'`)
79
81
  if (!script) {
80
- builtList = await RuntimeLib.buildActions(config, filterActions, true)
82
+ builtList = await RuntimeLib.buildActions(config, filterActions, flags['force-build']) // skipCheck is false
81
83
  }
82
84
  if (builtList.length > 0) {
83
85
  spinner.succeed(chalk.green(`Built ${builtList.length} action(s) for '${name}'`))
@@ -85,7 +87,7 @@ class Build extends BaseCommand {
85
87
  if (script) {
86
88
  spinner.fail(chalk.green(`build-action skipped by hook '${name}'`))
87
89
  } else {
88
- spinner.fail(chalk.green(`No actions built for '${name}'`))
90
+ spinner.info(chalk.green(`No actions built for '${name}'`))
89
91
  }
90
92
  }
91
93
  aioLogger.debug(`RuntimeLib.buildActions returned ${builtList}`)
@@ -94,7 +96,7 @@ class Build extends BaseCommand {
94
96
  throw err
95
97
  }
96
98
  } else {
97
- spinner.info(`no backend or a build already exists, skipping action build for '${name}'`)
99
+ spinner.info(`no backend, skipping action build for '${name}'`)
98
100
  }
99
101
  }
100
102
  if (flags['web-assets']) {
@@ -127,7 +129,8 @@ class Build extends BaseCommand {
127
129
  throw err
128
130
  }
129
131
  } else {
130
- spinner.info(`no frontend or a build already exists, skipping frontend build for '${name}'`)
132
+ // TODO: specify which ... keep this useful
133
+ spinner.info(chalk.green(`No frontend or a build already exists, skipping frontend build for '${name}'`))
131
134
  }
132
135
  }
133
136
  try {
@@ -140,7 +143,8 @@ class Build extends BaseCommand {
140
143
 
141
144
  Build.description = `Build an Adobe I/O App
142
145
 
143
- This will always force a rebuild unless --no-force-build is set.
146
+ Build the actions and web assets for an Adobe I/O App. Build is optimized to only build what is necessary.
147
+ Use the --force-build flag to force a build even if one already exists.
144
148
  `
145
149
 
146
150
  Build.flags = {
@@ -163,8 +167,8 @@ Build.flags = {
163
167
  allowNo: true
164
168
  }),
165
169
  'force-build': Flags.boolean({
166
- description: '[default: true] Force a build even if one already exists',
167
- default: true,
170
+ description: '[default: false] Force a build even if one already exists',
171
+ default: false,
168
172
  allowNo: true
169
173
  }),
170
174
  'content-hash': Flags.boolean({
@@ -18,9 +18,10 @@ const BaseCommand = require('../../BaseCommand')
18
18
  const BuildCommand = require('./build')
19
19
  const webLib = require('@adobe/aio-lib-web')
20
20
  const { Flags } = require('@oclif/core')
21
- const { createWebExportFilter, runInProcess, buildExtensionPointPayloadWoMetadata, buildExcShellViewExtensionMetadata } = require('../../lib/app-helper')
21
+ const { createWebExportFilter, runInProcess, buildExtensionPointPayloadWoMetadata, buildExcShellViewExtensionMetadata, getCliInfo } = require('../../lib/app-helper')
22
22
  const rtLib = require('@adobe/aio-lib-runtime')
23
23
  const LogForwarding = require('../../lib/log-forwarding')
24
+ const { sendAuditLogs, getAuditLogEvent, getFilesCountWithExtension } = require('../../lib/audit-logger')
24
25
 
25
26
  const PRE_DEPLOY_EVENT_REG = 'pre-deploy-event-reg'
26
27
  const POST_DEPLOY_EVENT_REG = 'post-deploy-event-reg'
@@ -32,6 +33,7 @@ class Deploy extends BuildCommand {
32
33
 
33
34
  // flags
34
35
  flags['web-assets'] = flags['web-assets'] && !flags.action
36
+ // Deploy only a specific action, the flags can be specified multiple times, this will set --no-publish
35
37
  flags.publish = flags.publish && !flags.action
36
38
 
37
39
  const deployConfigs = await this.getAppExtConfigs(flags)
@@ -51,12 +53,11 @@ class Deploy extends BuildCommand {
51
53
 
52
54
  try {
53
55
  const aioConfig = (await this.getFullConfig()).aio
56
+ const cliDetails = await getCliInfo()
54
57
 
55
58
  // 1. update log forwarding configuration
56
59
  // note: it is possible that .aio file does not exist, which means there is no local lg config
57
- if (aioConfig?.project?.workspace &&
58
- flags['log-forwarding-update'] &&
59
- flags.actions) {
60
+ if (aioConfig?.project?.workspace && flags['log-forwarding-update'] && flags.actions) {
60
61
  spinner.start('Updating log forwarding configuration')
61
62
  try {
62
63
  const lf = await LogForwarding.init(aioConfig)
@@ -80,7 +81,8 @@ class Deploy extends BuildCommand {
80
81
  }
81
82
 
82
83
  // 2. If workspace is prod and has extensions, check if the app is published
83
- if (!isStandaloneApp && aioConfig?.project?.workspace?.name === 'Production') {
84
+ // if --no-publish, we skip this check
85
+ if (flags.publish && aioConfig?.project?.workspace?.name === 'Production') {
84
86
  const extension = await this.getApplicationExtension(aioConfig)
85
87
  if (extension && extension.status === 'PUBLISHED') {
86
88
  flags.publish = false // if the app is production and published, then skip publish later on
@@ -92,7 +94,15 @@ class Deploy extends BuildCommand {
92
94
  }
93
95
  }
94
96
 
95
- // 3. deploy actions and web assets for each extension
97
+ // 3. send deploy log event
98
+ const logEvent = getAuditLogEvent(flags, aioConfig.project, 'AB_APP_DEPLOY')
99
+ if (logEvent) {
100
+ await sendAuditLogs(cliDetails.accessToken, logEvent, cliDetails.env)
101
+ } else {
102
+ this.log(chalk.red(chalk.bold('Warning: No valid config data found to send audit log event for deployment.')))
103
+ }
104
+
105
+ // 4. deploy actions and web assets for each extension
96
106
  // Possible improvements:
97
107
  // - parallelize
98
108
  // - break into smaller pieces deploy, allowing to first deploy all actions then all web assets
@@ -100,6 +110,14 @@ class Deploy extends BuildCommand {
100
110
  const k = keys[i]
101
111
  const v = values[i]
102
112
  await this.deploySingleConfig(k, v, flags, spinner)
113
+ if (v.app.hasFrontend && flags['web-assets']) {
114
+ const opItems = getFilesCountWithExtension(v.web.distProd)
115
+ const assetDeployedLogEvent = getAuditLogEvent(flags, aioConfig.project, 'AB_APP_ASSETS_DEPLOYED')
116
+ if (assetDeployedLogEvent) {
117
+ assetDeployedLogEvent.data.opItems = opItems
118
+ await sendAuditLogs(cliDetails.accessToken, assetDeployedLogEvent, cliDetails.env)
119
+ }
120
+ }
103
121
  }
104
122
 
105
123
  // 4. deploy extension manifest
@@ -172,7 +190,7 @@ class Deploy extends BuildCommand {
172
190
  // output should be "Error : <plugin-name> : <error-message>\n" for each failure
173
191
  this.error(hookResults.failures.map(f => `${f.plugin.name} : ${f.error.message}`).join('\nError: '), { exit: 1 })
174
192
  }
175
- deployedRuntimeEntities = await rtLib.deployActions(config, { filterEntities }, onProgress)
193
+ deployedRuntimeEntities = await rtLib.deployActions(config, { filterEntities, useForce: flags['force-deploy'] }, onProgress)
176
194
  }
177
195
 
178
196
  if (deployedRuntimeEntities.actions && deployedRuntimeEntities.actions.length > 0) {
@@ -181,7 +199,7 @@ class Deploy extends BuildCommand {
181
199
  if (script) {
182
200
  spinner.fail(chalk.green(`deploy-actions skipped by hook '${name}'`))
183
201
  } else {
184
- spinner.fail(chalk.green(`No actions deployed for '${name}'`))
202
+ spinner.info(chalk.green(`No actions deployed for '${name}'`))
185
203
  }
186
204
  }
187
205
  } catch (err) {
@@ -204,6 +222,11 @@ class Deploy extends BuildCommand {
204
222
  } else {
205
223
  deployedFrontendUrl = await webLib.deployWeb(config, onProgress)
206
224
  spinner.succeed(chalk.green(message))
225
+ const filesLogCount = getFilesCountWithExtension(config.web.distProd)
226
+ const filesDeployedMessage = `All static assets for the App Builder application in workspace: ${name} were successfully deployed to the CDN. Files deployed :`
227
+ const filesLogFormatted = filesLogCount?.map(file => ` • ${file}`).join('')
228
+ const finalMessage = chalk.green(`${filesDeployedMessage}\n${filesLogFormatted}`)
229
+ spinner.succeed(chalk.green(finalMessage))
207
230
  }
208
231
  } catch (err) {
209
232
  spinner.fail(chalk.green(message))
@@ -287,9 +310,13 @@ class Deploy extends BuildCommand {
287
310
  }
288
311
  }
289
312
 
290
- Deploy.description = `Build and deploy an Adobe I/O App
313
+ Deploy.description = `Deploy an Adobe I/O App
291
314
 
292
- This will always force a rebuild unless --no-force-build is set.
315
+ Deploys the actions and web assets for an Adobe I/O App.
316
+ This will also build any changed actions or web assets before deploying.
317
+ Use the --force-build flag to force a build even if one already exists.
318
+ Deploy is optimized to only deploy what is necessary. Be aware that deploying actions will overwrite any previous deployments.
319
+ Use the --force-deploy flag to force deploy changes, regardless of production Workspace being published in Exchange.
293
320
  `
294
321
 
295
322
  Deploy.flags = {
@@ -319,7 +346,7 @@ Deploy.flags = {
319
346
  'force-build': Flags.boolean({
320
347
  description: '[default: true] Force a build even if one already exists',
321
348
  exclusive: ['no-build'], // no-build
322
- default: true,
349
+ default: false,
323
350
  allowNo: true
324
351
  }),
325
352
  'content-hash': Flags.boolean({
@@ -108,6 +108,9 @@ class Run extends BaseCommand {
108
108
  }
109
109
 
110
110
  const verboseOutput = flags.verbose || flags.local || headlessApp
111
+ // we should evaluate this, a lot of output just disappears in the spinner text and
112
+ // using verbose dumps ALL of parcel's output, so this become unreadable
113
+ // we need a middle ground. -jm
111
114
  const onProgress = !verboseOutput
112
115
  ? info => {
113
116
  spinner.text = info
@@ -17,8 +17,9 @@ const { Flags } = require('@oclif/core')
17
17
 
18
18
  const BaseCommand = require('../../BaseCommand')
19
19
  const webLib = require('@adobe/aio-lib-web')
20
- const { runInProcess, buildExtensionPointPayloadWoMetadata } = require('../../lib/app-helper')
20
+ const { runInProcess, buildExtensionPointPayloadWoMetadata, getCliInfo } = require('../../lib/app-helper')
21
21
  const rtLib = require('@adobe/aio-lib-runtime')
22
+ const { sendAuditLogs, getAuditLogEvent } = require('../../lib/audit-logger')
22
23
 
23
24
  class Undeploy extends BaseCommand {
24
25
  async run () {
@@ -44,14 +45,29 @@ class Undeploy extends BaseCommand {
44
45
 
45
46
  const spinner = ora()
46
47
  try {
48
+ const aioConfig = (await this.getFullConfig()).aio
49
+ const cliDetails = await getCliInfo()
50
+ const logEvent = getAuditLogEvent(flags, aioConfig.project, 'AB_APP_UNDEPLOY')
51
+
52
+ // 1.1. send audit log event for successful undeploy
53
+ if (logEvent) {
54
+ await sendAuditLogs(cliDetails.accessToken, logEvent, cliDetails.env)
55
+ } else {
56
+ this.log(chalk.red(chalk.bold('Warning: No valid config data found to send audit log event for deployment.')))
57
+ }
58
+
47
59
  for (let i = 0; i < keys.length; ++i) {
48
60
  const k = keys[i]
49
61
  const v = values[i]
50
62
  await this.undeployOneExt(k, v, flags, spinner)
63
+ const assetUndeployLogEvent = getAuditLogEvent(flags, aioConfig.project, 'AB_APP_ASSETS_UNDEPLOYED')
64
+ if (assetUndeployLogEvent) {
65
+ await sendAuditLogs(cliDetails.accessToken, assetUndeployLogEvent, cliDetails.env)
66
+ }
51
67
  }
52
- // 2. unpublish extension manifest
68
+
69
+ // 1.2. unpublish extension manifest
53
70
  if (flags.unpublish && !(keys.length === 1 && keys[0] === 'application')) {
54
- const aioConfig = (await this.getFullConfig()).aio
55
71
  const payload = await this.unpublishExtensionPoints(libConsoleCLI, undeployConfigs, aioConfig, flags['force-unpublish'])
56
72
  this.log(chalk.blue(chalk.bold(`New Extension Point(s) in Workspace '${aioConfig.project.workspace.name}': '${Object.keys(payload.endpoints)}'`)))
57
73
  } else {
@@ -110,6 +126,7 @@ class Undeploy extends BaseCommand {
110
126
  if (!script) {
111
127
  await webLib.undeployWeb(config, onProgress)
112
128
  }
129
+
113
130
  spinner.succeed(chalk.green(`Un-Deploying web assets for ${extName}`))
114
131
  } catch (err) {
115
132
  spinner.fail(chalk.green(`Un-Deploying web assets for ${extName}`))
@@ -38,7 +38,7 @@ const deployActions = require('./deploy-actions')
38
38
  module.exports = async (watcherOptions) => {
39
39
  const { config, log } = watcherOptions
40
40
 
41
- log(`watching action files at ${config.actions.src}...`)
41
+ log(`watching action files at ${config.actions.src} ...`)
42
42
  const watcher = chokidar.watch(config.actions.src)
43
43
 
44
44
  watcher.on('change', createChangeHandler({ ...watcherOptions, watcher }))
@@ -91,6 +91,8 @@ function createChangeHandler (watcherOptions) {
91
91
  try {
92
92
  aioLogger.debug(`${filePath} has changed. Redeploying actions.`)
93
93
  const filterActions = getActionNameFromPath(filePath, watcherOptions)
94
+ // this is happening, but its not showing up because verbose is usually off
95
+ // this might be more important and worthy of signalling to the user
94
96
  if (!filterActions.length) {
95
97
  log(' -> A non-action file was changed, restart is required to deploy...')
96
98
  } else {
@@ -119,6 +121,13 @@ function createChangeHandler (watcherOptions) {
119
121
  * @returns {Array<string>} All of the actions which match the modified path
120
122
  */
121
123
  function getActionNameFromPath (filePath, watcherOptions) {
124
+ // note: this check only happens during aio app run
125
+ // before the watcher is started, all actions are built and deployed and hashes updated
126
+ // this code is missing 2 cases:
127
+ // 1. if the action is a folder with a package.json and the changed file is in the folder
128
+ // 2. if the changed file is in the folder with the action, but not the action file itself
129
+ // we need to be careful with these cases, because we could cause a recursive loop
130
+ // for now we continue to error on the cautious side, and output a message suggesting a restart
122
131
  const actionNames = []
123
132
  const unixFilePath = upath.toUnix(filePath)
124
133
  const { config } = watcherOptions
@@ -126,7 +135,10 @@ function getActionNameFromPath (filePath, watcherOptions) {
126
135
  if (pkg.actions) {
127
136
  Object.entries(pkg.actions).forEach(([actionName, action]) => {
128
137
  const unixActionFunction = upath.toUnix(action.function)
129
- if (unixActionFunction.includes(unixFilePath)) {
138
+ // since action could be a folder, and changed file could be in the folder
139
+ // we need to compare both ways
140
+ // there are 2 additional cases listed above
141
+ if (unixActionFunction.includes(unixFilePath) || unixFilePath.includes(unixActionFunction)) {
130
142
  actionNames.push(actionName)
131
143
  }
132
144
  })
@@ -0,0 +1,156 @@
1
+ /*
2
+ Copyright 2024 Adobe. All rights reserved.
3
+ This file is licensed to you under the Apache License, Version 2.0 (the "License");
4
+ you may not use this file except in compliance with the License. You may obtain a copy
5
+ of the License at http://www.apache.org/licenses/LICENSE-2.0
6
+ Unless required by applicable law or agreed to in writing, software distributed under
7
+ the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
8
+ OF ANY KIND, either express or implied. See the License for the specific language
9
+ governing permissions and limitations under the License.
10
+ */
11
+ const fetch = require('node-fetch')
12
+ const fs = require('fs')
13
+ const path = require('path')
14
+ const chalk = require('chalk')
15
+ const { getCliEnv, PROD_ENV } = require('@adobe/aio-lib-env')
16
+ const aioLogger = require('@adobe/aio-lib-core-logging')('@adobe/aio-cli-plugin-app:lib-audit-logger', { provider: 'debug' })
17
+
18
+ const OPERATIONS = {
19
+ AB_APP_DEPLOY: 'ab_app_deploy',
20
+ AB_APP_UNDEPLOY: 'ab_app_undeploy',
21
+ AB_APP_TEST: 'ab_app_test', // todo : remove after testing
22
+ AB_APP_ASSETS_DEPLOYED: 'ab_app_assets_deployed',
23
+ AB_APP_ASSETS_UNDEPLOYED: 'ab_app_assets_undeployed'
24
+ }
25
+
26
+ const AUDIT_SERVICE_ENPOINTS = {
27
+ stage: 'https://adp-auditlog-service-stage.adobeioruntime.net/api/v1/web/audit-log-api/event-post',
28
+ prod: 'https://adp-auditlog-service-prod.adobeioruntime.net/api/v1/web/audit-log-api/event-post'
29
+ }
30
+
31
+ /**
32
+ * Send audit log events to audit service
33
+ * @param {string} accessToken valid access token
34
+ * @param {object} logEvent logEvent details
35
+ * @param {string} env valid env stage|prod
36
+ */
37
+ async function sendAuditLogs (accessToken, logEvent, env = 'prod') {
38
+ // TODO: this is blocked by the audit service only being available in stage
39
+ // remove this check once the service is available in prod
40
+ if (env !== 'stage') {
41
+ return
42
+ }
43
+ const url = AUDIT_SERVICE_ENPOINTS[env]
44
+ const payload = {
45
+ event: logEvent
46
+ }
47
+ const options = {
48
+ method: 'POST',
49
+ headers: {
50
+ Authorization: 'Bearer ' + accessToken,
51
+ 'Content-type': 'application/json'
52
+ },
53
+ body: JSON.stringify(payload)
54
+ }
55
+ const response = await fetch(url, options)
56
+ if (response.status !== 200) {
57
+ const err = await response.text()
58
+ throw new Error('Failed to send audit log - ' + response.status + ' ' + err)
59
+ }
60
+ }
61
+
62
+ /**
63
+ *
64
+ * @param {object} flags cli flags
65
+ * @param {object} project details
66
+ * @param {string} event log name
67
+ * @returns {object} logEvent
68
+ */
69
+ function getAuditLogEvent (flags, project, event) {
70
+ if (getCliEnv() === PROD_ENV) {
71
+ aioLogger.debug('Audit logging is currently disabled in production environment')
72
+ return null
73
+ }
74
+
75
+ let logEvent, logStrMsg
76
+ if (project && project.org && project.workspace) {
77
+ if (event === 'AB_APP_DEPLOY') {
78
+ logStrMsg = `Starting deployment for the App Builder application in workspace ${project.workspace.name}`
79
+ } else if (event === 'AB_APP_UNDEPLOY') {
80
+ logStrMsg = `Starting undeployment for the App Builder application in workspace ${project.workspace.name}`
81
+ } else if (event === 'AB_APP_ASSETS_UNDEPLOYED') {
82
+ logStrMsg = `All static assets for the App Builder application in workspace: ${project.workspace.name} were successfully undeployed from the CDN`
83
+ } else if (event === 'AB_APP_ASSETS_DEPLOYED') {
84
+ logStrMsg = `All static assets for the App Builder application in workspace: ${project.workspace.name} were successfully deployed to the CDN.\n Files deployed - `
85
+ }
86
+
87
+ logEvent = {
88
+ orgId: project.org.id,
89
+ projectId: project.id,
90
+ workspaceId: project.workspace.id,
91
+ workspaceName: project.workspace.name,
92
+ operation: event in OPERATIONS ? OPERATIONS[event] : OPERATIONS.AB_APP_TEST,
93
+ timestamp: new Date().valueOf(),
94
+ data: {
95
+ cliCommandFlags: flags,
96
+ opDetailsStr: logStrMsg
97
+ }
98
+ }
99
+ }
100
+ return logEvent
101
+ }
102
+
103
+ /**
104
+ *
105
+ * @param {string} directory | path to assets directory
106
+ * @returns {Array} log | array of log messages
107
+ */
108
+ function getFilesCountWithExtension (directory) {
109
+ const log = []
110
+
111
+ if (!fs.existsSync(directory)) {
112
+ this.log(chalk.red(chalk.bold(`Error: Directory ${directory} does not exist.`)))
113
+ return log
114
+ }
115
+
116
+ const files = fs.readdirSync(directory)
117
+
118
+ if (files.length === 0) {
119
+ this.log(chalk.red(chalk.bold(`Error: No files found in directory ${directory}.`)))
120
+ return log
121
+ }
122
+
123
+ const fileTypeCounts = {}
124
+
125
+ files.forEach(file => {
126
+ const ext = path.extname(file).toLowerCase() || 'no extension'
127
+ if (fileTypeCounts[ext]) {
128
+ fileTypeCounts[ext]++
129
+ } else {
130
+ fileTypeCounts[ext] = 1
131
+ }
132
+ })
133
+
134
+ Object.keys(fileTypeCounts).forEach(ext => {
135
+ const count = fileTypeCounts[ext]
136
+ let description
137
+
138
+ if (ext === '.js') description = 'Javascript file(s)'
139
+ else if (ext === '.css') description = 'CSS file(s)'
140
+ else if (ext === '.html') description = 'HTML page(s)'
141
+ else if (['.png', '.jpg', '.jpeg', '.gif', '.svg', '.webp'].includes(ext)) description = 'image(s)'
142
+ else if (ext === 'no extension') description = 'file(s) without extension'
143
+ else description = `${ext} file(s)`
144
+
145
+ log.push(`${count} ${description}\n`)
146
+ })
147
+
148
+ return log
149
+ }
150
+
151
+ module.exports = {
152
+ sendAuditLogs,
153
+ getAuditLogEvent,
154
+ AUDIT_SERVICE_ENPOINTS,
155
+ getFilesCountWithExtension
156
+ }
@@ -82,8 +82,7 @@ async function runDev (config, dataDir, options = {}, log = () => {}, inprocHook
82
82
 
83
83
  // build and deploy actions
84
84
  log('building actions..')
85
- await buildActions(devConfig, null, true /* force build */)
86
-
85
+ await buildActions(devConfig, null, false /* force build */)
87
86
  const { cleanup: watcherCleanup } = await actionsWatcher({ config: devConfig, isLocal, log, inprocHook })
88
87
  cleanup.add(() => watcherCleanup(), 'stopping action watcher...')
89
88
  }
@@ -152,10 +151,16 @@ async function runDev (config, dataDir, options = {}, log = () => {}, inprocHook
152
151
  devConfig.app.hasFrontend = false
153
152
  }
154
153
 
155
- log('setting up vscode debug configuration files...')
156
- const vscodeConfig = vscode(devConfig)
157
- await vscodeConfig.update({ frontEndUrl })
158
- cleanup.add(() => vscodeConfig.cleanup(), 'cleaning up vscode debug configuration files...')
154
+ // todo: remove vscode config swapping, dev command uses a persistent file so we don't need this.
155
+ // also there was a latent issue with projects that defined an action src as a folder with an index.js file.
156
+ // it looks explicitly for package.json and fails if it does not find it.
157
+ // regarless, we don't need it, and when we actually remove --local we can be rid of this.
158
+ if (isLocal) {
159
+ log('setting up vscode debug configuration files...')
160
+ const vscodeConfig = vscode(devConfig)
161
+ await vscodeConfig.update({ frontEndUrl })
162
+ cleanup.add(() => vscodeConfig.cleanup(), 'cleaning up vscode debug configuration files...')
163
+ }
159
164
 
160
165
  // automatically fetch logs if there are actions
161
166
  if (config.app.hasBackend && fetchLogs) {