Repository: intuit/auto
Pull request #683 (2019-11-13 00:19:58)

Fix bug where 'all-contributors' plugin wasn't picking up changes
# What Changed

Get all the files changes for a merge commit. Help find contributions for `all-contributors` plugin to work off.

# Why

Merge commits don't actually contain the files that were changed.

Todo:

- [x] Add tests

<!-- GITHUB_RELEASE PR BODY: canary-version -->
Published PR with canary version: `7.13.4-canary.683.8949.0`
<!-- GITHUB_RELEASE PR BODY: canary-version -->



Patch:
diff --git a/.all-contributorsrc b/.all-contributorsrc
index 8a0ff01f..a730892b 100644
--- a/.all-contributorsrc
+++ b/.all-contributorsrc
@@ -126,6 +126,15 @@
       "contributions": [
         "code"
       ]
+    },
+    {
+      "login": "karenclo",
+      "name": "Karen Lo",
+      "avatar_url": "https://avatars1.githubusercontent.com/u/8535239?v=4",
+      "profile": "https://github.com/karenclo",
+      "contributions": [
+        "doc"
+      ]
     }
   ],
   "commitConvention": "none"
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 221d5f8b..58c0aab5 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,22 +1,3 @@
-# v7.14.0 (Tue Nov 12 2019)
-
-#### 🚀  Enhancement
-
-- `@auto-it/core`
-  - detect PR number when running  "auto label" without "--pr" [#682](https://github.com/intuit/auto/pull/682) ([@hipstersmoothie](https://github.com/hipstersmoothie))
-
-#### 📝  Documentation
-
-- `auto`
-  - Rewrite README Issue #666 [#680](https://github.com/intuit/auto/pull/680) ([@karenclo](https://github.com/karenclo) [@hipstersmoothie](https://github.com/hipstersmoothie))
-
-#### Authors: 2
-
-- Andrew Lisowski ([@hipstersmoothie](https://github.com/hipstersmoothie))
-- Karen Lo ([@karenclo](https://github.com/karenclo))
-
----
-
 # v7.13.3 (Tue Nov 12 2019)
 
 #### 🐛  Bug Fix
diff --git a/README.md b/README.md
index 26df58e3..1447edf1 100644
--- a/README.md
+++ b/README.md
@@ -182,6 +182,7 @@ Thanks goes to these wonderful people ([emoji key](https://github.com/kentcdodds
     <td align="center"><a href="https://github.com/su7edja"><img src="https://avatars0.githubusercontent.com/u/2717065?v=4" width="100px;" alt="su7edja"/><br /><sub><b>su7edja</b></sub></a><br /><a href="https://github.com/intuit/auto/commits?author=su7edja" title="Code">💻</a></td>
     <td align="center"><a href="https://github.com/yogikhan"><img src="https://avatars3.githubusercontent.com/u/16071601?v=4" width="100px;" alt="Yogesh Khandlewal"/><br /><sub><b>Yogesh Khandlewal</b></sub></a><br /><a href="https://github.com/intuit/auto/commits?author=yogikhan" title="Code">💻</a></td>
     <td align="center"><a href="https://github.com/Celeo"><img src="https://avatars1.githubusercontent.com/u/772507?v=4" width="100px;" alt="Matt Boulanger"/><br /><sub><b>Matt Boulanger</b></sub></a><br /><a href="https://github.com/intuit/auto/commits?author=Celeo" title="Code">💻</a></td>
+    <td align="center"><a href="https://github.com/karenclo"><img src="https://avatars1.githubusercontent.com/u/8535239?v=4" width="100px;" alt="Karen Lo"/><br /><sub><b>Karen Lo</b></sub></a><br /><a href="https://github.com/intuit/auto/commits?author=karenclo" title="Documentation">📖</a></td>
   </tr>
 </table>
 
diff --git a/lerna.json b/lerna.json
index 363948ee..9f68125d 100644
--- a/lerna.json
+++ b/lerna.json
@@ -1,5 +1,5 @@
 {
-  "version": "7.14.0",
+  "version": "7.13.3",
   "npmClient": "yarn",
   "useWorkspaces": true,
   "packages": [
diff --git a/packages/cli/package.json b/packages/cli/package.json
index 2117c3d9..87090378 100644
--- a/packages/cli/package.json
+++ b/packages/cli/package.json
@@ -2,7 +2,7 @@
   "name": "auto",
   "bin": "dist/bin/auto.js",
   "description": "CLI tools to help facilitate semantic versioning based on GitHub PR labels",
-  "version": "7.14.0",
+  "version": "7.13.3",
   "author": {
     "name": "Andrew Lisowski",
     "email": "lisowski54@gmail.com"
diff --git a/packages/core/package.json b/packages/core/package.json
index bcd50937..fcfe1907 100644
--- a/packages/core/package.json
+++ b/packages/core/package.json
@@ -1,6 +1,6 @@
 {
   "name": "@auto-it/core",
-  "version": "7.14.0",
+  "version": "7.13.3",
   "description": "Node API for using auto.",
   "main": "dist/auto.js",
   "author": {
diff --git a/plugins/all-contributors/package.json b/plugins/all-contributors/package.json
index 63304c3c..6d796242 100644
--- a/plugins/all-contributors/package.json
+++ b/plugins/all-contributors/package.json
@@ -1,6 +1,6 @@
 {
   "name": "@auto-it/all-contributors",
-  "version": "7.14.0",
+  "version": "7.13.3",
   "main": "dist/index.js",
   "description": "Automatically add contributors as changelogs are produced.",
   "author": {
diff --git a/plugins/all-contributors/src/index.ts b/plugins/all-contributors/src/index.ts
index f64d3cc8..f198cdcb 100644
--- a/plugins/all-contributors/src/index.ts
+++ b/plugins/all-contributors/src/index.ts
@@ -1,4 +1,4 @@
-import { Auto, IPlugin } from '@auto-it/core';
+import { Auto, IPlugin, execPromise } from '@auto-it/core';
 import fs from 'fs';
 import path from 'path';
 import match from 'anymatch';
@@ -89,73 +89,95 @@ export default class AllContributorsPlugin implements IPlugin {
 
   /** Tap into auto plugin points. */
   apply(auto: Auto) {
-    auto.hooks.afterAddToChangelog.tap(this.name, ({ commits }) => {
-      const config: AllContributorsRc = JSON.parse(
-        fs.readFileSync(rcFile, 'utf8')
-      );
-      const authorContributions: Record<string, Set<Contribution>> = {};
-      let didUpdate = false;
-
-      // 1. Find all the authors and their contribution types
-      commits.forEach(commit => {
-        const { authors } = commit;
-        let { files } = commit;
-
-        Object.keys(this.options.types || {})
-          .filter((type): type is Contribution => {
-            /** Determine if path is the contribution type */
-            const isType = (file: string) =>
-              match(this.options.types[type as Contribution] || [], file);
-            const isMatch = files.some(isType);
-            files = files.filter(file => !isType(file));
-
-            return isMatch;
+    auto.hooks.afterAddToChangelog.tapPromise(
+      this.name,
+      async ({ commits }) => {
+        const config: AllContributorsRc = JSON.parse(
+          fs.readFileSync(rcFile, 'utf8')
+        );
+        const authorContributions: Record<string, Set<Contribution>> = {};
+        let didUpdate = false;
+
+        const commitsWithAllChangedFiles = await Promise.all(
+          commits.map(async commit => {
+            const extra = await execPromise('git', [
+              'show',
+              '--pretty=""',
+              '--name-only',
+              '--first-parent',
+              '-m',
+              commit.hash
+            ]);
+
+            commit.files = [
+              ...new Set([...commit.files, ...extra.split('\n')])
+            ];
+
+            return commit;
           })
-          .forEach(contribution => {
-            authors.forEach(({ username }) => {
-              if (!username) {
-                return;
-              }
-
-              if (!authorContributions[username]) {
-                authorContributions[username] = new Set();
-              }
-
-              authorContributions[username].add(contribution);
+        );
+
+        // 1. Find all the authors and their contribution types
+        commitsWithAllChangedFiles.forEach(commit => {
+          const { authors } = commit;
+          let { files } = commit;
+
+          Object.keys(this.options.types || {})
+            .filter((type): type is Contribution => {
+              /** Determine if path is the contribution type */
+              const isType = (file: string) =>
+                match(this.options.types[type as Contribution] || [], file);
+              const isMatch = files.some(isType);
+              files = files.filter(file => !isType(file));
+
+              return isMatch;
+            })
+            .forEach(contribution => {
+              authors.forEach(({ username }) => {
+                if (!username) {
+                  return;
+                }
+
+                if (!authorContributions[username]) {
+                  authorContributions[username] = new Set();
+                }
+
+                authorContributions[username].add(contribution);
+              });
             });
-          });
-      });
-
-      // 2. Determine if contributor has update
-      Object.entries(authorContributions).forEach(
-        ([username, contributions]) => {
-          const { contributions: old = [] } =
-            config.contributors.find(
-              contributor => contributor.login === username
-            ) || {};
-          const hasNew = [...contributions].find(
-            contribution => !old.includes(contribution)
-          );
-
-          if (hasNew && !this.options.exclude.includes(username)) {
-            const newContributions = new Set([...old, ...contributions]);
-
-            didUpdate = true;
-            auto.logger.log.info(`Adding "${username}"'s contributions...`);
-
-            execSync(
-              `npx all-contributors add ${username} ${[
-                ...newContributions
-              ].join(',')}`,
-              { stdio: 'inherit' }
+        });
+
+        // 2. Determine if contributor has update
+        Object.entries(authorContributions).forEach(
+          ([username, contributions]) => {
+            const { contributions: old = [] } =
+              config.contributors.find(
+                contributor => contributor.login === username
+              ) || {};
+            const hasNew = [...contributions].find(
+              contribution => !old.includes(contribution)
             );
+
+            if (hasNew && !this.options.exclude.includes(username)) {
+              const newContributions = new Set([...old, ...contributions]);
+
+              didUpdate = true;
+              auto.logger.log.info(`Adding "${username}"'s contributions...`);
+
+              execSync(
+                `npx all-contributors add ${username} ${[
+                  ...newContributions
+                ].join(',')}`,
+                { stdio: 'inherit' }
+              );
+            }
           }
-        }
-      );
+        );
 
-      if (didUpdate) {
-        auto.logger.log.success('Updated contributors!');
+        if (didUpdate) {
+          auto.logger.log.success('Updated contributors!');
+        }
       }
-    });
+    );
   }
 }
diff --git a/plugins/chrome/package.json b/plugins/chrome/package.json
index 84a74e0c..af139dfa 100644
--- a/plugins/chrome/package.json
+++ b/plugins/chrome/package.json
@@ -1,6 +1,6 @@
 {
   "name": "@auto-it/chrome",
-  "version": "7.14.0",
+  "version": "7.13.3",
   "main": "dist/index.js",
   "description": "Chrome publishing plugin for auto",
   "author": {
diff --git a/plugins/conventional-commits/package.json b/plugins/conventional-commits/package.json
index f3a172b1..0531c39e 100644
--- a/plugins/conventional-commits/package.json
+++ b/plugins/conventional-commits/package.json
@@ -1,6 +1,6 @@
 {
   "name": "@auto-it/conventional-commits",
-  "version": "7.14.0",
+  "version": "7.13.3",
   "main": "dist/index.js",
   "description": "Conventional commit plugin for auto",
   "author": {
diff --git a/plugins/crates/package.json b/plugins/crates/package.json
index 7d531bab..2eb7191a 100644
--- a/plugins/crates/package.json
+++ b/plugins/crates/package.json
@@ -1,6 +1,6 @@
 {
   "name": "@auto-it/crates",
-  "version": "7.14.0",
+  "version": "7.13.3",
   "main": "dist/index.js",
   "description": "Deploy Rust crates to crates.io",
   "author": {
diff --git a/plugins/first-time-contributor/package.json b/plugins/first-time-contributor/package.json
index f780a77f..a0e7896a 100644
--- a/plugins/first-time-contributor/package.json
+++ b/plugins/first-time-contributor/package.json
@@ -1,6 +1,6 @@
 {
   "name": "@auto-it/first-time-contributor",
-  "version": "7.14.0",
+  "version": "7.13.3",
   "main": "dist/index.js",
   "description": "Thank first time contributors for their work right in your release notes.",
   "author": {
diff --git a/plugins/git-tag/package.json b/plugins/git-tag/package.json
index 23859fbe..223e858f 100644
--- a/plugins/git-tag/package.json
+++ b/plugins/git-tag/package.json
@@ -1,6 +1,6 @@
 {
   "name": "@auto-it/git-tag",
-  "version": "7.14.0",
+  "version": "7.13.3",
   "main": "dist/index.js",
   "description": "Manage your projects version through just a git tag",
   "author": {
diff --git a/plugins/jira/package.json b/plugins/jira/package.json
index cc3dc1c1..6035626e 100644
--- a/plugins/jira/package.json
+++ b/plugins/jira/package.json
@@ -1,6 +1,6 @@
 {
   "name": "@auto-it/jira",
-  "version": "7.14.0",
+  "version": "7.13.3",
   "main": "dist/index.js",
   "description": "Jira plugin for auto",
   "author": {
diff --git a/plugins/maven/package.json b/plugins/maven/package.json
index 8a400c12..16e18b2d 100644
--- a/plugins/maven/package.json
+++ b/plugins/maven/package.json
@@ -1,6 +1,6 @@
 {
   "name": "@auto-it/maven",
-  "version": "7.14.0",
+  "version": "7.13.3",
   "main": "dist/index.js",
   "description": "Maven publishing plugin for auto",
   "author": {
diff --git a/plugins/npm/package.json b/plugins/npm/package.json
index fa5c9d5d..7026d33b 100644
--- a/plugins/npm/package.json
+++ b/plugins/npm/package.json
@@ -1,6 +1,6 @@
 {
   "name": "@auto-it/npm",
-  "version": "7.14.0",
+  "version": "7.13.3",
   "main": "dist/index.js",
   "description": "NPM publishing plugin for auto",
   "author": {
diff --git a/plugins/omit-commits/package.json b/plugins/omit-commits/package.json
index 7a15fe09..9178281d 100644
--- a/plugins/omit-commits/package.json
+++ b/plugins/omit-commits/package.json
@@ -1,6 +1,6 @@
 {
   "name": "@auto-it/omit-commits",
-  "version": "7.14.0",
+  "version": "7.13.3",
   "main": "dist/index.js",
   "description": "Omit commits plugin for auto",
   "author": {
diff --git a/plugins/omit-release-notes/package.json b/plugins/omit-release-notes/package.json
index d24a5d89..2a810de3 100644
--- a/plugins/omit-release-notes/package.json
+++ b/plugins/omit-release-notes/package.json
@@ -1,6 +1,6 @@
 {
   "name": "@auto-it/omit-release-notes",
-  "version": "7.14.0",
+  "version": "7.13.3",
   "main": "dist/index.js",
   "description": "Omit release notes plugin for auto",
   "author": {
diff --git a/plugins/released/package.json b/plugins/released/package.json
index b937a7da..c2f009fb 100644
--- a/plugins/released/package.json
+++ b/plugins/released/package.json
@@ -1,6 +1,6 @@
 {
   "name": "@auto-it/released",
-  "version": "7.14.0",
+  "version": "7.13.3",
   "main": "dist/index.js",
   "description": "Released plugin for auto. Comments with version + extra",
   "author": {
diff --git a/plugins/s3/package.json b/plugins/s3/package.json
index 87d8d387..9b6da36d 100644
--- a/plugins/s3/package.json
+++ b/plugins/s3/package.json
@@ -1,6 +1,6 @@
 {
   "name": "@auto-it/s3",
-  "version": "7.14.0",
+  "version": "7.13.3",
   "main": "dist/index.js",
   "description": "Post your built artifacts to s3",
   "author": {
diff --git a/plugins/slack/package.json b/plugins/slack/package.json
index b39bd7fd..b16de9fb 100644
--- a/plugins/slack/package.json
+++ b/plugins/slack/package.json
@@ -1,6 +1,6 @@
 {
   "name": "@auto-it/slack",
-  "version": "7.14.0",
+  "version": "7.13.3",
   "main": "dist/index.js",
   "description": "Slack plugin for auto",
   "author": {
diff --git a/plugins/twitter/package.json b/plugins/twitter/package.json
index 45a65f98..acf73c46 100644
--- a/plugins/twitter/package.json
+++ b/plugins/twitter/package.json
@@ -1,6 +1,6 @@
 {
   "name": "@auto-it/twitter",
-  "version": "7.14.0",
+  "version": "7.13.3",
   "main": "dist/index.js",
   "description": "Twitter plugin for auto",
   "author": {
diff --git a/plugins/upload-assets/package.json b/plugins/upload-assets/package.json
index fe1fee7d..aa5ce988 100644
--- a/plugins/upload-assets/package.json
+++ b/plugins/upload-assets/package.json
@@ -1,6 +1,6 @@
 {
   "name": "@auto-it/upload-assets",
-  "version": "7.14.0",
+  "version": "7.13.3",
   "main": "dist/index.js",
   "description": "Upload assets plugin for auto",
   "author": {


Test patch:
diff --git a/plugins/all-contributors/__tests__/all-contributors.test.ts b/plugins/all-contributors/__tests__/all-contributors.test.ts
index 9dc4d275..3ee0da4c 100644
--- a/plugins/all-contributors/__tests__/all-contributors.test.ts
+++ b/plugins/all-contributors/__tests__/all-contributors.test.ts
@@ -1,4 +1,4 @@
-import Auto, { SEMVER } from '@auto-it/core';
+import * as Auto from '@auto-it/core';
 import { execSync } from 'child_process';
 import { makeHooks } from '@auto-it/core/dist/utils/make-hooks';
 import makeCommitFromMsg from '@auto-it/core/dist/__tests__/make-commit-from-msg';
@@ -8,10 +8,14 @@ import fs from 'fs';
 import AllContributors from '../src';
 
 const exec = jest.fn();
+const gitShow = jest.fn();
+gitShow.mockReturnValue('');
 exec.mockReturnValue('');
 jest.mock('child_process');
 // @ts-ignore
 execSync.mockImplementation(exec);
+// @ts-ignore
+jest.spyOn(Auto, 'execPromise').mockImplementation(gitShow);
 
 const mockRead = (result: string) =>
   jest
@@ -29,10 +33,10 @@ describe('All Contributors Plugin', () => {
     const autoHooks = makeHooks();
     mockRead('{ "contributors": [] }');
 
-    releasedLabel.apply({ hooks: autoHooks, logger: dummyLog() } as Auto);
+    releasedLabel.apply({ hooks: autoHooks, logger: dummyLog() } as Auto.Auto);
 
     await autoHooks.afterAddToChangelog.promise({
-      bump: SEMVER.patch,
+      bump: Auto.SEMVER.patch,
       currentVersion: '0.0.0',
       lastRelease: '0.0.0',
       releaseNotes: '',
@@ -52,10 +56,10 @@ describe('All Contributors Plugin', () => {
     const autoHooks = makeHooks();
     mockRead('{ "contributors": [] }');
 
-    releasedLabel.apply({ hooks: autoHooks, logger: dummyLog() } as Auto);
+    releasedLabel.apply({ hooks: autoHooks, logger: dummyLog() } as Auto.Auto);
 
     await autoHooks.afterAddToChangelog.promise({
-      bump: SEMVER.patch,
+      bump: Auto.SEMVER.patch,
       currentVersion: '0.0.0',
       lastRelease: '0.0.0',
       releaseNotes: '',
@@ -70,15 +74,39 @@ describe('All Contributors Plugin', () => {
     expect(exec.mock.calls[0][0]).toBe('npx all-contributors add Jeff code');
   });
 
+  test('should find contributions from merge commit', async () => {
+    const releasedLabel = new AllContributors();
+    const autoHooks = makeHooks();
+    mockRead('{ "contributors": [] }');
+    gitShow.mockReturnValueOnce('src/index.ts');
+
+    releasedLabel.apply({ hooks: autoHooks, logger: dummyLog() } as Auto.Auto);
+
+    await autoHooks.afterAddToChangelog.promise({
+      bump: Auto.SEMVER.patch,
+      currentVersion: '0.0.0',
+      lastRelease: '0.0.0',
+      releaseNotes: '',
+      commits: [
+        makeCommitFromMsg('Do the thing', {
+          files: [],
+          username: 'Jeff'
+        })
+      ]
+    });
+
+    expect(exec.mock.calls[0][0]).toBe('npx all-contributors add Jeff code');
+  });
+
   test('should find a multiple contributions', async () => {
     const releasedLabel = new AllContributors();
     const autoHooks = makeHooks();
     mockRead('{ "contributors": [] }');
 
-    releasedLabel.apply({ hooks: autoHooks, logger: dummyLog() } as Auto);
+    releasedLabel.apply({ hooks: autoHooks, logger: dummyLog() } as Auto.Auto);
 
     await autoHooks.afterAddToChangelog.promise({
-      bump: SEMVER.patch,
+      bump: Auto.SEMVER.patch,
       currentVersion: '0.0.0',
       lastRelease: '0.0.0',
       releaseNotes: '',
@@ -106,10 +134,10 @@ describe('All Contributors Plugin', () => {
       '{ "contributors": [ { "login": "Jeff", "contributions": ["infra"] } ] }'
     );
 
-    releasedLabel.apply({ hooks: autoHooks, logger: dummyLog() } as Auto);
+    releasedLabel.apply({ hooks: autoHooks, logger: dummyLog() } as Auto.Auto);
 
     await autoHooks.afterAddToChangelog.promise({
-      bump: SEMVER.patch,
+      bump: Auto.SEMVER.patch,
       currentVersion: '0.0.0',
       lastRelease: '0.0.0',
       releaseNotes: '',
@@ -126,17 +154,17 @@ describe('All Contributors Plugin', () => {
     );
   });
 
-  test('should not update if no new contribution tpyes', async () => {
+  test('should not update if no new contribution types', async () => {
     const releasedLabel = new AllContributors();
     const autoHooks = makeHooks();
     mockRead(
       '{ "contributors": [ { "login": "Jeff", "contributions": ["code"] } ] }'
     );
 
-    releasedLabel.apply({ hooks: autoHooks, logger: dummyLog() } as Auto);
+    releasedLabel.apply({ hooks: autoHooks, logger: dummyLog() } as Auto.Auto);
 
     await autoHooks.afterAddToChangelog.promise({
-      bump: SEMVER.patch,
+      bump: Auto.SEMVER.patch,
       currentVersion: '0.0.0',
       lastRelease: '0.0.0',
       releaseNotes: '',