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

Replace netlify's zip-it-and-ship-it for serverless deploy #3782

Merged
Show file tree
Hide file tree
Changes from 1 commit
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
63 changes: 63 additions & 0 deletions packages/cli/src/commands/deploy/aws-providers/packing.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import path from 'path'
Copy link
Contributor Author

@Irev-Dev Irev-Dev Nov 27, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is packages/cli/src/commands/deploy/aws-providers/packing.js a good home? not sure where this file should live.

Or should these functions be rolled into packages/cli/src/commands/deploy/aws-providers/serverless.js?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My preference: move packing to a separate folder and called in "packaging/nft.js"

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Now in packages/cli/src/commands/deploy/packing/nft.js.

Is that what you intended, or did you want it in packages/cli/src/commands/deploy/aws-providers/packing/nft.js or other?


import { nodeFileTrace } from '@vercel/nft'
import archiver from 'archiver'
import fse from 'fs-extra'

const ZIPBALL_DIR = './api/dist/zipball'

function zipDirectory(source, out) {
const archive = archiver('zip', { zlib: { level: 5 } })
const stream = fse.createWriteStream(out)

return new Promise((resolve, reject) => {
archive
.directory(source, false)
.on('error', (err) => reject(err))
.pipe(stream)

stream.on('close', () => resolve())
archive.finalize()
})
}

const packageSingleFunction = async (functionFile) => {
const { name: functionName } = path.parse(functionFile)
const { fileList: functionDependencyFileList } = await nodeFileTrace([
functionFile,
])
const copyPromises = []
for (const singleDependencyPath of functionDependencyFileList) {
copyPromises.push(
fse.copy(
'./' + singleDependencyPath,
`${ZIPBALL_DIR}/${functionName}/${singleDependencyPath}`
)
)
}
const functionEntryPromise = fse.outputFile(
`${ZIPBALL_DIR}/${functionName}/${functionName}.js`,
`module.exports = require('${functionFile}')`
)
copyPromises.push(functionEntryPromise)

await Promise.all(copyPromises)
await zipDirectory(
`${ZIPBALL_DIR}/${functionName}`,
`${ZIPBALL_DIR}/${functionName}.zip`
)
await fse.remove(`${ZIPBALL_DIR}/${functionName}`)
return
}

export const pack = async () => {
console.log('starting pack')
const startTime = new Date().valueOf()
const filesToBePacked = (await fse.readdir('./api/dist/functions'))
.filter((path) => path.endsWith('.js'))
.map((path) => `./api/dist/functions/${path}`)
await Promise.all(filesToBePacked.map(packageSingleFunction))
console.log(
`Packed in ${Math.round((new Date().valueOf() - startTime) / 1000)}s`
)
}
15 changes: 0 additions & 15 deletions packages/cli/src/commands/deploy/aws-providers/serverless.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,25 +7,10 @@ export const preRequisites = [
'Please follow the steps at https://www.serverless.com/framework/docs/providers/aws/guide/installation/ to install Serverless.',
],
},
{
title: 'Checking if @netlify/zip-it-and-ship-it is installed...',
command: ['yarn', ['zip-it-and-ship-it', '--version']],
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The new deps that have been added are @vercel/nft, archiver and fs-extra. They are not cli tools so can't use --version as a test, is there an easy way to check deps?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure it is easy, but in the past to verify dependencies like this are there, I have loaded package.json in code and inspected the JSON object to verify that there is the expected key/value under dependencies/devDependencies

errorMessage: [
'Looks like @netlify/zip-it-and-ship-it is not installed.',
'Either run `yarn rw setup aws-serverless` or add it separately as a dev dependency in the api workspace.',
],
},
]

export const buildCommands = [
{ title: 'Building API...', command: ['yarn', ['rw', 'build', 'api']] },
{
title: 'Packaging API...',
command: [
'yarn',
['zip-it-and-ship-it', 'api/dist/functions/', 'api/dist/zipball'],
],
},
]

export const deployCommand = {
Expand Down
38 changes: 29 additions & 9 deletions packages/cli/src/commands/deploy/aws.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,14 @@ import path from 'path'

import execa from 'execa'
import Listr from 'listr'
import VerboseRenderer from 'listr-verbose-renderer'
import terminalLink from 'terminal-link'

import { getPaths } from '../../lib'
import c from '../../lib/colors'

import { pack } from './aws-providers/packing'

export const command = 'aws [provider]'
export const description = 'Deploy to AWS using the selected provider'
export const builder = (yargs) => {
Expand All @@ -29,6 +32,17 @@ export const builder = (yargs) => {
default: 'api',
type: 'array',
})
.option('verbose', {
describe: 'verbosity of logs',
default: true,
type: 'boolean',
})
.option('stage', {
describe:
'serverless stage pass through param: https://www.serverless.com/blog/stages-and-environments',
default: 'dev',
type: 'string',
})
.epilogue(
`Also see the ${terminalLink(
'Redwood CLI Reference',
Expand All @@ -37,7 +51,7 @@ export const builder = (yargs) => {
)
}

export const handler = async ({ provider }) => {
export const handler = async ({ provider, verbose, stage }) => {
const BASE_DIR = getPaths().base
const providerData = await import(`./aws-providers/${provider}`)

Expand Down Expand Up @@ -68,28 +82,34 @@ export const handler = async ({ provider }) => {
title: 'Building and Packaging...',
task: () =>
new Listr(
providerData.buildCommands.map((commandDetail) => {
return {
title: commandDetail.title,
[
{
title: providerData.buildCommands[0].title,
task: async () => {
await execa(...commandDetail.command, {
await execa(...providerData.buildCommands[0].command, {
cwd: BASE_DIR,
})
},
}
}),
},
{
title: 'packing',
task: pack,
},
],
{ collapse: false }
),
},
].filter(Boolean),
{ collapse: false }
{ collapse: false, renderer: verbose && VerboseRenderer }
)

try {
await tasks.run()

console.log(c.green(providerData.deployCommand.title))
const deploy = execa(...providerData.deployCommand.command, {
const deployCommand = [...providerData.deployCommand.command]
deployCommand[1] = [...deployCommand[1], '--stage', stage]
const deploy = execa(...deployCommand, {
cwd: BASE_DIR,
})
deploy.stdout.pipe(process.stdout)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,9 @@ export const preRequisites = [
]

export const apiDevPackages = [
'@netlify/zip-it-and-ship-it',
'@vercel/nft',
'archiver',
'fs-extra',
'serverless-dotenv-plugin',
]

Expand Down