Repository: serverless-heaven/serverless-webpack
Pull request #794 (2021-04-22 19:08:03)

fix: Correctly handle packaging for function during `deploy -f`
<!--
1. Do not remove any section of the template. If something is not applicable leave it empty but leave it in the PR
2. Please follow the template, otherwise we'll have to ask you to update it and it will take longer until your PR is merged
-->

## What did you implement:

Correct behavior of `copyExistingArtifacts` when it's invoked as a part of `deploy function` command. 

Closes: https://github.com/serverless-heaven/serverless-webpack/issues/737

## How did you implement it:

I used a similar approach to one taken in a few different places when `function` is available in `options`

<!--
If this is a nontrivial change please briefly describe your implementation so its easy for us to understand and review your code.
-->

## How can we verify it:

Setup a project that has at least two functions and `package.individually: true`. Deploy the stack and then try to deploy a single function with `deploy function` command. Previously it was failing when it tried to copy an artifact for other functions that the one specified with `deploy function` command.

<!--
Add any applicable config, commands, screenshots or other resources
to make it easy for us to verify this works. The easier you make it for us
to review a PR, the faster we can review and merge it.

Examples:
* Step by step description, how to verify
* Screenshots - Showing the difference between your output and the master
* Other - Anything else that comes to mind to help us evaluate
-->

## Todos:

- [x] Write tests
- [x] Write documentation
- [x] Fix linting errors
- [x] Make sure code coverage hasn't dropped
- [x] Provide verification config / commands / resources
- [x] Enable "Allow edits from maintainers" for this PR
- [x] Update the messages below

***Is this ready for review?:*** YES
***Is it a breaking change?:*** NO



Patch:
diff --git a/lib/packageModules.js b/lib/packageModules.js
index 31c3238..0aec043 100644
--- a/lib/packageModules.js
+++ b/lib/packageModules.js
@@ -133,18 +133,20 @@ module.exports = {
 
   copyExistingArtifacts() {
     this.serverless.cli.log('Copying existing artifacts...');
-    const allFunctionNames = this.serverless.service.getAllFunctions();
+    // When invoked as a part of `deploy function`,
+    // only function passed with `-f` flag should be processed.
+    const functionNames = this.options.function ? [this.options.function] : this.serverless.service.getAllFunctions();
 
     // Copy artifacts to package location
     if (isIndividialPackaging.call(this)) {
-      _.forEach(allFunctionNames, funcName => copyArtifactByName.call(this, funcName));
+      _.forEach(functionNames, funcName => copyArtifactByName.call(this, funcName));
     } else {
       // Copy service packaged artifact
       const serviceName = this.serverless.service.getServiceObject().name;
       copyArtifactByName.call(this, serviceName);
     }
 
-    _.forEach(allFunctionNames, funcName => {
+    _.forEach(functionNames, funcName => {
       const func = this.serverless.service.getFunction(funcName);
 
       const archiveName = isIndividialPackaging.call(this) ? funcName : this.serverless.service.getServiceObject().name;
@@ -155,7 +157,7 @@ module.exports = {
 
     // Set artifact locations
     if (isIndividialPackaging.call(this)) {
-      _.forEach(allFunctionNames, funcName => {
+      _.forEach(functionNames, funcName => {
         const func = this.serverless.service.getFunction(funcName);
 
         const archiveName = funcName;


Test patch:
diff --git a/tests/packageModules.test.js b/tests/packageModules.test.js
index c64a697..c7904a4 100644
--- a/tests/packageModules.test.js
+++ b/tests/packageModules.test.js
@@ -679,6 +679,22 @@ describe('packageModules', () => {
           ])
         );
       });
+
+      it('copies only the artifact for function specified in options', () => {
+        _.set(module, 'options.function', 'func1');
+        const expectedFunc1Destination = path.join('.serverless', 'func1.zip');
+
+        return expect(module.copyExistingArtifacts()).to.be.fulfilled.then(() =>
+          BbPromise.all([
+            // Should copy an artifact per function into .serverless
+            expect(fsMock.copyFileSync).callCount(1),
+            expect(fsMock.copyFileSync).to.be.calledWith(path.join('.webpack', 'func1.zip'), expectedFunc1Destination),
+
+            // Should set package artifact locations
+            expect(func1).to.have.a.nested.property('package.artifact').that.equals(expectedFunc1Destination)
+          ])
+        );
+      });
     });
   });
 });