Skip to content

Commit 7c44a98

Browse files
authoredJan 21, 2025··
fix: ACNA-3397 - web action does not have web in the url, resulting in an invalid link (#824)
1 parent 8f968ab commit 7c44a98

11 files changed

+309
-97
lines changed
 

‎package.json

+2-2
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,14 @@
55
"author": "Adobe Inc.",
66
"bugs": "https://github.com/adobe/aio-cli-plugin-app/issues",
77
"dependencies": {
8-
"@adobe/aio-cli-lib-app-config": "^4",
8+
"@adobe/aio-cli-lib-app-config": "^4.0.3",
99
"@adobe/aio-cli-lib-console": "^5",
1010
"@adobe/aio-lib-core-config": "^5",
1111
"@adobe/aio-lib-core-logging": "^3",
1212
"@adobe/aio-lib-core-networking": "^5",
1313
"@adobe/aio-lib-env": "^3",
1414
"@adobe/aio-lib-ims": "^7",
15-
"@adobe/aio-lib-runtime": "^7.0.0",
15+
"@adobe/aio-lib-runtime": "^7.0.1",
1616
"@adobe/aio-lib-templates": "^3",
1717
"@adobe/aio-lib-web": "^7",
1818
"@adobe/generator-aio-app": "^7",

‎src/commands/app/deploy.js

+4-18
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,11 @@ const BaseCommand = require('../../BaseCommand')
1818
const BuildCommand = require('./build')
1919
const webLib = require('@adobe/aio-lib-web')
2020
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')
2222
const rtLib = require('@adobe/aio-lib-runtime')
2323
const LogForwarding = require('../../lib/log-forwarding')
2424
const { sendAuditLogs, getAuditLogEvent, getFilesCountWithExtension } = require('../../lib/audit-logger')
25+
const logActions = require('../../lib/log-actions')
2526

2627
const PRE_DEPLOY_EVENT_REG = 'pre-deploy-event-reg'
2728
const POST_DEPLOY_EVENT_REG = 'post-deploy-event-reg'
@@ -235,24 +236,9 @@ class Deploy extends BuildCommand {
235236

236237
// log deployed resources
237238
if (deployedRuntimeEntities.actions && deployedRuntimeEntities.actions.length > 0) {
238-
this.log(chalk.blue(chalk.bold('Your deployed actions:')))
239-
const web = deployedRuntimeEntities.actions.filter(createWebExportFilter(true))
240-
const nonWeb = deployedRuntimeEntities.actions.filter(createWebExportFilter(false))
241-
242-
if (web.length > 0) {
243-
this.log('web actions:')
244-
web.forEach(a => {
245-
this.log(chalk.blue(chalk.bold(` -> ${a.url || a.name} `)))
246-
})
247-
}
248-
249-
if (nonWeb.length > 0) {
250-
this.log('non-web actions:')
251-
nonWeb.forEach(a => {
252-
this.log(chalk.blue(chalk.bold(` -> ${a.url || a.name} `)))
253-
})
254-
}
239+
await logActions({ entities: deployedRuntimeEntities, log: (...rest) => this.log(chalk.bold(chalk.blue(...rest))) })
255240
}
241+
256242
// TODO urls should depend on extension point, exc shell only for exc shell extension point - use a post-app-deploy hook ?
257243
if (deployedFrontendUrl) {
258244
this.log(chalk.blue(chalk.bold(`To view your deployed application:\n -> ${deployedFrontendUrl}`)))

‎src/commands/app/undeploy.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -112,9 +112,9 @@ class Undeploy extends BaseCommand {
112112
if (!script) {
113113
await rtLib.undeployActions(config)
114114
}
115-
spinner.succeed(chalk.green(`Un-Deploying actions for ${extName}`))
115+
spinner.succeed(chalk.green(`Un-deploying actions for ${extName}`))
116116
} catch (err) {
117-
spinner.fail(chalk.green(`Un-Deploying actions for ${extName}`))
117+
spinner.fail(chalk.green(`Un-deploying actions for ${extName}`))
118118
throw err
119119
}
120120
} else {

‎src/lib/actions-watcher.js

+7-1
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,13 @@ module.exports = async (watcherOptions) => {
6363
async function buildAndDeploy (watcherOptions, filterActions) {
6464
const { config, isLocal, log, inprocHook } = watcherOptions
6565
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 })
6773
}
6874

6975
/**

‎src/lib/app-helper.js

+4-2
Original file line numberDiff line numberDiff line change
@@ -551,11 +551,13 @@ function deleteUserConfig (configData) {
551551
/** @private */
552552
const createWebExportFilter = (filterValue) => {
553553
return (action) => {
554-
if (!action || !action.annotations) {
554+
if (!action) {
555555
return false
556556
}
557557

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)
559561
}
560562
}
561563

‎src/lib/deploy-actions.js

+31-39
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
Copyright 2020 Adobe. All rights reserved.
2+
Copyright 2024 Adobe. All rights reserved.
33
This file is licensed to you under the Apache License, Version 2.0 (the "License");
44
you may not use this file except in compliance with the License. You may obtain a copy
55
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
1010
governing permissions and limitations under the License.
1111
*/
1212

13-
const { runInProcess, createWebExportFilter } = require('./app-helper')
13+
const { runInProcess } = require('./app-helper')
1414
const { deployActions } = require('@adobe/aio-lib-runtime')
15+
const logActions = require('./log-actions')
1516

1617
/**
1718
* Deploys actions.
1819
*
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
2326
*/
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+
}) => {
2633
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)
2844
if (!script) {
29-
const deployConfig = {
30-
isLocalDev,
31-
filterEntities: {
32-
byBuiltActions: filter
33-
}
34-
}
3545
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)
4247
if (hookResults?.failures?.length > 0) {
4348
// output should be "Error : <plugin-name> : <error-message>\n" for each failure
4449
log('Error: ' + hookResults.failures.map(f => `${f.plugin.name} : ${f.error.message}`).join('\nError: '))
4550
throw new Error(`Hook 'deploy-actions' failed with ${hookResults.failures[0].error}`)
4651
}
4752
}
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))
5253

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 })
6756
}
57+
6858
await runInProcess(config.hooks['post-app-deploy'], config)
59+
60+
return { script, entities }
6961
}

