Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,14 @@
"author": "Adobe Inc.",
"bugs": "https://github.com/adobe/aio-cli-plugin-app/issues",
"dependencies": {
"@adobe/aio-cli-lib-app-config": "^4",
"@adobe/aio-cli-lib-app-config": "^4.0.3",
"@adobe/aio-cli-lib-console": "^5",
"@adobe/aio-lib-core-config": "^5",
"@adobe/aio-lib-core-logging": "^3",
"@adobe/aio-lib-core-networking": "^5",
"@adobe/aio-lib-env": "^3",
"@adobe/aio-lib-ims": "^7",
"@adobe/aio-lib-runtime": "^7.0.0",
"@adobe/aio-lib-runtime": "^7.0.1",
"@adobe/aio-lib-templates": "^3",
"@adobe/aio-lib-web": "^7",
"@adobe/generator-aio-app": "^7",
Expand Down
22 changes: 4 additions & 18 deletions src/commands/app/deploy.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,11 @@ const BaseCommand = require('../../BaseCommand')
const BuildCommand = require('./build')
const webLib = require('@adobe/aio-lib-web')
const { Flags } = require('@oclif/core')
const { createWebExportFilter, runInProcess, buildExtensionPointPayloadWoMetadata, buildExcShellViewExtensionMetadata, getCliInfo } = require('../../lib/app-helper')
const { runInProcess, buildExtensionPointPayloadWoMetadata, buildExcShellViewExtensionMetadata, getCliInfo } = require('../../lib/app-helper')
const rtLib = require('@adobe/aio-lib-runtime')
const LogForwarding = require('../../lib/log-forwarding')
const { sendAuditLogs, getAuditLogEvent, getFilesCountWithExtension } = require('../../lib/audit-logger')
const logActions = require('../../lib/log-actions')

const PRE_DEPLOY_EVENT_REG = 'pre-deploy-event-reg'
const POST_DEPLOY_EVENT_REG = 'post-deploy-event-reg'
Expand Down Expand Up @@ -235,24 +236,9 @@ class Deploy extends BuildCommand {

// log deployed resources
if (deployedRuntimeEntities.actions && deployedRuntimeEntities.actions.length > 0) {
this.log(chalk.blue(chalk.bold('Your deployed actions:')))
const web = deployedRuntimeEntities.actions.filter(createWebExportFilter(true))
const nonWeb = deployedRuntimeEntities.actions.filter(createWebExportFilter(false))

if (web.length > 0) {
this.log('web actions:')
web.forEach(a => {
this.log(chalk.blue(chalk.bold(` -> ${a.url || a.name} `)))
})
}

if (nonWeb.length > 0) {
this.log('non-web actions:')
nonWeb.forEach(a => {
this.log(chalk.blue(chalk.bold(` -> ${a.url || a.name} `)))
})
}
await logActions({ entities: deployedRuntimeEntities, log: (...rest) => this.log(chalk.bold(chalk.blue(...rest))) })
}

// TODO urls should depend on extension point, exc shell only for exc shell extension point - use a post-app-deploy hook ?
if (deployedFrontendUrl) {
this.log(chalk.blue(chalk.bold(`To view your deployed application:\n -> ${deployedFrontendUrl}`)))
Expand Down
4 changes: 2 additions & 2 deletions src/commands/app/undeploy.js
Original file line number Diff line number Diff line change
Expand Up @@ -112,9 +112,9 @@ class Undeploy extends BaseCommand {
if (!script) {
await rtLib.undeployActions(config)
}
spinner.succeed(chalk.green(`Un-Deploying actions for ${extName}`))
spinner.succeed(chalk.green(`Un-deploying actions for ${extName}`))
} catch (err) {
spinner.fail(chalk.green(`Un-Deploying actions for ${extName}`))
spinner.fail(chalk.green(`Un-deploying actions for ${extName}`))
throw err
}
} else {
Expand Down
8 changes: 7 additions & 1 deletion src/lib/actions-watcher.js
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,13 @@ module.exports = async (watcherOptions) => {
async function buildAndDeploy (watcherOptions, filterActions) {
const { config, isLocal, log, inprocHook } = watcherOptions
await buildActions(config, filterActions)
await deployActions(config, isLocal, log, filterActions, inprocHook)
const deployConfig = {
isLocalDev: isLocal,
filterEntities: {
actions: filterActions
}
}
await deployActions({ config, deployConfig, log, inprocHook })
}

/**
Expand Down
6 changes: 4 additions & 2 deletions src/lib/app-helper.js
Original file line number Diff line number Diff line change
Expand Up @@ -551,11 +551,13 @@ function deleteUserConfig (configData) {
/** @private */
const createWebExportFilter = (filterValue) => {
return (action) => {
if (!action || !action.annotations) {
if (!action) {
return false
}

return String(!!action.annotations['web-export']) === String(filterValue)
// if no annotations, its as if web-export = false
const webExportValue = action.annotations?.['web-export'] ?? false
return String(!!webExportValue) === String(filterValue)
}
}

Expand Down
70 changes: 31 additions & 39 deletions src/lib/deploy-actions.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
Copyright 2020 Adobe. All rights reserved.
Copyright 2024 Adobe. All rights reserved.
This file is licensed to you under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. You may obtain a copy
of the License at http://www.apache.org/licenses/LICENSE-2.0
Expand All @@ -10,60 +10,52 @@ OF ANY KIND, either express or implied. See the License for the specific languag
governing permissions and limitations under the License.
*/

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

/**
* Deploys actions.
*
* @param {object} config see src/lib/config-loader.js
* @param {boolean} isLocalDev default false, set to true if it's a local deploy
* @param {Function} [log] a log function
* @param {boolean} filter true if a filter by built actions is desired.
* @private
* @param {object} options
* @param {object} options.config see src/lib/config-loader.js
* @param {object} [options.deployConfig] see https://github.com/adobe/aio-lib-runtime/blob/master/README.md#typedefs
* @param {Function} [options.log] a log function
* @param {Function} [options.inprocHook] a hook function
*/
/** @private */
module.exports = async (config, isLocalDev = false, log = () => {}, filter = false, inprocHook) => {
module.exports = async ({
config,
deployConfig = {},
log = () => {},
inprocHook
}) => {
await runInProcess(config.hooks['pre-app-deploy'], config)
const script = await runInProcess(config.hooks['deploy-actions'], { config, options: { isLocalDev, filter } })

const hookFilterEntities = Array.isArray(deployConfig.filterEntities?.actions) ? deployConfig.filterEntities.actions : []
const hookData = {
appConfig: config,
filterEntities: hookFilterEntities,
isLocalDev: deployConfig.isLocalDev
}

let entities
const script = await runInProcess(config.hooks['deploy-actions'], hookData)
if (!script) {
const deployConfig = {
isLocalDev,
filterEntities: {
byBuiltActions: filter
}
}
if (inprocHook) {
const hookFilterEntities = Array.isArray(filter) ? filter : []
const hookResults = await inprocHook('deploy-actions', {
appConfig: config,
filterEntities: hookFilterEntities,
isLocalDev
})
const hookResults = await inprocHook('deploy-actions', hookData)
if (hookResults?.failures?.length > 0) {
// output should be "Error : <plugin-name> : <error-message>\n" for each failure
log('Error: ' + hookResults.failures.map(f => `${f.plugin.name} : ${f.error.message}`).join('\nError: '))
throw new Error(`Hook 'deploy-actions' failed with ${hookResults.failures[0].error}`)
}
}
const entities = await deployActions(config, deployConfig, log)
if (entities.actions) {
const web = entities.actions.filter(createWebExportFilter(true))
const nonWeb = entities.actions.filter(createWebExportFilter(false))

if (web.length > 0) {
log('web actions:')
web.forEach(a => {
log(` -> ${a.url || a.name}`)
})
}

if (nonWeb.length > 0) {
log('non-web actions:')
nonWeb.forEach(a => {
log(` -> ${a.url || a.name}`)
})
}
}
entities = await deployActions(config, deployConfig, log)
await logActions({ entities, log })
}

await runInProcess(config.hooks['post-app-deploy'], config)

return { script, entities }
}
52 changes: 52 additions & 0 deletions src/lib/log-actions.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
/*
Copyright 2024 Adobe. All rights reserved.
This file is licensed to you under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. You may obtain a copy
of the License at http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under
the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONSTJ
OF ANY KIND, either express or implied. See the License for the specific language
governing permissions and limitations under the License.
*/

const { createWebExportFilter } = require('./app-helper')

/**
* Logs deployed action entities.
*
* @private
* @param {object} options
* @param {object} options.entities runtime entities that have been deployed
* @param {object} [options.deployConfig] see https://github.com/adobe/aio-lib-runtime?tab=readme-ov-file#typedefs
* @param {Function} [options.log] a log function
*/
module.exports = async ({
entities,
log = console.log
}) => {
if (!entities.actions) {
return
}

log('Your deployed actions:')

const _web = entities.actions.filter(createWebExportFilter(true))
const _webRaw = entities.actions.filter(createWebExportFilter('raw'))
const web = [..._web, ..._webRaw]
const nonWeb = entities.actions.filter(createWebExportFilter(false))

if (web.length > 0) {
log('web actions:')
web.forEach(a => {
log(` -> ${a.url || a.name}`)
})
}

if (nonWeb.length > 0) {
log('non-web actions:')
nonWeb.forEach(a => {
log(` -> ${a.url || a.name}`)
})
}
}
13 changes: 12 additions & 1 deletion src/lib/run-dev.js
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,18 @@ async function runDev (config, dataDir, options = {}, log = () => {}, inprocHook
// Deploy Phase - deploy actions
if (withBackend) {
log('redeploying actions..')
await deployActions(devConfig, isLocal, log, true, inprocHook)
const deployConfig = {
isLocalDev: isLocal,
filterEntities: {
byBuiltActions: true
}
}
await deployActions({
config: devConfig,
deployConfig,
log,
inprocHook
})
}

// Deploy Phase - serve the web UI
Expand Down
30 changes: 28 additions & 2 deletions test/commands/lib/app-helper.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ jest.mock('@adobe/aio-lib-core-networking', () => ({

jest.mock('@adobe/aio-lib-core-config')
jest.mock('execa')
jest.mock('process')
jest.mock('path')
jest.mock('fs-extra') // do not touch the real fs
jest.mock('@adobe/aio-lib-env')
Expand Down Expand Up @@ -919,9 +918,25 @@ describe('createWebExportFilter', () => {
const webFilter = appHelper.createWebExportFilter(true)
const nonWebFilter = appHelper.createWebExportFilter(false)

test('null action', () => {
const action = null

expect(webFilter(action)).toEqual(false)
expect(nonWebFilter(action)).toEqual(false)
})

test('no annotations', () => {
const action = {
name: 'abcde', url: 'https://fake.site'
}

expect(webFilter(action)).toEqual(false)
expect(nonWebFilter(action)).toEqual(true)
})

test('no web-export annotation', () => {
const action = {
name: 'abcde', url: 'https://fake.site', annotations: []
name: 'abcde', url: 'https://fake.site', annotations: {}
}

expect(webFilter(action)).toEqual(false)
Expand Down Expand Up @@ -967,6 +982,17 @@ describe('createWebExportFilter', () => {
expect(webFilter(action2)).toEqual(false)
expect(nonWebFilter(action2)).toEqual(true)
})

test('web-export: raw annotation', () => {
const action1 = {
name: 'abcde',
url: 'https://fake.site',
annotations: { 'web-export': 'raw' }
}

expect(webFilter(action1)).toEqual(true)
expect(nonWebFilter(action1)).toEqual(false)
})
})

describe('object values', () => {
Expand Down
Loading