@adobe/aio-cli-plugin-app 13.1.1 → 13.1.3

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/package.json CHANGED
@@ -1,18 +1,18 @@
1
1
  {
2
2
  "name": "@adobe/aio-cli-plugin-app",
3
3
  "description": "Create, Build and Deploy Adobe I/O Applications",
4
- "version": "13.1.1",
4
+ "version": "13.1.3",
5
5
  "author": "Adobe Inc.",
6
6
  "bugs": "https://github.com/adobe/aio-cli-plugin-app/issues",
7
7
  "dependencies": {
8
- "@adobe/aio-cli-lib-app-config": "^4",
8
+ "@adobe/aio-cli-lib-app-config": "^4.0.3",
9
9
  "@adobe/aio-cli-lib-console": "^5",
10
10
  "@adobe/aio-lib-core-config": "^5",
11
11
  "@adobe/aio-lib-core-logging": "^3",
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": "^7.0.0",
15
+ "@adobe/aio-lib-runtime": "^7.0.1",
16
16
  "@adobe/aio-lib-templates": "^3",
17
17
  "@adobe/aio-lib-web": "^7",
18
18
  "@adobe/generator-aio-app": "^7",
@@ -54,22 +54,22 @@
54
54
  },
55
55
  "devDependencies": {
56
56
  "@adobe/aio-lib-test-proxy": "^2",
57
- "@adobe/eslint-config-aio-lib-config": "^3.0.0",
57
+ "@adobe/eslint-config-aio-lib-config": "^4.0.0",
58
58
  "@types/jest": "^29",
59
59
  "babel-runtime": "^6.26.0",
60
60
  "core-js": "^3",
61
61
  "eol": "^0.9.1",
62
- "eslint": "^8.46.0",
62
+ "eslint": "^8.57.1",
63
63
  "eslint-config-standard": "^17.1.0",
64
- "eslint-plugin-import": "^2.28.0",
65
- "eslint-plugin-jest": "^27.2.3",
66
- "eslint-plugin-jsdoc": "^42.0.0",
67
- "eslint-plugin-n": "^15.7",
64
+ "eslint-plugin-import": "^2.31.0",
65
+ "eslint-plugin-jest": "^27.9.0",
66
+ "eslint-plugin-jsdoc": "^48.11.0",
67
+ "eslint-plugin-n": "^15.7.0",
68
68
  "eslint-plugin-node": "^11.1.0",
69
- "eslint-plugin-promise": "^6.1.1",
69
+ "eslint-plugin-promise": "^6.6.0",
70
70
  "jest": "^29.5.0",
71
71
  "nock": "^13.2.9",
72
- "oclif": "^3.2.0",
72
+ "oclif": "^4.17.13",
73
73
  "stdout-stderr": "^0.1.9"
74
74
  },
75
75
  "engines": {
@@ -18,10 +18,11 @@ 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, getCliInfo } = require('../../lib/app-helper')
21
+ const { 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
24
  const { sendAuditLogs, getAuditLogEvent, getFilesCountWithExtension } = require('../../lib/audit-logger')
25
+ const logActions = require('../../lib/log-actions')
25
26
 
26
27
  const PRE_DEPLOY_EVENT_REG = 'pre-deploy-event-reg'
27
28
  const POST_DEPLOY_EVENT_REG = 'post-deploy-event-reg'
@@ -64,7 +65,7 @@ class Deploy extends BuildCommand {
64
65
  const lfConfig = lf.getLocalConfigWithSecrets()
65
66
  if (lfConfig.isDefined()) {
66
67
  await lf.updateServerConfig(lfConfig)
67
- spinner.succeed(chalk.green(`Log forwarding is set to '${lfConfig.getDestination()}'`))
68
+ spinner.succeed(chalk.green(`\nLog forwarding is set to '${lfConfig.getDestination()}'`))
68
69
  } else {
69
70
  if (flags.verbose) {
70
71
  spinner.info(chalk.dim('Log forwarding is not updated: no configuration is provided'))
@@ -93,14 +94,6 @@ class Deploy extends BuildCommand {
93
94
  }
94
95
  }
95
96
 
96
- // 3. send deploy log event
97
- const logEvent = getAuditLogEvent(flags, aioConfig.project, 'AB_APP_DEPLOY')
98
- if (logEvent) {
99
- await sendAuditLogs(cliDetails.accessToken, logEvent, cliDetails.env)
100
- } else {
101
- this.log(chalk.red(chalk.bold('Warning: No valid config data found to send audit log event for deployment.')))
102
- }
103
-
104
97
  // 4. deploy actions and web assets for each extension
105
98
  // Possible improvements:
106
99
  // - parallelize
@@ -112,9 +105,14 @@ class Deploy extends BuildCommand {
112
105
  if (v.app.hasFrontend && flags['web-assets']) {
113
106
  const opItems = getFilesCountWithExtension(v.web.distProd)
114
107
  const assetDeployedLogEvent = getAuditLogEvent(flags, aioConfig.project, 'AB_APP_ASSETS_DEPLOYED')
115
- if (assetDeployedLogEvent) {
108
+ if (assetDeployedLogEvent && cliDetails?.accessToken) {
116
109
  assetDeployedLogEvent.data.opItems = opItems
117
- await sendAuditLogs(cliDetails.accessToken, assetDeployedLogEvent, cliDetails.env)
110
+ try {
111
+ // only send logs in case of web-assets deployment
112
+ await sendAuditLogs(cliDetails.accessToken, assetDeployedLogEvent, cliDetails.env)
113
+ } catch (error) {
114
+ this.warn('Error: Audit Log Service Error: Failed to send audit log event for deployment.')
115
+ }
118
116
  }
119
117
  }
120
118
  }
@@ -238,24 +236,9 @@ class Deploy extends BuildCommand {
238
236
 
239
237
  // log deployed resources
240
238
  if (deployedRuntimeEntities.actions && deployedRuntimeEntities.actions.length > 0) {
241
- this.log(chalk.blue(chalk.bold('Your deployed actions:')))
242
- const web = deployedRuntimeEntities.actions.filter(createWebExportFilter(true))
243
- const nonWeb = deployedRuntimeEntities.actions.filter(createWebExportFilter(false))
244
-
245
- if (web.length > 0) {
246
- this.log('web actions:')
247
- web.forEach(a => {
248
- this.log(chalk.blue(chalk.bold(` -> ${a.url || a.name} `)))
249
- })
250
- }
251
-
252
- if (nonWeb.length > 0) {
253
- this.log('non-web actions:')
254
- nonWeb.forEach(a => {
255
- this.log(chalk.blue(chalk.bold(` -> ${a.url || a.name} `)))
256
- })
257
- }
239
+ await logActions({ entities: deployedRuntimeEntities, log: (...rest) => this.log(chalk.bold(chalk.blue(...rest))) })
258
240
  }
241
+
259
242
  // TODO urls should depend on extension point, exc shell only for exc shell extension point - use a post-app-deploy hook ?
260
243
  if (deployedFrontendUrl) {
261
244
  this.log(chalk.blue(chalk.bold(`To view your deployed application:\n -> ${deployedFrontendUrl}`)))
@@ -27,16 +27,21 @@ class Undeploy extends BaseCommand {
27
27
  const { flags } = await this.parse(Undeploy)
28
28
 
29
29
  const undeployConfigs = await this.getAppExtConfigs(flags)
30
+
31
+ // 1. undeploy actions and web assets for each extension
32
+ const keys = Object.keys(undeployConfigs)
33
+ const values = Object.values(undeployConfigs)
34
+
35
+ // if it is standalone app, unpublish it without token
36
+ const isStandaloneApp = (keys.length === 1 && keys[0] === 'application')
37
+ flags.unpublish = flags.unpublish && !isStandaloneApp
38
+
30
39
  let libConsoleCLI
31
40
  if (flags.unpublish) {
32
41
  // force login at beginning (if required)
33
42
  libConsoleCLI = await this.getLibConsoleCLI()
34
43
  }
35
44
 
36
- // 1. undeploy actions and web assets for each extension
37
- const keys = Object.keys(undeployConfigs)
38
- const values = Object.values(undeployConfigs)
39
-
40
45
  if (
41
46
  (!flags.unpublish && !flags['web-assets'] && !flags.actions)
42
47
  ) {
@@ -46,28 +51,25 @@ class Undeploy extends BaseCommand {
46
51
  const spinner = ora()
47
52
  try {
48
53
  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
- }
54
+ const cliDetails = await getCliInfo(flags.unpublish)
58
55
 
59
56
  for (let i = 0; i < keys.length; ++i) {
60
57
  const k = keys[i]
61
58
  const v = values[i]
62
59
  await this.undeployOneExt(k, v, flags, spinner)
63
60
  const assetUndeployLogEvent = getAuditLogEvent(flags, aioConfig.project, 'AB_APP_ASSETS_UNDEPLOYED')
64
- if (assetUndeployLogEvent) {
65
- await sendAuditLogs(cliDetails.accessToken, assetUndeployLogEvent, cliDetails.env)
61
+ // send logs for case of web-assets undeployment
62
+ if (assetUndeployLogEvent && cliDetails?.accessToken) {
63
+ try {
64
+ await sendAuditLogs(cliDetails.accessToken, assetUndeployLogEvent, cliDetails.env)
65
+ } catch (error) {
66
+ this.warn('Warning: Audit Log Service Error: Failed to send audit log event for un-deployment.')
67
+ }
66
68
  }
67
69
  }
68
70
 
69
71
  // 1.2. unpublish extension manifest
70
- if (flags.unpublish && !(keys.length === 1 && keys[0] === 'application')) {
72
+ if (flags.unpublish) {
71
73
  const payload = await this.unpublishExtensionPoints(libConsoleCLI, undeployConfigs, aioConfig, flags['force-unpublish'])
72
74
  this.log(chalk.blue(chalk.bold(`New Extension Point(s) in Workspace '${aioConfig.project.workspace.name}': '${Object.keys(payload.endpoints)}'`)))
73
75
  } else {
@@ -110,9 +112,9 @@ class Undeploy extends BaseCommand {
110
112
  if (!script) {
111
113
  await rtLib.undeployActions(config)
112
114
  }
113
- spinner.succeed(chalk.green(`Un-Deploying actions for ${extName}`))
115
+ spinner.succeed(chalk.green(`Un-deploying actions for ${extName}`))
114
116
  } catch (err) {
115
- spinner.fail(chalk.green(`Un-Deploying actions for ${extName}`))
117
+ spinner.fail(chalk.green(`Un-deploying actions for ${extName}`))
116
118
  throw err
117
119
  }
118
120
  } else {
@@ -63,7 +63,13 @@ module.exports = async (watcherOptions) => {
63
63
  async function buildAndDeploy (watcherOptions, filterActions) {
64
64
  const { config, isLocal, log, inprocHook } = watcherOptions
65
65
  await buildActions(config, filterActions)
66
- await deployActions(config, isLocal, log, filterActions, inprocHook)
66
+ const deployConfig = {
67
+ isLocalDev: isLocal,
68
+ filterEntities: {
69
+ actions: filterActions
70
+ }
71
+ }
72
+ await deployActions({ config, deployConfig, log, inprocHook })
67
73
  }
68
74
 
69
75
  /**
@@ -155,7 +155,7 @@ async function runScript (command, dir, cmdArgs = []) {
155
155
  aioLogger.debug(`Killing ${command} event hook long-running process (pid: ${pid})`)
156
156
  process.kill(pid, 'SIGTERM')
157
157
  } catch (_) {
158
- // do nothing if pid not found
158
+ // do nothing if pid not found
159
159
  }
160
160
  })
161
161
  }
@@ -551,11 +551,13 @@ function deleteUserConfig (configData) {
551
551
  /** @private */
552
552
  const createWebExportFilter = (filterValue) => {
553
553
  return (action) => {
554
- if (!action || !action.annotations) {
554
+ if (!action) {
555
555
  return false
556
556
  }
557
557
 
558
- return String(!!action.annotations['web-export']) === String(filterValue)
558
+ // if no annotations, its as if web-export = false
559
+ const webExportValue = action.annotations?.['web-export'] ?? false
560
+ return String(!!webExportValue) === String(filterValue)
559
561
  }
560
562
  }
561
563
 
@@ -12,18 +12,16 @@ const fetch = require('node-fetch')
12
12
  const fs = require('fs')
13
13
  const path = require('path')
14
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
15
 
18
16
  const OPERATIONS = {
19
17
  AB_APP_DEPLOY: 'ab_app_deploy',
20
18
  AB_APP_UNDEPLOY: 'ab_app_undeploy',
21
- AB_APP_TEST: 'ab_app_test', // todo : remove after testing
19
+ AB_APP_TEST: 'ab_app_test',
22
20
  AB_APP_ASSETS_DEPLOYED: 'ab_app_assets_deployed',
23
21
  AB_APP_ASSETS_UNDEPLOYED: 'ab_app_assets_undeployed'
24
22
  }
25
23
 
26
- const AUDIT_SERVICE_ENPOINTS = {
24
+ const AUDIT_SERVICE_ENDPOINTS = {
27
25
  stage: 'https://adp-auditlog-service-stage.adobeioruntime.net/api/v1/web/audit-log-api/event-post',
28
26
  prod: 'https://adp-auditlog-service-prod.adobeioruntime.net/api/v1/web/audit-log-api/event-post'
29
27
  }
@@ -35,12 +33,7 @@ const AUDIT_SERVICE_ENPOINTS = {
35
33
  * @param {string} env valid env stage|prod
36
34
  */
37
35
  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]
36
+ const url = AUDIT_SERVICE_ENDPOINTS[env] ?? AUDIT_SERVICE_ENDPOINTS.prod
44
37
  const payload = {
45
38
  event: logEvent
46
39
  }
@@ -67,11 +60,6 @@ async function sendAuditLogs (accessToken, logEvent, env = 'prod') {
67
60
  * @returns {object} logEvent
68
61
  */
69
62
  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
63
  let logEvent, logStrMsg
76
64
  if (project && project.org && project.workspace) {
77
65
  if (event === 'AB_APP_DEPLOY') {
@@ -113,7 +101,7 @@ function getFilesCountWithExtension (directory) {
113
101
  return log
114
102
  }
115
103
 
116
- const files = fs.readdirSync(directory)
104
+ const files = fs.readdirSync(directory, { recursive: true })
117
105
 
118
106
  if (files.length === 0) {
119
107
  this.log(chalk.red(chalk.bold(`Error: No files found in directory ${directory}.`)))
@@ -121,7 +109,6 @@ function getFilesCountWithExtension (directory) {
121
109
  }
122
110
 
123
111
  const fileTypeCounts = {}
124
-
125
112
  files.forEach(file => {
126
113
  const ext = path.extname(file).toLowerCase() || 'no extension'
127
114
  if (fileTypeCounts[ext]) {
@@ -134,23 +121,38 @@ function getFilesCountWithExtension (directory) {
134
121
  Object.keys(fileTypeCounts).forEach(ext => {
135
122
  const count = fileTypeCounts[ext]
136
123
  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
-
124
+ switch (ext) {
125
+ case '.js':
126
+ description = 'Javascript file(s)'
127
+ break
128
+ case '.css':
129
+ description = 'CSS file(s)'
130
+ break
131
+ case '.html':
132
+ description = 'HTML page(s)'
133
+ break
134
+ case '.png':
135
+ case '.jpg':
136
+ case '.jpeg':
137
+ case '.gif':
138
+ case '.svg':
139
+ case '.webp':
140
+ description = `${ext} image(s)`
141
+ break
142
+ case 'no extension':
143
+ description = 'file(s) without extension'
144
+ break
145
+ default:
146
+ description = `${ext} file(s)`
147
+ }
145
148
  log.push(`${count} ${description}\n`)
146
149
  })
147
-
148
150
  return log
149
151
  }
150
152
 
151
153
  module.exports = {
152
154
  sendAuditLogs,
153
155
  getAuditLogEvent,
154
- AUDIT_SERVICE_ENPOINTS,
156
+ AUDIT_SERVICE_ENDPOINTS,
155
157
  getFilesCountWithExtension
156
158
  }
@@ -1,5 +1,5 @@
1
1
  /*
2
- Copyright 2020 Adobe. All rights reserved.
2
+ Copyright 2024 Adobe. All rights reserved.
3
3
  This file is licensed to you under the Apache License, Version 2.0 (the "License");
4
4
  you may not use this file except in compliance with the License. You may obtain a copy
5
5
  of the License at http://www.apache.org/licenses/LICENSE-2.0
@@ -10,60 +10,52 @@ OF ANY KIND, either express or implied. See the License for the specific languag
10
10
  governing permissions and limitations under the License.
11
11
  */
12
12
 
13
- const { runInProcess, createWebExportFilter } = require('./app-helper')
13
+ const { runInProcess } = require('./app-helper')
14
14
  const { deployActions } = require('@adobe/aio-lib-runtime')
15
+ const logActions = require('./log-actions')
15
16
 
16
17
  /**
17
18
  * Deploys actions.
18
19
  *
19
- * @param {object} config see src/lib/config-loader.js
20
- * @param {boolean} isLocalDev default false, set to true if it's a local deploy
21
- * @param {Function} [log] a log function
22
- * @param {boolean} filter true if a filter by built actions is desired.
20
+ * @private
21
+ * @param {object} options
22
+ * @param {object} options.config see src/lib/config-loader.js
23
+ * @param {object} [options.deployConfig] see https://github.com/adobe/aio-lib-runtime/blob/master/README.md#typedefs
24
+ * @param {Function} [options.log] a log function
25
+ * @param {Function} [options.inprocHook] a hook function
23
26
  */
24
- /** @private */
25
- module.exports = async (config, isLocalDev = false, log = () => {}, filter = false, inprocHook) => {
27
+ module.exports = async ({
28
+ config,
29
+ deployConfig = {},
30
+ log = () => {},
31
+ inprocHook
32
+ }) => {
26
33
  await runInProcess(config.hooks['pre-app-deploy'], config)
27
- const script = await runInProcess(config.hooks['deploy-actions'], { config, options: { isLocalDev, filter } })
34
+
35
+ const hookFilterEntities = Array.isArray(deployConfig.filterEntities?.actions) ? deployConfig.filterEntities.actions : []
36
+ const hookData = {
37
+ appConfig: config,
38
+ filterEntities: hookFilterEntities,
39
+ isLocalDev: deployConfig.isLocalDev
40
+ }
41
+
42
+ let entities
43
+ const script = await runInProcess(config.hooks['deploy-actions'], hookData)
28
44
  if (!script) {
29
- const deployConfig = {
30
- isLocalDev,
31
- filterEntities: {
32
- byBuiltActions: filter
33
- }
34
- }
35
45
  if (inprocHook) {
36
- const hookFilterEntities = Array.isArray(filter) ? filter : []
37
- const hookResults = await inprocHook('deploy-actions', {
38
- appConfig: config,
39
- filterEntities: hookFilterEntities,
40
- isLocalDev
41
- })
46
+ const hookResults = await inprocHook('deploy-actions', hookData)
42
47
  if (hookResults?.failures?.length > 0) {
43
48
  // output should be "Error : <plugin-name> : <error-message>\n" for each failure
44
49
  log('Error: ' + hookResults.failures.map(f => `${f.plugin.name} : ${f.error.message}`).join('\nError: '))
45
50
  throw new Error(`Hook 'deploy-actions' failed with ${hookResults.failures[0].error}`)
46
51
  }
47
52
  }
48
- const entities = await deployActions(config, deployConfig, log)
49
- if (entities.actions) {
50
- const web = entities.actions.filter(createWebExportFilter(true))
51
- const nonWeb = entities.actions.filter(createWebExportFilter(false))
52
53
 
53
- if (web.length > 0) {
54
- log('web actions:')
55
- web.forEach(a => {
56
- log(` -> ${a.url || a.name}`)
57
- })
58
- }
59
-
60
- if (nonWeb.length > 0) {
61
- log('non-web actions:')
62
- nonWeb.forEach(a => {
63
- log(` -> ${a.url || a.name}`)
64
- })
65
- }
66
- }
54
+ entities = await deployActions(config, deployConfig, log)
55
+ await logActions({ entities, log })
67
56
  }
57
+
68
58
  await runInProcess(config.hooks['post-app-deploy'], config)
59
+
60
+ return { script, entities }
69
61
  }
@@ -0,0 +1,52 @@
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
+
7
+ Unless required by applicable law or agreed to in writing, software distributed under
8
+ the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONSTJ
9
+ OF ANY KIND, either express or implied. See the License for the specific language
10
+ governing permissions and limitations under the License.
11
+ */
12
+
13
+ const { createWebExportFilter } = require('./app-helper')
14
+
15
+ /**
16
+ * Logs deployed action entities.
17
+ *
18
+ * @private
19
+ * @param {object} options
20
+ * @param {object} options.entities runtime entities that have been deployed
21
+ * @param {object} [options.deployConfig] see https://github.com/adobe/aio-lib-runtime?tab=readme-ov-file#typedefs
22
+ * @param {Function} [options.log] a log function
23
+ */
24
+ module.exports = async ({
25
+ entities,
26
+ log = console.log
27
+ }) => {
28
+ if (!entities.actions) {
29
+ return
30
+ }
31
+
32
+ log('Your deployed actions:')
33
+
34
+ const _web = entities.actions.filter(createWebExportFilter(true))
35
+ const _webRaw = entities.actions.filter(createWebExportFilter('raw'))
36
+ const web = [..._web, ..._webRaw]
37
+ const nonWeb = entities.actions.filter(createWebExportFilter(false))
38
+
39
+ if (web.length > 0) {
40
+ log('web actions:')
41
+ web.forEach(a => {
42
+ log(` -> ${a.url || a.name}`)
43
+ })
44
+ }
45
+
46
+ if (nonWeb.length > 0) {
47
+ log('non-web actions:')
48
+ nonWeb.forEach(a => {
49
+ log(` -> ${a.url || a.name}`)
50
+ })
51
+ }
52
+ }
@@ -122,7 +122,18 @@ async function runDev (config, dataDir, options = {}, log = () => {}, inprocHook
122
122
  // Deploy Phase - deploy actions
123
123
  if (withBackend) {
124
124
  log('redeploying actions..')
125
- await deployActions(devConfig, isLocal, log, true, inprocHook)
125
+ const deployConfig = {
126
+ isLocalDev: isLocal,
127
+ filterEntities: {
128
+ byBuiltActions: true
129
+ }
130
+ }
131
+ await deployActions({
132
+ config: devConfig,
133
+ deployConfig,
134
+ log,
135
+ inprocHook
136
+ })
126
137
  }
127
138
 
128
139
  // Deploy Phase - serve the web UI