‎src/lib/log-actions.js

+52
Original file line numberDiff line numberDiff line change
@@ -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+
}

‎src/lib/run-dev.js

+12-1
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,18 @@ async function runDev (config, dataDir, options = {}, log = () => {}, inprocHook
122122
// Deploy Phase - deploy actions
123123
if (withBackend) {
124124
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+
})
126137
}
127138

128139
// Deploy Phase - serve the web UI

‎test/commands/lib/app-helper.test.js

+28-2
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@ jest.mock('@adobe/aio-lib-core-networking', () => ({
2121

2222
jest.mock('@adobe/aio-lib-core-config')
2323
jest.mock('execa')
24-
jest.mock('process')
2524
jest.mock('path')
2625
jest.mock('fs-extra') // do not touch the real fs
2726
jest.mock('@adobe/aio-lib-env')
@@ -919,9 +918,25 @@ describe('createWebExportFilter', () => {
919918
const webFilter = appHelper.createWebExportFilter(true)
920919
const nonWebFilter = appHelper.createWebExportFilter(false)
921920

921+
test('null action', () => {
922+
const action = null
923+
924+
expect(webFilter(action)).toEqual(false)
925+
expect(nonWebFilter(action)).toEqual(false)
926+
})
927+
928+
test('no annotations', () => {
929+
const action = {
930+
name: 'abcde', url: 'https://fake.site'
931+
}
932+
933+
expect(webFilter(action)).toEqual(false)
934+
expect(nonWebFilter(action)).toEqual(true)
935+
})
936+
922937
test('no web-export annotation', () => {
923938
const action = {
924-
name: 'abcde', url: 'https://fake.site', annotations: []
939+
name: 'abcde', url: 'https://fake.site', annotations: {}
925940
}
926941

927942
expect(webFilter(action)).toEqual(false)
@@ -967,6 +982,17 @@ describe('createWebExportFilter', () => {
967982
expect(webFilter(action2)).toEqual(false)
968983
expect(nonWebFilter(action2)).toEqual(true)
969984
})
985+
986+
test('web-export: raw annotation', () => {
987+
const action1 = {
988+
name: 'abcde',
989+
url: 'https://fake.site',
990+
annotations: { 'web-export': 'raw' }
991+
}
992+
993+
expect(webFilter(action1)).toEqual(true)
994+
expect(nonWebFilter(action1)).toEqual(false)
995+
})
970996
})
971997

972998
describe('object values', () => {

0 commit comments

Comments
 (0)
Please sign in to comment.