From bcbbd47fa09b7d99d7f8da3f11150215d1203bba Mon Sep 17 00:00:00 2001 From: Robert Bragg Date: Thu, 7 Jan 2021 12:53:00 +0000 Subject: [PATCH] fix(Packaging): Consider absolute artifact paths (#8325) (#8315) Co-authored-by: Piotr Grzesik --- lib/plugins/package/lib/packageService.js | 5 +- .../package/lib/packageService.test.js | 161 +++++++++++++++++- 2 files changed, 159 insertions(+), 7 deletions(-) diff --git a/lib/plugins/package/lib/packageService.js b/lib/plugins/package/lib/packageService.js index dfe40f473..cf223aa4a 100644 --- a/lib/plugins/package/lib/packageService.js +++ b/lib/plugins/package/lib/packageService.js @@ -120,7 +120,7 @@ module.exports = { // use the artifact in function config if provided if (funcPackageConfig.artifact) { - const filePath = path.join(this.serverless.config.servicePath, funcPackageConfig.artifact); + const filePath = path.resolve(this.serverless.config.servicePath, funcPackageConfig.artifact); functionObject.package.artifact = filePath; return filePath; } @@ -128,11 +128,12 @@ module.exports = { // use the artifact in service config if provided // and if the function is not set to be packaged individually if (this.serverless.service.package.artifact && !funcPackageConfig.individually) { - const filePath = path.join( + const filePath = path.resolve( this.serverless.config.servicePath, this.serverless.service.package.artifact ); funcPackageConfig.artifact = filePath; + return filePath; } diff --git a/test/unit/lib/plugins/package/lib/packageService.test.js b/test/unit/lib/plugins/package/lib/packageService.test.js index de402681f..9edc1e874 100644 --- a/test/unit/lib/plugins/package/lib/packageService.test.js +++ b/test/unit/lib/plugins/package/lib/packageService.test.js @@ -3,6 +3,7 @@ const _ = require('lodash'); const BbPromise = require('bluebird'); const path = require('path'); +const fs = require('fs'); const fse = require('fs-extra'); const chai = require('chai'); const sinon = require('sinon'); @@ -11,6 +12,7 @@ const Serverless = require('../../../../../../lib/Serverless'); const serverlessConfigFileUtils = require('../../../../../../lib/utils/getServerlessConfigFile'); const { createTmpDir, listZipFiles } = require('../../../../../utils/fs'); const runServerless = require('../../../../../utils/run-serverless'); +const fixtures = require('../../../../../fixtures'); // Configure chai chai.use(require('chai-as-promised')); @@ -593,11 +595,12 @@ describe('lib/plugins/package/lib/packageService.test.js', () => { }); }); - describe.skip('TODO: pre-prepared artifact', () => { + describe('pre-prepared artifact', () => { before(async () => { await runServerless({ fixture: 'packaging', cliArgs: ['package'], + awsRequestStubMap: mockedDescribeStacksResponse, configExt: { package: { artifact: 'artifact.zip', @@ -611,28 +614,176 @@ describe('lib/plugins/package/lib/packageService.test.js', () => { }, fnArtifact: { handler: 'index.handler', - artifact: 'artifact-function.zip', + package: { + artifact: 'artifact-function.zip', + }, }, }, }, }); }); - it('should support `package.artifact`', () => { + + it.skip('TODO: should support `package.artifact`', () => { // Confirm that file pointed at `package.artifact` is configured as service level artifact // // Replace // https://github.com/serverless/serverless/blob/b12d565ea0ad588445fb120e049db157afc7bf37/test/unit/lib/plugins/package/lib/packageService.test.js#L227-L235 }); - it('should ignore `package.artifact` if `functions[].package.individually', () => { + it.skip('TODO: should ignore `package.artifact` if `functions[].package.individually', () => { // Confirm that fnIndividual was packaged independently // // Replace // https://github.com/serverless/serverless/blob/b12d565ea0ad588445fb120e049db157afc7bf37/test/unit/lib/plugins/package/lib/packageService.test.js#L262-L287 }); - it('should support `functions[].package.artifact`', () => { + it.skip('TODO: should support `functions[].package.artifact`', () => { // Confirm that file pointed at `functions.fnArtifact.package.artifact` is configured as function level artifact }); + + describe('with absolute artifact path', () => { + let absoluteArtifactFilePath; + let zipContent; + let servicePath; + let updateConfig; + + before(async () => { + ({ servicePath, updateConfig } = await fixtures.setup('packageArtifact')); + absoluteArtifactFilePath = path.join(servicePath, 'newArtifact.zip'); + await fs.promises.copyFile( + path.join(servicePath, 'artifact.zip'), + absoluteArtifactFilePath + ); + zipContent = await fs.promises.readFile(absoluteArtifactFilePath); + }); + + describe('while deploying whole service', () => { + const s3UploadStub = sinon.stub(); + const awsRequestStubMap = { + Lambda: { + getFunction: { + Configuration: { + LastModified: '2020-05-20T15:34:16.494+0000', + }, + }, + }, + S3: { + upload: s3UploadStub, + listObjectsV2: {}, + }, + CloudFormation: { + describeStacks: {}, + describeStackResource: { StackResourceDetail: { PhysicalResourceId: 'resource-id' } }, + }, + STS: { + getCallerIdentity: { + ResponseMetadata: { RequestId: 'ffffffff-ffff-ffff-ffff-ffffffffffff' }, + UserId: 'XXXXXXXXXXXXXXXXXXXXX', + Account: '999999999999', + Arn: 'arn:aws:iam::999999999999:user/test', + }, + }, + }; + + beforeEach(() => { + s3UploadStub.resetHistory(); + }); + + it('for function', async () => { + await updateConfig({ + functions: { + other: { + package: { + artifact: absoluteArtifactFilePath, + }, + }, + }, + }); + await runServerless({ + cwd: servicePath, + cliArgs: ['deploy'], + lastLifecycleHookName: 'aws:deploy:deploy:uploadArtifacts', + awsRequestStubMap, + }); + + const callArgs = s3UploadStub.args.find((item) => + item[0].Key.endsWith('newArtifact.zip') + ); + expect(callArgs[0].Body.path).to.equal(absoluteArtifactFilePath); + }); + + it('service-wide', async () => { + await updateConfig({ + package: { + artifact: absoluteArtifactFilePath, + }, + }); + await runServerless({ + cwd: servicePath, + cliArgs: ['deploy'], + lastLifecycleHookName: 'aws:deploy:deploy:uploadArtifacts', + awsRequestStubMap, + }); + + const callArgs = s3UploadStub.args.find((item) => + item[0].Key.endsWith('newArtifact.zip') + ); + expect(callArgs[0].Body.path).to.equal(absoluteArtifactFilePath); + }); + }); + + describe('while deploying specific function', () => { + const updateFunctionCodeStub = sinon.stub(); + const awsRequestStubMap = { + Lambda: { + getFunction: { + Configuration: { + LastModified: '2020-05-20T15:34:16.494+0000', + }, + }, + updateFunctionCode: updateFunctionCodeStub, + updateFunctionConfiguration: {}, + }, + }; + + beforeEach(() => { + updateFunctionCodeStub.resetHistory(); + }); + + it('for function', async () => { + await updateConfig({ + functions: { + other: { + package: { + artifact: absoluteArtifactFilePath, + }, + }, + }, + }); + await runServerless({ + cwd: servicePath, + cliArgs: ['deploy', '-f', 'other'], + awsRequestStubMap, + }); + expect(updateFunctionCodeStub).to.have.been.calledOnce; + expect(updateFunctionCodeStub.args[0][0].ZipFile).to.deep.equal(Buffer.from(zipContent)); + }); + + it('service-wide', async () => { + await updateConfig({ + package: { + artifact: absoluteArtifactFilePath, + }, + }); + await runServerless({ + cwd: servicePath, + cliArgs: ['deploy', '-f', 'foo'], + awsRequestStubMap, + }); + expect(updateFunctionCodeStub).to.have.been.calledOnce; + expect(updateFunctionCodeStub.args[0][0].ZipFile).to.deep.equal(Buffer.from(zipContent)); + }); + }); + }); }); });