diff --git a/package/lib/compileFunctions.js b/package/lib/compileFunctions.js index b318d47..55e43d9 100644 --- a/package/lib/compileFunctions.js +++ b/package/lib/compileFunctions.js @@ -47,10 +47,9 @@ module.exports = { '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 + funcTemplate.properties.environmentVariables = _.mapValues( + _.merge({}, _.get(this, 'serverless.service.provider.environment'), funcObject.environment), + (value, key, result) => coerceEnvOrError(result, key, value) ); funcTemplate.accessControl.gcpIamPolicy.bindings = _.unionBy( _.get(funcObject, 'iam.bindings'), @@ -198,6 +197,19 @@ const validateIamProperty = (funcObject, functionName) => { } }; +const coerceEnvOrError = (result, key, value) => { + if (typeof value === 'string') { + return value; + } else if (typeof value === 'number') { + return value.toString(); + } + const errorMessage = [ + `The value for environment variable ${key} is an unsupported type: ${typeof value}.`, + ' Values must either be strings or numbers (which are coerced into strings at package time).', + ].join(''); + throw new Error(errorMessage); +}; + const getFunctionTemplate = (funcObject, projectName, region, sourceArchiveUrl) => { //eslint-disable-line return { diff --git a/package/lib/compileFunctions.test.js b/package/lib/compileFunctions.test.js index a4c764d..78cb02b 100644 --- a/package/lib/compileFunctions.test.js +++ b/package/lib/compileFunctions.test.js @@ -370,12 +370,72 @@ describe('CompileFunctions', () => { }); }); + it('should fail setting environment variable due to unsupported type (bool)', () => { + googlePackage.serverless.service.functions = { + func1: { + handler: 'func1', + environment: { + TEST_VAR: true, + }, + events: [{ http: 'foo' }], + }, + }; + + expect(() => googlePackage.compileFunctions()).toThrow(Error); + }); + + it('should fail setting environment variable due to unsupported type (null)', () => { + googlePackage.serverless.service.functions = { + func1: { + handler: 'func1', + environment: { + TEST_VAR: null, + }, + events: [{ http: 'foo' }], + }, + }; + + expect(() => googlePackage.compileFunctions()).toThrow(Error); + }); + + it('should fail setting environment variable due to unsupported type (object)', () => { + googlePackage.serverless.service.functions = { + func1: { + handler: 'func1', + environment: { + dev: { + TEST_VAR: 'test', + }, + }, + events: [{ http: 'foo' }], + }, + }; + + expect(() => googlePackage.compileFunctions()).toThrow(Error); + }); + + it('should fail setting environment variable from provider due to unsupported type (bool)', () => { + googlePackage.serverless.service.functions = { + func1: { + handler: 'func1', + events: [{ http: 'foo' }], + }, + }; + googlePackage.serverless.service.provider.environment = { + TEST_VAR: true, + }; + + expect(() => googlePackage.compileFunctions()).toThrow(Error); + }); + it('should set the environment variables based on the function configuration', () => { googlePackage.serverless.service.functions = { func1: { handler: 'func1', environment: { TEST_VAR: 'test', + INT_VAR: 1, + FLOAT_VAR: 3.141, }, events: [{ http: 'foo' }], }, @@ -393,6 +453,8 @@ describe('CompileFunctions', () => { availableMemoryMb: 256, environmentVariables: { TEST_VAR: 'test', + INT_VAR: '1', + FLOAT_VAR: '3.141', }, timeout: '60s', sourceArchiveUrl: 'gs://sls-my-service-dev-12345678/some-path/artifact.zip', @@ -421,6 +483,8 @@ describe('CompileFunctions', () => { }; googlePackage.serverless.service.provider.environment = { TEST_VAR: 'test', + INT_VAR: 1, + FLOAT_VAR: 3.141, }; const compiledResources = [ @@ -435,6 +499,8 @@ describe('CompileFunctions', () => { availableMemoryMb: 256, environmentVariables: { TEST_VAR: 'test', + INT_VAR: '1', + FLOAT_VAR: '3.141', }, timeout: '60s', sourceArchiveUrl: 'gs://sls-my-service-dev-12345678/some-path/artifact.zip',