diff --git a/lib/plugins/aws/deploy/lib/extendedValidate.js b/lib/plugins/aws/deploy/lib/extendedValidate.js index 965d91b31..0c670d128 100644 --- a/lib/plugins/aws/deploy/lib/extendedValidate.js +++ b/lib/plugins/aws/deploy/lib/extendedValidate.js @@ -50,8 +50,14 @@ module.exports = { }); } else if (!_.isEmpty(this.serverless.service.functions)) { // artifact file validation (single service artifact) - const artifactFileName = this.provider.naming.getServiceArtifactName(); - const artifactFilePath = path.join(this.packagePath, artifactFileName); + let artifactFilePath; + let artifactFileName; + if (this.serverless.service.package.artifact) { + artifactFileName = artifactFilePath = this.serverless.service.package.artifact; + } else { + artifactFileName = this.provider.naming.getServiceArtifactName(); + artifactFilePath = path.join(this.packagePath, artifactFileName); + } if (!this.serverless.utils.fileExistsSync(artifactFilePath)) { throw new this.serverless.classes .Error(`No ${artifactFileName} file found in the package path you provided.`); diff --git a/lib/plugins/aws/deploy/lib/extendedValidate.test.js b/lib/plugins/aws/deploy/lib/extendedValidate.test.js index f25325995..5e0d010b1 100644 --- a/lib/plugins/aws/deploy/lib/extendedValidate.test.js +++ b/lib/plugins/aws/deploy/lib/extendedValidate.test.js @@ -127,5 +127,26 @@ describe('extendedValidate', () => { expect(fileExistsSyncStub).to.have.been.calledWithExactly('artifact.zip'); }); }); + + it('should throw error if specified package artifact does not exist', () => { + // const fileExistsSyncStub = sinon.stub(awsDeploy.serverless.utils, 'fileExistsSync'); + fileExistsSyncStub.onCall(0).returns(true); + fileExistsSyncStub.onCall(1).returns(false); + readFileSyncStub.returns(stateFileMock); + awsDeploy.serverless.service.package.artifact = 'some/file.zip'; + expect(() => awsDeploy.extendedValidate()).to.throw(Error); + delete awsDeploy.serverless.service.package.artifact; + }); + + it('should not throw error if specified package artifact exists', () => { + // const fileExistsSyncStub = sinon.stub(awsDeploy.serverless.utils, 'fileExistsSync'); + fileExistsSyncStub.onCall(0).returns(true); + fileExistsSyncStub.onCall(1).returns(true); + readFileSyncStub.returns(stateFileMock); + awsDeploy.serverless.service.package.artifact = 'some/file.zip'; + return awsDeploy.extendedValidate().then(() => { + delete awsDeploy.serverless.service.package.artifact; + }); + }); }); }); diff --git a/lib/plugins/package/lib/packageService.js b/lib/plugins/package/lib/packageService.js index f90795fa4..b232eaf19 100644 --- a/lib/plugins/package/lib/packageService.js +++ b/lib/plugins/package/lib/packageService.js @@ -39,6 +39,9 @@ module.exports = { this.serverless.cli.log(`Packaging disabled for function: "${functionName}"`); return BbPromise.resolve(); } + if (functionObject.package.artifact) { + return BbPromise.resolve(); + } if (functionObject.package.individually || this.serverless.service .package.individually) { return this.packageFunction(functionName); @@ -48,7 +51,7 @@ module.exports = { }); return BbPromise.all(packagePromises).then(() => { - if (shouldPackageService) { + if (shouldPackageService && !this.serverless.service.package.artifact) { return this.packageAll(); } return BbPromise.resolve(); diff --git a/lib/plugins/package/lib/packageService.test.js b/lib/plugins/package/lib/packageService.test.js index 46a308c41..f3da7f193 100644 --- a/lib/plugins/package/lib/packageService.test.js +++ b/lib/plugins/package/lib/packageService.test.js @@ -161,13 +161,24 @@ describe('#packageService()', () => { )); }); - it('should not package service with only disabled functions', () => { + it('should not package functions if package artifact specified', () => { + serverless.service.package.artifact = 'some/file.zip'; + + const packageAllStub = sinon.stub(packagePlugin, 'packageAll').resolves(); + + return expect(packagePlugin.packageService()).to.be.fulfilled + .then(() => expect(packageAllStub).to.not.be.called); + }); + + it('should package functions individually if package artifact specified', () => { + serverless.service.package.artifact = 'some/file.zip'; + serverless.service.package.individually = true; serverless.service.functions = { 'test-one': { name: 'test-one', - package: { - disable: true, - }, + }, + 'test-two': { + name: 'test-two', }, }; @@ -178,10 +189,36 @@ describe('#packageService()', () => { return expect(packagePlugin.packageService()).to.be.fulfilled .then(() => BbPromise.join( - expect(packageFunctionStub).to.not.be.calledOnce, - expect(packageAllStub).to.not.be.calledOnce + expect(packageFunctionStub).to.be.calledTwice, + expect(packageAllStub).to.not.be.called )); }); + + it('should package single functions individually if package artifact specified', () => { + serverless.service.package.artifact = 'some/file.zip'; + serverless.service.functions = { + 'test-one': { + name: 'test-one', + package: { + individually: true, + }, + }, + 'test-two': { + name: 'test-two', + }, + }; + + const packageFunctionStub = sinon + .stub(packagePlugin, 'packageFunction').resolves((func) => func.name); + const packageAllStub = sinon + .stub(packagePlugin, 'packageAll').resolves((func) => func.name); + + return expect(packagePlugin.packageService()).to.be.fulfilled + .then(() => BbPromise.join( + expect(packageFunctionStub).to.be.calledOnce, + expect(packageAllStub).to.not.be.called + )); + }); }); describe('#packageAll()', () => {