From 2bf67ad8d7e0d31bcefe2c78e2488b7cd46aeadd Mon Sep 17 00:00:00 2001 From: Carter Wooten Date: Thu, 18 Apr 2019 19:19:39 -0400 Subject: [PATCH 1/3] Adding code to permit individual packaging --- deploy/lib/uploadArtifacts.js | 60 +++++++++++++++++++++++++++-------- package.json | 1 + package/googlePackage.js | 5 +++ 3 files changed, 53 insertions(+), 13 deletions(-) diff --git a/deploy/lib/uploadArtifacts.js b/deploy/lib/uploadArtifacts.js index 6141242..ec6de94 100644 --- a/deploy/lib/uploadArtifacts.js +++ b/deploy/lib/uploadArtifacts.js @@ -1,24 +1,58 @@ 'use strict'; const fs = require('fs'); +const _ = require('lodash'); +const BbPromise = require('bluebird'); +const path = require('path'); +const filesize = require('filesize'); module.exports = { uploadArtifacts() { this.serverless.cli.log('Uploading artifacts...'); - const params = { - bucket: this.serverless.service.provider.deploymentBucketName, - resource: { - name: this.serverless.service.package.artifactFilePath, - contentType: 'application/octet-stream', - }, - media: { - mimeType: 'application/octet-stream', - body: fs.createReadStream(this.serverless.service.package.artifact), - }, - }; - - return this.provider.request('storage', 'objects', 'insert', params) + const functionNames = this.serverless.service.getAllFunctions(); + const artifactFilePaths = _.uniq( + _.map(functionNames, (name) => { + const functionArtifactFileName = `${name}.zip`; + const functionObject = this.serverless.service.getFunction(name); + functionObject.package = functionObject.package || {}; + const artifactFilePath = functionObject.package.artifact || + this.serverless.service.package.artifact; + + if (!artifactFilePath || + (this.serverless.service.artifact && !functionObject.package.artifact)) { + if (this.serverless.service.package.individually || functionObject.package.individually) { + const artifactFileName = functionArtifactFileName; + return path.join(this.packagePath, artifactFileName); + } + return path.join(this.packagePath, this.provider.naming.getServiceArtifactName()); + } + + return artifactFilePath; + }), + ); + + return BbPromise.map(artifactFilePaths, (artifactFilePath) => { + const stats = fs.statSync(artifactFilePath); + const fileName = path.basename(artifactFilePath); + this.serverless.cli.log( + `Uploading service ${fileName} file to Google Cloud Storage (${filesize(stats.size)})...` + ); + + const params = { + bucket: this.serverless.service.provider.deploymentBucketName, + resource: { + name: `${this.serverless.service.package.artifactDirectoryName}/${path.basename(artifactFilePath)}`, + contentType: 'application/octet-stream', + }, + media: { + mimeType: 'application/octet-stream', + body: fs.createReadStream(artifactFilePath), + }, + }; + + return this.provider.request('storage', 'objects', 'insert', params); + }) .then(() => { this.serverless.cli.log('Artifacts successfully uploaded...'); }); diff --git a/package.json b/package.json index cf13ec0..ff3d555 100644 --- a/package.json +++ b/package.json @@ -28,6 +28,7 @@ "async": "^2.1.4", "bluebird": "^3.4.7", "chalk": "^1.1.3", + "filesize": "^4.1.2", "fs-extra": "^3.0.1", "googleapis": "^32.0.0", "lodash": "^4.17.4" diff --git a/package/googlePackage.js b/package/googlePackage.js index d1cc375..1b1fc5b 100644 --- a/package/googlePackage.js +++ b/package/googlePackage.js @@ -1,6 +1,7 @@ 'use strict'; const BbPromise = require('bluebird'); +const path = require('path'); const cleanupServerlessDir = require('./lib/cleanupServerlessDir'); const validate = require('../shared/validate'); @@ -17,6 +18,10 @@ class GooglePackage { constructor(serverless, options) { this.serverless = serverless; this.options = options; + this.servicePath = this.serverless.config.servicePath || ''; + this.packagePath = this.options.package || + this.serverless.service.package.path || + path.join(this.servicePath || '.', '.serverless'); this.provider = this.serverless.getProvider('google'); Object.assign( From 0f6e734c40ac13273c87ac92c2ae2cc11cef814e Mon Sep 17 00:00:00 2001 From: Carter Wooten Date: Thu, 18 Apr 2019 19:23:07 -0400 Subject: [PATCH 2/3] Update `compileFunctions` for individual packaging --- package/lib/compileFunctions.js | 145 +++++++++++++++++--------------- 1 file changed, 75 insertions(+), 70 deletions(-) diff --git a/package/lib/compileFunctions.js b/package/lib/compileFunctions.js index e667347..e027533 100644 --- a/package/lib/compileFunctions.js +++ b/package/lib/compileFunctions.js @@ -8,78 +8,83 @@ const _ = require('lodash'); const BbPromise = require('bluebird'); module.exports = { + compileFunction(functionName) { + const funcObject = this.serverless.service.getFunction(functionName); + + this.serverless.cli + .log(`Compiling function "${functionName}"...`); + + validateHandlerProperty(funcObject, functionName); + validateEventsProperty(funcObject, functionName); + + const funcTemplate = getFunctionTemplate( + funcObject, + this.serverless.service.provider.region, + `gs://${ + this.serverless.service.provider.deploymentBucketName + }/${this.serverless.service.package.artifactDirectoryName}/${functionName}.zip`); + + funcTemplate.properties.availableMemoryMb = _.get(funcObject, 'memorySize') + || _.get(this, 'serverless.service.provider.memorySize') + || 256; + funcTemplate.properties.location = _.get(funcObject, 'location') + || _.get(this, 'serverless.service.provider.region') + || 'us-central1'; + funcTemplate.properties.runtime = _.get(funcObject, 'runtime') + || _.get(this, 'serverless.service.provider.runtime') + || 'nodejs8'; + funcTemplate.properties.timeout = _.get(funcObject, 'timeout') + || _.get(this, 'serverless.service.provider.timeout') + || '60s'; + funcTemplate.properties.environmentVariables = _.merge( + _.get(this, 'serverless.service.provider.environment'), + funcObject.environment // eslint-disable-line comma-dangle + ); + + if (!_.size(funcTemplate.properties.environmentVariables)) { + delete funcTemplate.properties.environmentVariables; + } + + funcTemplate.properties.labels = _.assign({}, + _.get(this, 'serverless.service.provider.labels') || {}, + _.get(funcObject, 'labels') || {} // eslint-disable-line comma-dangle + ); + + const eventType = Object.keys(funcObject.events[0])[0]; + + if (eventType === 'http') { + const url = funcObject.events[0].http; + + funcTemplate.properties.httpsTrigger = {}; + funcTemplate.properties.httpsTrigger.url = url; + } + if (eventType === 'event') { + const type = funcObject.events[0].event.eventType; + const path = funcObject.events[0].event.path; //eslint-disable-line + const resource = funcObject.events[0].event.resource; + + funcTemplate.properties.eventTrigger = {}; + funcTemplate.properties.eventTrigger.eventType = type; + if (path) funcTemplate.properties.eventTrigger.path = path; + funcTemplate.properties.eventTrigger.resource = resource; + } + + this.serverless.service.provider.compiledConfigurationTemplate.resources.push(funcTemplate); + }, compileFunctions() { const artifactFilePath = this.serverless.service.package.artifact; - const fileName = artifactFilePath.split(path.sep).pop(); - - this.serverless.service.package - .artifactFilePath = `${this.serverless.service.package.artifactDirectoryName}/${fileName}`; - - this.serverless.service.getAllFunctions().forEach((functionName) => { - const funcObject = this.serverless.service.getFunction(functionName); - - this.serverless.cli - .log(`Compiling function "${functionName}"...`); - - validateHandlerProperty(funcObject, functionName); - validateEventsProperty(funcObject, functionName); - - const funcTemplate = getFunctionTemplate( - funcObject, - this.serverless.service.provider.region, - `gs://${ - this.serverless.service.provider.deploymentBucketName - }/${this.serverless.service.package.artifactFilePath}`); - - funcTemplate.properties.availableMemoryMb = _.get(funcObject, 'memorySize') - || _.get(this, 'serverless.service.provider.memorySize') - || 256; - funcTemplate.properties.location = _.get(funcObject, 'location') - || _.get(this, 'serverless.service.provider.region') - || 'us-central1'; - funcTemplate.properties.runtime = _.get(funcObject, 'runtime') - || _.get(this, 'serverless.service.provider.runtime') - || 'nodejs8'; - funcTemplate.properties.timeout = _.get(funcObject, 'timeout') - || _.get(this, 'serverless.service.provider.timeout') - || '60s'; - funcTemplate.properties.environmentVariables = _.merge( - _.get(this, 'serverless.service.provider.environment'), - funcObject.environment // eslint-disable-line comma-dangle - ); - - if (!_.size(funcTemplate.properties.environmentVariables)) { - delete funcTemplate.properties.environmentVariables; - } - - funcTemplate.properties.labels = _.assign({}, - _.get(this, 'serverless.service.provider.labels') || {}, - _.get(funcObject, 'labels') || {} // eslint-disable-line comma-dangle - ); - - const eventType = Object.keys(funcObject.events[0])[0]; - - if (eventType === 'http') { - const url = funcObject.events[0].http; - - funcTemplate.properties.httpsTrigger = {}; - funcTemplate.properties.httpsTrigger.url = url; - } - if (eventType === 'event') { - const type = funcObject.events[0].event.eventType; - const path = funcObject.events[0].event.path; //eslint-disable-line - const resource = funcObject.events[0].event.resource; - - funcTemplate.properties.eventTrigger = {}; - funcTemplate.properties.eventTrigger.eventType = type; - if (path) funcTemplate.properties.eventTrigger.path = path; - funcTemplate.properties.eventTrigger.resource = resource; - } - - this.serverless.service.provider.compiledConfigurationTemplate.resources.push(funcTemplate); - }); - - return BbPromise.resolve(); + if (artifactFilePath) { + const fileName = artifactFilePath.split(path.sep).pop(); + + this.serverless.service.package + .artifactFilePath = `${this.serverless.service.package.artifactDirectoryName}/${fileName}`; + } + + const allFunctions = this.serverless.service.getAllFunctions(); + return BbPromise.each( + allFunctions, + functionName => this.compileFunction(functionName) + ); }, }; From 50701e266e3508b865e31aa7f67b64bb69a5d8e1 Mon Sep 17 00:00:00 2001 From: Carter Wooten Date: Thu, 18 Apr 2019 19:43:30 -0400 Subject: [PATCH 3/3] Fixes after testing without individual packaging --- deploy/googleDeploy.js | 5 +++++ deploy/lib/uploadArtifacts.js | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/deploy/googleDeploy.js b/deploy/googleDeploy.js index dfe845e..7a69471 100644 --- a/deploy/googleDeploy.js +++ b/deploy/googleDeploy.js @@ -1,6 +1,7 @@ 'use strict'; const BbPromise = require('bluebird'); +const path = require('path'); const validate = require('../shared/validate'); const utils = require('../shared/utils'); @@ -15,6 +16,10 @@ class GoogleDeploy { constructor(serverless, options) { this.serverless = serverless; this.options = options; + this.servicePath = this.serverless.config.servicePath || ''; + this.packagePath = this.options.package || + this.serverless.service.package.path || + path.join(this.servicePath || '.', '.serverless'); this.provider = this.serverless.getProvider('google'); Object.assign( diff --git a/deploy/lib/uploadArtifacts.js b/deploy/lib/uploadArtifacts.js index ec6de94..87a5d05 100644 --- a/deploy/lib/uploadArtifacts.js +++ b/deploy/lib/uploadArtifacts.js @@ -25,7 +25,7 @@ module.exports = { const artifactFileName = functionArtifactFileName; return path.join(this.packagePath, artifactFileName); } - return path.join(this.packagePath, this.provider.naming.getServiceArtifactName()); + return path.join(this.packagePath, `${this.provider.serverless.service.service}.zip`); } return artifactFilePath;