Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ACNA-976 - feat: add new app event hooks for custom build scripts #340

Merged
merged 6 commits into from
Dec 4, 2020
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
30 changes: 25 additions & 5 deletions src/commands/app/build.js
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,16 @@ class Build extends BaseCommand {
if (!flags['skip-actions']) {
if (config.app.hasBackend && (flags['force-build'] || !fs.existsSync(config.actions.dist))) {
spinner.start('Building actions')
await RuntimeLib.buildActions(config, filterActions)
spinner.succeed(chalk.green('Building actions'))
try {
const script = await runPackageScript('build-actions')
if (!script) {
await RuntimeLib.buildActions(config, filterActions)
}
spinner.succeed(chalk.green('Building actions'))
} catch (err) {
spinner.fail(chalk.green('Building actions'))
throw err
}
} else {
spinner.info('no backend or a build already exists, skipping action build')
}
Expand All @@ -63,8 +71,16 @@ class Build extends BaseCommand {
await writeConfig(config.web.injectedConfig, urls)
}
spinner.start('Building web assets')
await webLib.buildWeb(config, onProgress)
spinner.succeed(chalk.green('Building web assets'))
try {
const script = await runPackageScript('build-static')
if (!script) {
await webLib.buildWeb(config, onProgress)
}
spinner.succeed(chalk.green('Building web assets'))
} catch (err) {
spinner.fail(chalk.green('Building web assets'))
throw err
}
} else {
spinner.info('no frontend or a build already exists, skipping frontend build')
}
Expand All @@ -77,7 +93,11 @@ class Build extends BaseCommand {

// final message
if (flags['skip-static']) {
this.log(chalk.green(chalk.bold('Build success, your actions are ready to be deployed 👌')))
if (flags['skip-actions']) {
this.log(chalk.green(chalk.bold('Nothing to build 🚫')))
} else {
this.log(chalk.green(chalk.bold('Build success, your actions are ready to be deployed 👌')))
}
} else {
this.log(chalk.green(chalk.bold('Build success, your app is ready to be deployed 👌')))
}
Expand Down
32 changes: 27 additions & 5 deletions src/commands/app/deploy.js
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ class Deploy extends BuildCommand {
} catch (err) {
this.log(err)
}

if (!flags['skip-actions']) {
if (config.app.hasBackend) {
let filterEntities
Expand All @@ -63,17 +64,34 @@ class Deploy extends BuildCommand {
// todo: fix this, the following change does not work, if we call rtLib version it chokes on some actions
// Error: EISDIR: illegal operation on a directory, read
spinner.start('Deploying actions')
deployedRuntimeEntities = { ...await rtLib.deployActions(config, { filterEntities }, onProgress) }
spinner.succeed(chalk.green('Deploying actions'))
try {
const script = await runPackageScript('deploy-actions')
if (!script) {
deployedRuntimeEntities = { ...await rtLib.deployActions(config, { filterEntities }, onProgress) }
}
spinner.succeed(chalk.green('Deploying actions'))
} catch (err) {
spinner.fail(chalk.green('Deploying actions'))
throw err
}
} else {
this.log('no backend, skipping action deploy')
}
}

if (!flags['skip-static']) {
if (config.app.hasFrontend) {
spinner.start('Deploying web assets')
deployedFrontendUrl = await webLib.deployWeb(config, onProgress)
spinner.succeed(chalk.green('Deploying web assets'))
try {
const script = await runPackageScript('deploy-static')
if (!script) {
deployedFrontendUrl = await webLib.deployWeb(config, onProgress)
}
spinner.succeed(chalk.green('Deploying web assets'))
} catch (err) {
spinner.fail(chalk.green('Deploying web assets'))
throw err
}
} else {
this.log('no frontend, skipping frontend deploy')
}
Expand Down Expand Up @@ -107,7 +125,11 @@ class Deploy extends BuildCommand {
// final message
if (!flags['skip-deploy']) {
if (flags['skip-static']) {
this.log(chalk.green(chalk.bold('Well done, your actions are now online 🏄')))
if (flags['skip-actions']) {
this.log(chalk.green(chalk.bold('Nothing to deploy 🚫')))
} else {
this.log(chalk.green(chalk.bold('Well done, your actions are now online 🏄')))
}
} else {
this.log(chalk.green(chalk.bold('Well done, your app is now online 🏄')))
}
Expand Down
104 changes: 100 additions & 4 deletions test/commands/app/build.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -175,10 +175,106 @@ describe('run', () => {
expect(mockWebLib.buildWeb).toHaveBeenCalledTimes(1)
})

test('error in runPackageScript', async () => {
helpers.runPackageScript.mockRejectedValue('error')
test('build (--skip-actions and --skip-static)', async () => {
const noScriptFound = undefined
helpers.runPackageScript
.mockResolvedValueOnce(noScriptFound) // pre-app-build
.mockResolvedValueOnce(noScriptFound) // post-app-build

command.argv = ['--skip-actions', '--skip-static']
await command.run()
expect(command.error).toHaveBeenCalledTimes(0)

expect(command.log).toHaveBeenCalledTimes(1)
expect(command.log).toHaveBeenCalledWith(expect.stringMatching(/Nothing to build/))
})

test('build (--skip-actions)', async () => {
const noScriptFound = undefined
helpers.runPackageScript
.mockResolvedValueOnce(noScriptFound) // pre-app-build
.mockResolvedValueOnce(noScriptFound) // post-app-build

command.argv = ['--skip-actions']
await command.run()
expect(command.error).toHaveBeenCalledTimes(0)

expect(command.log).toHaveBeenCalledTimes(1)
expect(command.log).toHaveBeenCalledWith(expect.stringMatching(/Build success, your app is ready to be deployed/))
})

test('build (--skip-static)', async () => {
const noScriptFound = undefined
helpers.runPackageScript
.mockResolvedValueOnce(noScriptFound) // pre-app-build
.mockResolvedValueOnce(noScriptFound) // post-app-build

command.argv = ['--skip-static']
await command.run()
expect(command.log).toHaveBeenNthCalledWith(1, 'error')
expect(command.log).toHaveBeenNthCalledWith(2, 'error')
expect(command.error).toHaveBeenCalledTimes(0)

expect(command.log).toHaveBeenCalledTimes(1)
expect(command.log).toHaveBeenCalledWith(expect.stringMatching(/Build success, your actions are ready to be deployed/))
})

test('build (has build-actions and build-static hooks)', async () => {
const noScriptFound = undefined
const childProcess = {}
helpers.runPackageScript
.mockResolvedValueOnce(noScriptFound) // pre-app-build
.mockResolvedValueOnce(childProcess) // build-actions (uses hook)
.mockResolvedValueOnce(childProcess) // build-static (uses hook)
.mockResolvedValueOnce(noScriptFound) // post-app-build

await command.run()
expect(command.error).toHaveBeenCalledTimes(0)

expect(command.log).toHaveBeenCalledTimes(1)
expect(command.log).toHaveBeenCalledWith(expect.stringMatching(/Build success, your app is ready to be deployed/))
})

test('build (pre and post hooks have errors, --skip-actions and --skip-static)', async () => {
helpers.runPackageScript
.mockRejectedValueOnce('error-pre-app-build') // pre-app-build (logs error)
.mockRejectedValueOnce('error-post-app-build') // post-app-build (logs error)

command.argv = ['--skip-actions', '--skip-static']
await command.run()
expect(command.error).toHaveBeenCalledTimes(0)

expect(command.log).toHaveBeenCalledTimes(3)
expect(command.log).toHaveBeenCalledWith('error-pre-app-build')
expect(command.log).toHaveBeenCalledWith('error-post-app-build')
expect(command.log).toHaveBeenCalledWith(expect.stringMatching(/Nothing to build/))
})

test('build (build-actions hook has an error)', async () => {
const noScriptFound = undefined
helpers.runPackageScript
.mockResolvedValueOnce(noScriptFound) // pre-app-build (no error)
.mockRejectedValueOnce('error-build-actions') // build-actions (rethrows error)
.mockResolvedValueOnce(noScriptFound) // build-static (will not reach here)
.mockResolvedValueOnce(noScriptFound) // post-app-build (will not reach here)

await command.run()
expect(command.error).toHaveBeenCalledTimes(1)
expect(command.error).toHaveBeenCalledWith('error-build-actions')

expect(command.log).toHaveBeenCalledTimes(0)
})

test('build (build-static hook has an error)', async () => {
const noScriptFound = undefined
helpers.runPackageScript
.mockResolvedValueOnce(noScriptFound) // pre-app-build (no error)
.mockResolvedValueOnce(noScriptFound) // build-actions (uses inbuilt, no error)
.mockRejectedValueOnce('error-build-static') // build-static (rethrows error)
.mockResolvedValueOnce(noScriptFound) // post-app-build (will not reach here)

await command.run()
expect(command.error).toHaveBeenCalledTimes(1)
expect(command.error).toHaveBeenCalledWith('error-build-static')

expect(command.log).toHaveBeenCalledTimes(0)
})
})
102 changes: 97 additions & 5 deletions test/commands/app/deploy.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -365,14 +365,106 @@ describe('run', () => {
expect(mockWebLib.deployWeb).toHaveBeenCalledTimes(1)
})

test('build & deploy (app hooks missing)', async () => {
test('deploy (--skip-actions and --skip-static)', async () => {
const noScriptFound = undefined
helpers.runPackageScript
.mockRejectedValueOnce('error-1')
.mockRejectedValueOnce('error-2')
.mockResolvedValueOnce(noScriptFound) // pre-app-deploy
.mockResolvedValueOnce(noScriptFound) // post-app-deploy

command.argv = ['--skip-actions', '--skip-static']
await command.run()
expect(command.error).toHaveBeenCalledTimes(0)
expect(command.log).toHaveBeenCalledWith('error-1')
expect(command.log).toHaveBeenCalledWith('error-2')

expect(command.log).toHaveBeenCalledTimes(1)
expect(command.log).toHaveBeenCalledWith(expect.stringMatching(/Nothing to deploy/))
})

test('deploy (--skip-actions)', async () => {
const noScriptFound = undefined
helpers.runPackageScript
.mockResolvedValueOnce(noScriptFound) // pre-app-deploy
.mockResolvedValueOnce(noScriptFound) // post-app-deploy

command.argv = ['--skip-actions']
await command.run()
expect(command.error).toHaveBeenCalledTimes(0)

expect(command.log).toHaveBeenCalledTimes(1)
expect(command.log).toHaveBeenCalledWith(expect.stringMatching(/Well done, your app is now online/))
})

test('deploy (--skip-static)', async () => {
const noScriptFound = undefined
helpers.runPackageScript
.mockResolvedValueOnce(noScriptFound) // pre-app-deploy
.mockResolvedValueOnce(noScriptFound) // post-app-deploy

command.argv = ['--skip-static']
await command.run()
expect(command.error).toHaveBeenCalledTimes(0)

expect(command.log).toHaveBeenCalledTimes(1)
expect(command.log).toHaveBeenCalledWith(expect.stringMatching(/Well done, your actions are now online/))
})

test('deploy (has deploy-actions and deploy-static hooks)', async () => {
const noScriptFound = undefined
const childProcess = {}
helpers.runPackageScript
.mockResolvedValueOnce(noScriptFound) // pre-app-deploy
.mockResolvedValueOnce(childProcess) // deploy-actions (uses hook)
.mockResolvedValueOnce(childProcess) // deploy-static (uses hook)
.mockResolvedValueOnce(noScriptFound) // post-app-deploy

await command.run()
expect(command.error).toHaveBeenCalledTimes(0)

expect(command.log).toHaveBeenCalledTimes(1)
expect(command.log).toHaveBeenCalledWith(expect.stringMatching(/Well done, your app is now online/))
})

test('deploy (pre and post hooks have errors, --skip-actions and --skip-static)', async () => {
helpers.runPackageScript
.mockRejectedValueOnce('error-pre-app-deploy') // pre-app-deploy (logs error)
.mockRejectedValueOnce('error-post-app-deploy') // post-app-deploy (logs error)

command.argv = ['--skip-actions', '--skip-static']
await command.run()
expect(command.error).toHaveBeenCalledTimes(0)

expect(command.log).toHaveBeenCalledTimes(3)
expect(command.log).toHaveBeenCalledWith('error-pre-app-deploy')
expect(command.log).toHaveBeenCalledWith('error-post-app-deploy')
expect(command.log).toHaveBeenCalledWith(expect.stringMatching(/Nothing to deploy/))
})

test('deploy (deploy-actions hook has an error)', async () => {
const noScriptFound = undefined
helpers.runPackageScript
.mockResolvedValueOnce(noScriptFound) // pre-app-deploy (no error)
.mockRejectedValueOnce('error-deploy-actions') // deploy-actions (rethrows error)
.mockResolvedValueOnce(noScriptFound) // deploy-static (will not reach here)
.mockResolvedValueOnce(noScriptFound) // post-app-deploy (will not reach here)

await command.run()
expect(command.error).toHaveBeenCalledTimes(1)
expect(command.error).toHaveBeenCalledWith('error-deploy-actions')

expect(command.log).toHaveBeenCalledTimes(0)
})

test('deploy (deploy-static hook has an error)', async () => {
const noScriptFound = undefined
helpers.runPackageScript
.mockResolvedValueOnce(noScriptFound) // pre-app-deploy (no error)
.mockResolvedValueOnce(noScriptFound) // deploy-actions (uses inbuilt, no error)
.mockRejectedValueOnce('error-deploy-static') // deploy-static (rethrows error)
.mockResolvedValueOnce(noScriptFound) // post-app-deploy (will not reach here)

await command.run()
expect(command.error).toHaveBeenCalledTimes(1)
expect(command.error).toHaveBeenCalledWith('error-deploy-static')

expect(command.log).toHaveBeenCalledTimes(0)
})
})
2 changes: 2 additions & 0 deletions test/jest.setup.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ governing permissions and limitations under the License.

const { stdout, stderr } = require('stdout-stderr')

jest.setTimeout(30000)

const fs = require.requireActual('fs')
const eol = require('eol')
const path = require('path')
Expand Down