diff --git a/lib/workers/branch/index.js b/lib/workers/branch/index.js
index 5a8384ed9bc3ef1c83b7c8cb095fcefe1f921679..c6fcf2d42f765c75de8016b1db08da22a2220076 100644
--- a/lib/workers/branch/index.js
+++ b/lib/workers/branch/index.js
@@ -8,7 +8,6 @@ let logger = require('../../logger');
 module.exports = {
   getParentBranch,
   ensureBranch,
-  generateConfig,
   processBranchUpgrades,
 };
 
@@ -191,37 +190,10 @@ async function ensureBranch(config) {
   return true;
 }
 
-async function generateConfig(branchUpgrades) {
-  const config = {
-    upgrades: [],
-  };
-  const hasGroupName = branchUpgrades[0].groupName !== null;
-  logger.debug(`hasGroupName: ${hasGroupName}`);
-  // Use group settings only if multiple upgrades or lazy grouping is disabled
-  const groupEligible =
-    branchUpgrades.length > 1 || branchUpgrades[0].lazyGrouping === false;
-  logger.debug(`groupEligible: ${groupEligible}`);
-  const useGroupSettings = hasGroupName && groupEligible;
-  logger.debug(`useGroupSettings: ${useGroupSettings}`);
-  for (const branchUpgrade of branchUpgrades) {
-    const upgrade = Object.assign({}, branchUpgrade);
-    if (useGroupSettings) {
-      // Now overwrite original config with group config
-      Object.assign(upgrade, upgrade.group);
-    }
-    // Delete group config regardless of whether it was applied
-    delete upgrade.group;
-    config.upgrades.push(upgrade);
-  }
-  // Now assign first upgrade's config as branch config
-  return Object.assign(config, config.upgrades[0]);
-}
-
 async function processBranchUpgrades(branchUpgrades, errors, warnings) {
   logger.trace({ config: branchUpgrades }, 'processBranchUpgrades');
   let createdBranch;
-  const config = await module.exports.generateConfig(branchUpgrades);
-  logger.trace({ config }, 'generateConfig');
+  const config = Object.assign({}, branchUpgrades);
   // Delete the semanticPrefix for this branch if feature is not enabled
   if (config.semanticCommits) {
     logger.debug('Branch has semantic commits enabled');
@@ -233,7 +205,7 @@ async function processBranchUpgrades(branchUpgrades, errors, warnings) {
   const branchName = handlebars.compile(config.branchName)(config);
   const prTitle = handlebars.compile(config.prTitle)(config);
 
-  logger = config.logger.child({
+  logger = logger.child({
     repository: config.repository,
     branch: branchName,
   });
diff --git a/lib/workers/repository/index.js b/lib/workers/repository/index.js
index 264cb959dfa13cdcd90499b15b812f6c6f83666d..c669f000f99b9d34ddcdbd6228f22bd998af6581 100644
--- a/lib/workers/repository/index.js
+++ b/lib/workers/repository/index.js
@@ -62,15 +62,13 @@ async function renovateRepository(packageFileConfig) {
     config.errors = config.errors.concat(res.errors);
     config.warnings = config.warnings.concat(res.warnings);
     const branchUpgrades = res.branchUpgrades;
-    config.logger.debug(
-      `Updating ${Object.keys(branchUpgrades).length} branch(es)`
-    );
+    config.logger.debug(`Updating ${branchUpgrades.length} branch(es)`);
     config.logger.trace({ config: branchUpgrades }, 'branchUpgrades');
     if (config.repoIsOnboarded) {
       const branchList = [];
-      for (const branchName of Object.keys(branchUpgrades)) {
+      for (const branchUpgrade of branchUpgrades) {
         const createdBranchName = await branchWorker.processBranchUpgrades(
-          branchUpgrades[branchName],
+          branchUpgrade,
           config.errors,
           config.warnings
         );
diff --git a/lib/workers/repository/onboarding.js b/lib/workers/repository/onboarding.js
index 574dce997d96bdec97349626c4f1525b5d5e831e..88e177af5be95f995e0fc5e4c9bb8eca40b6960e 100644
--- a/lib/workers/repository/onboarding.js
+++ b/lib/workers/repository/onboarding.js
@@ -30,7 +30,6 @@ async function createBranch(config) {
 async function ensurePr(config, branchUpgrades) {
   const warnings = config.warnings;
   const errors = config.errors;
-  const onboardBranchNames = Object.keys(branchUpgrades);
   let prBody = `Welcome to [Renovate](https://keylocation.sg/our-tech/renovate)!
 
 This is an onboarding PR to help you understand and configure Renovate before any changes are made to any \`package.json\` files. Once you close this Pull Request, we will begin keeping your dependencies up-to-date via automated Pull Requests.
@@ -89,29 +88,18 @@ Please make any fixes in _this branch_.
   let prDesc = `
 With your current configuration, renovate will initially create the following Pull Requests:
 
-| Pull Requests (${onboardBranchNames.length}) |
+| Pull Requests (${branchUpgrades.length}) |
 | ------ |
 `;
-  onboardBranchNames.forEach(branchName => {
-    const upgrades = branchUpgrades[branchName];
-    const upgrade0 = upgrades[0];
-    if (!upgrade0.lazyGrouping || (upgrade0.groupName && upgrades.length > 1)) {
-      Object.assign(upgrade0, upgrade0.group);
-    }
-    // Delete the semanticPrefix for this branch if feature is not enabled
-    if (upgrade0.semanticCommits) {
-      config.logger.debug('Branch has semantic commits enabled');
-    } else {
-      config.logger.debug('Branch has semantic commits disabled');
-      delete upgrade0.semanticPrefix;
-    }
-    const prTitle = handlebars.compile(upgrade0.prTitle)(upgrade0);
+  branchUpgrades.forEach(branch => {
+    const branchName = handlebars.compile(branch.branchName)(branch);
+    const prTitle = handlebars.compile(branch.prTitle)(branch);
     prDesc += `| **${prTitle}**<ul>`;
-    if (upgrade0.schedule && upgrade0.schedule.length) {
-      prDesc += `<li>Schedule: ${JSON.stringify(upgrade0.schedule)}</li>`;
+    if (branch.schedule && branch.schedule.length) {
+      prDesc += `<li>Schedule: ${JSON.stringify(branch.schedule)}</li>`;
     }
     prDesc += `<li>Branch name: \`${branchName}\`</li>`;
-    upgrades.forEach(upgrade => {
+    branch.upgrades.forEach(upgrade => {
       if (upgrade.isPin) {
         prDesc += '<li>Pins ';
       } else {
@@ -122,7 +110,7 @@ With your current configuration, renovate will initially create the following Pu
     });
     prDesc += '</ul> |\n';
   });
-  if (onboardBranchNames.length === 0) {
+  if (branchUpgrades.length === 0) {
     // Overwrite empty content
     prDesc =
       'It looks like your repository dependencies are already up-to-date and no initial Pull Requests will be necessary.';
diff --git a/lib/workers/repository/upgrades.js b/lib/workers/repository/upgrades.js
index 25b35cc3d86705613c0197f145bb0a245f39a21a..9d0dbb4984f07f5671ccc2ce1082909bea0d9219 100644
--- a/lib/workers/repository/upgrades.js
+++ b/lib/workers/repository/upgrades.js
@@ -2,8 +2,12 @@ const handlebars = require('handlebars');
 const configParser = require('../../config');
 const packageFileWorker = require('../package-file');
 
+let logger = require('../../logger');
+
 module.exports = {
   determineRepoUpgrades,
+  groupByBranch,
+  generateConfig,
   branchifyUpgrades,
   getPackageFileConfig,
 };
@@ -27,8 +31,37 @@ async function determineRepoUpgrades(config) {
   return upgrades;
 }
 
-async function branchifyUpgrades(upgrades, logger) {
-  logger.trace({ config: upgrades }, 'branchifyUpgrades');
+function generateConfig(branchUpgrades) {
+  const config = {
+    upgrades: [],
+  };
+  const hasGroupName = branchUpgrades[0].groupName !== null;
+  logger.debug(`hasGroupName: ${hasGroupName}`);
+  // Use group settings only if multiple upgrades or lazy grouping is disabled
+  const groupEligible =
+    branchUpgrades.length > 1 || branchUpgrades[0].lazyGrouping === false;
+  logger.debug(`groupEligible: ${groupEligible}`);
+  const useGroupSettings = hasGroupName && groupEligible;
+  logger.debug(`useGroupSettings: ${useGroupSettings}`);
+  for (const branchUpgrade of branchUpgrades) {
+    const upgrade = Object.assign({}, branchUpgrade);
+    if (useGroupSettings) {
+      // Now overwrite original config with group config
+      Object.assign(upgrade, upgrade.group);
+    } else {
+      delete upgrade.groupName;
+    }
+    // Delete group config regardless of whether it was applied
+    delete upgrade.group;
+    delete upgrade.lazyGrouping;
+    config.upgrades.push(upgrade);
+  }
+  // Now assign first upgrade's config as branch config
+  return Object.assign(config, config.upgrades[0]);
+}
+
+function groupByBranch(upgrades) {
+  logger.trace({ config: upgrades }, 'groupUpgrades');
   logger.info(`Processing ${upgrades.length} dependency upgrade(s)`);
   const result = {
     errors: [],
@@ -72,6 +105,22 @@ async function branchifyUpgrades(upgrades, logger) {
   return result;
 }
 
+async function branchifyUpgrades(upgrades, parentLogger) {
+  logger = parentLogger || logger;
+  logger.debug('branchifyUpgrades');
+  logger.trace({ config: upgrades }, 'branchifyUpgrades');
+  const branchConfigs = [];
+  const res = module.exports.groupByBranch(upgrades);
+  for (const branchName of Object.keys(res.branchUpgrades)) {
+    logger = logger.child({ branch: branchName });
+    const branchUpgrades = res.branchUpgrades[branchName];
+    const branchConfig = module.exports.generateConfig(branchUpgrades);
+    branchConfig.logger = logger;
+    branchConfigs.push(branchConfig);
+  }
+  return branchConfigs;
+}
+
 function getPackageFileConfig(repoConfig, index) {
   let packageFile = repoConfig.packageFiles[index];
   if (typeof packageFile === 'string') {
diff --git a/test/workers/branch/index.spec.js b/test/workers/branch/index.spec.js
index e0ebb682c466d4720df57db6701a131fd60afee7..c68af96f72688bd68dcb4270d43c3f1980fc776c 100644
--- a/test/workers/branch/index.spec.js
+++ b/test/workers/branch/index.spec.js
@@ -331,58 +331,46 @@ describe('workers/branch', () => {
       config.logger = logger;
       branchWorker.ensureBranch = jest.fn(() => true);
       prWorker.ensurePr = jest.fn(() => true);
+      config.upgrades = [{ depName: 'a' }];
     });
     it('returns immediately if closed PR found', async () => {
       config.api.checkForClosedPr.mockReturnValue(true);
-      await branchWorker.processBranchUpgrades([config]);
+      await branchWorker.processBranchUpgrades(config);
       expect(branchWorker.ensureBranch.mock.calls.length).toBe(0);
     });
     it('does not return immediately if recreateClosed true', async () => {
       config.api.checkForClosedPr.mockReturnValue(true);
       config.recreateClosed = true;
-      await branchWorker.processBranchUpgrades([config]);
+      await branchWorker.processBranchUpgrades(config);
       expect(branchWorker.ensureBranch.mock.calls.length).toBe(1);
     });
     it('pins', async () => {
       config.type = 'pin';
-      await branchWorker.processBranchUpgrades([config]);
+      await branchWorker.processBranchUpgrades(config);
       expect(branchWorker.ensureBranch.mock.calls.length).toBe(1);
     });
     it('majors', async () => {
       config.type = 'major';
-      await branchWorker.processBranchUpgrades([config]);
+      await branchWorker.processBranchUpgrades(config);
       expect(branchWorker.ensureBranch.mock.calls.length).toBe(1);
     });
     it('minors', async () => {
       config.type = 'minor';
-      await branchWorker.processBranchUpgrades([config]);
+      await branchWorker.processBranchUpgrades(config);
       expect(branchWorker.ensureBranch.mock.calls.length).toBe(1);
     });
     it('handles semantic commits', async () => {
       config.type = 'minor';
       config.semanticCommits = true;
-      await branchWorker.processBranchUpgrades([config]);
+      await branchWorker.processBranchUpgrades(config);
       expect(branchWorker.ensureBranch.mock.calls.length).toBe(1);
     });
     it('handles errors', async () => {
       config.api.checkForClosedPr = jest.fn(() => {
         throw new Error('oops');
       });
-      await branchWorker.processBranchUpgrades([config]);
+      await branchWorker.processBranchUpgrades(config);
       expect(branchWorker.ensureBranch.mock.calls.length).toBe(0);
     });
   });
-  describe('generateConfig(branchUpgrades)', () => {
-    let config;
-    beforeEach(() => {
-      config = Object.assign({}, defaultConfig, { logger });
-    });
-    it('uses group settings', async () => {
-      config.groupName = 'some-group';
-      config.group.branchName = 'some-group-branchname';
-      const branchUpgrades = [config, config];
-      const res = await branchWorker.generateConfig(branchUpgrades);
-      expect(res.branchName).toEqual(config.group.branchName);
-    });
-  });
 });
diff --git a/test/workers/repository/__snapshots__/upgrades.spec.js.snap b/test/workers/repository/__snapshots__/upgrades.spec.js.snap
index 3cc4de3c3f6d2e5cf8e7cf75d2e11c0317cc096e..87019805872d65c06848816027359b1dbaaf1d75 100644
--- a/test/workers/repository/__snapshots__/upgrades.spec.js.snap
+++ b/test/workers/repository/__snapshots__/upgrades.spec.js.snap
@@ -1,6 +1,34 @@
 // Jest Snapshot v1, https://goo.gl/fbAQLP
 
-exports[`workers/repository/upgrades branchifyUpgrades(upgrades, logger) does not group if different compiled branch names 1`] = `
+exports[`workers/repository/upgrades generateConfig(branchUpgrades) does not group single upgrade 1`] = `
+Object {
+  "depName": "some-dep",
+  "foo": 1,
+  "upgrades": Array [
+    Object {
+      "depName": "some-dep",
+      "foo": 1,
+    },
+  ],
+}
+`;
+
+exports[`workers/repository/upgrades generateConfig(branchUpgrades) groups single upgrade if not lazyGrouping 1`] = `
+Object {
+  "depName": "some-dep",
+  "foo": 2,
+  "groupName": "some-group",
+  "upgrades": Array [
+    Object {
+      "depName": "some-dep",
+      "foo": 2,
+      "groupName": "some-group",
+    },
+  ],
+}
+`;
+
+exports[`workers/repository/upgrades groupByBranch(upgrades) does not group if different compiled branch names 1`] = `
 Object {
   "branchUpgrades": Object {
     "bar-1.1.0": Array [
@@ -27,7 +55,7 @@ Object {
 }
 `;
 
-exports[`workers/repository/upgrades branchifyUpgrades(upgrades, logger) groups if same compiled branch names 1`] = `
+exports[`workers/repository/upgrades groupByBranch(upgrades) groups if same compiled branch names 1`] = `
 Object {
   "branchUpgrades": Object {
     "bar-1.1.0": Array [
@@ -52,7 +80,7 @@ Object {
 }
 `;
 
-exports[`workers/repository/upgrades branchifyUpgrades(upgrades, logger) groups if same compiled group name 1`] = `
+exports[`workers/repository/upgrades groupByBranch(upgrades) groups if same compiled group name 1`] = `
 Object {
   "branchUpgrades": Object {
     "foo": Array [
@@ -87,7 +115,7 @@ Object {
 }
 `;
 
-exports[`workers/repository/upgrades branchifyUpgrades(upgrades, logger) mixes errors and warnings 1`] = `
+exports[`workers/repository/upgrades groupByBranch(upgrades) mixes errors and warnings 1`] = `
 Object {
   "branchUpgrades": Object {
     "bar-1.1.0": Array [
@@ -118,7 +146,7 @@ Object {
 }
 `;
 
-exports[`workers/repository/upgrades branchifyUpgrades(upgrades, logger) returns empty object if no input array 1`] = `
+exports[`workers/repository/upgrades groupByBranch(upgrades) returns empty object if no input array 1`] = `
 Object {
   "branchUpgrades": Object {},
   "errors": Array [],
@@ -126,7 +154,7 @@ Object {
 }
 `;
 
-exports[`workers/repository/upgrades branchifyUpgrades(upgrades, logger) returns one branch if one input 1`] = `
+exports[`workers/repository/upgrades groupByBranch(upgrades) returns one branch if one input 1`] = `
 Object {
   "branchUpgrades": Object {
     "foo-1.1.0": Array [
@@ -140,3 +168,23 @@ Object {
   "warnings": Array [],
 }
 `;
+
+exports[`workers/repository/upgrades groups multiple upgrades 1`] = `
+Object {
+  "depName": "some-dep",
+  "foo": 2,
+  "groupName": "some-group",
+  "upgrades": Array [
+    Object {
+      "depName": "some-dep",
+      "foo": 2,
+      "groupName": "some-group",
+    },
+    Object {
+      "depName": "some-other-dep",
+      "foo": 2,
+      "groupName": "some-group",
+    },
+  ],
+}
+`;
diff --git a/test/workers/repository/index.spec.js b/test/workers/repository/index.spec.js
index 5ce2f9d9fc33a2d93e44d58e9f2924478f399c3e..be9ae49a4c84f30ab61319acb63ad2ad905feb8e 100644
--- a/test/workers/repository/index.spec.js
+++ b/test/workers/repository/index.spec.js
@@ -83,11 +83,7 @@ describe('workers/repository', () => {
       config.hasRenovateJson = true;
       onboarding.getOnboardingStatus.mockReturnValueOnce(true);
       upgrades.branchifyUpgrades.mockReturnValueOnce({
-        branchUpgrades: {
-          foo: {},
-          bar: {},
-          baz: {},
-        },
+        branchUpgrades: [{}, {}, {}],
       });
       await repositoryWorker.renovateRepository(config);
       expect(branchWorker.processBranchUpgrades.mock.calls.length).toBe(3);
diff --git a/test/workers/repository/onboarding.spec.js b/test/workers/repository/onboarding.spec.js
index f02eb610835d2e95dd8ac1d056b210918e814777..0ea02ba0b3a7fd5349c363e04136da5bd21b6bb1 100644
--- a/test/workers/repository/onboarding.spec.js
+++ b/test/workers/repository/onboarding.spec.js
@@ -17,7 +17,7 @@ describe('lib/workers/repository/onboarding', () => {
         },
         logger,
       };
-      branchUpgrades = {};
+      branchUpgrades = [];
     });
     it('creates pr', async () => {
       config.baseBranch = 'next';
@@ -65,85 +65,95 @@ If the default settings are all suitable for you, simply close this Pull Request
       expect(config.api.updatePr.mock.calls.length).toBe(0);
     });
     it('creates complex pr', async () => {
-      branchUpgrades = {
-        'branch-a': [
-          {
-            prTitle: 'Pin a',
-            isPin: true,
-            depName: 'a',
-            repositoryUrl: 'https://a',
-            currentVersion: '^1.0.0',
-            newVersion: '1.1.0',
-            semanticCommits: true,
-          },
-        ],
-        'branch-b': [
-          {
-            prTitle: 'Upgrade b',
-            depName: 'b',
-            repositoryUrl: 'https://b',
-            currentVersion: '1.0.0',
-            newVersion: '2.0.0',
-            schedule: 'on monday',
-          },
-        ],
-      };
+      branchUpgrades = [
+        {
+          branchName: 'branch-a',
+          prTitle: 'Pin a',
+          upgrades: [
+            {
+              isPin: true,
+              depName: 'a',
+              repositoryUrl: 'https://a',
+              currentVersion: '^1.0.0',
+              newVersion: '1.1.0',
+            },
+          ],
+        },
+        {
+          branchName: 'branch-b',
+          prTitle: 'Upgrade b',
+          schedule: 'on monday',
+          upgrades: [
+            {
+              depName: 'b',
+              repositoryUrl: 'https://b',
+              currentVersion: '1.0.0',
+              newVersion: '2.0.0',
+            },
+          ],
+        },
+      ];
       await onboarding.ensurePr(config, branchUpgrades);
       expect(config.api.createPr.mock.calls.length).toBe(1);
       expect(config.api.updatePr.mock.calls.length).toBe(0);
       expect(config.api.createPr.mock.calls).toMatchSnapshot();
     });
     it('handles groups', async () => {
-      branchUpgrades = {
-        'branch-a': [
-          {
-            prTitle: 'Pin a',
-            isPin: true,
-            depName: 'a',
-            repositoryUrl: 'https://a',
-            currentVersion: '^1.0.0',
-            newVersion: '1.1.0',
-            semanticCommits: true,
-            lazyGrouping: true,
-            groupName: 'some-group',
-          },
-          {
-            prTitle: 'Upgrade b',
-            depName: 'b',
-            repositoryUrl: 'https://b',
-            currentVersion: '1.0.0',
-            newVersion: '2.0.0',
-            schedule: 'on monday',
-          },
-        ],
-      };
+      branchUpgrades = [
+        {
+          branchName: 'branch-a',
+          prTitle: 'Pin a',
+          groupName: 'some-group',
+          upgrades: [
+            {
+              isPin: true,
+              depName: 'a',
+              repositoryUrl: 'https://a',
+              currentVersion: '^1.0.0',
+              newVersion: '1.1.0',
+            },
+            {
+              depName: 'b',
+              repositoryUrl: 'https://b',
+              currentVersion: '1.0.0',
+              newVersion: '2.0.0',
+            },
+          ],
+        },
+      ];
       await onboarding.ensurePr(config, branchUpgrades);
       expect(config.api.createPr.mock.calls.length).toBe(1);
       expect(config.api.updatePr.mock.calls.length).toBe(0);
       expect(config.api.createPr.mock.calls).toMatchSnapshot();
     });
     it('creates shows warnings and errors', async () => {
-      branchUpgrades = {
-        'branch-a': [
-          {
-            prTitle: 'Pin a',
-            isPin: true,
-            depName: 'a',
-            repositoryUrl: 'https://a',
-            currentVersion: '^1.0.0',
-            newVersion: '1.1.0',
-          },
-        ],
-        'branch-b': [
-          {
-            prTitle: 'Upgrade b',
-            depName: 'b',
-            repositoryUrl: 'https://b',
-            currentVersion: '1.0.0',
-            newVersion: '2.0.0',
-          },
-        ],
-      };
+      branchUpgrades = [
+        {
+          branchName: 'branch-a',
+          prTitle: 'Pin a',
+          upgrades: [
+            {
+              isPin: true,
+              depName: 'a',
+              repositoryUrl: 'https://a',
+              currentVersion: '^1.0.0',
+              newVersion: '1.1.0',
+            },
+          ],
+        },
+        {
+          branchName: 'branch-b',
+          prTitle: 'Upgrade b',
+          upgrades: [
+            {
+              depName: 'b',
+              repositoryUrl: 'https://b',
+              currentVersion: '1.0.0',
+              newVersion: '2.0.0',
+            },
+          ],
+        },
+      ];
       config.errors = [
         {
           depName: 'a',
diff --git a/test/workers/repository/upgrades.spec.js b/test/workers/repository/upgrades.spec.js
index faf64a50f2d3e693c783594d532509c5d4d99e61..0583efb106023ac9af2927c39111f57c9b703d79 100644
--- a/test/workers/repository/upgrades.spec.js
+++ b/test/workers/repository/upgrades.spec.js
@@ -44,9 +44,71 @@ describe('workers/repository/upgrades', () => {
       expect(res.length).toBe(3);
     });
   });
-  describe('branchifyUpgrades(upgrades, logger)', () => {
+  describe('generateConfig(branchUpgrades)', () => {
+    it('does not group single upgrade', () => {
+      const branchUpgrades = [
+        {
+          depName: 'some-dep',
+          groupName: 'some-group',
+          lazyGrouping: true,
+          foo: 1,
+          group: {
+            foo: 2,
+          },
+        },
+      ];
+      const res = upgrades.generateConfig(branchUpgrades);
+      expect(res.foo).toBe(1);
+      expect(res.groupName).toBeUndefined();
+      expect(res).toMatchSnapshot();
+    });
+    it('groups single upgrade if not lazyGrouping', () => {
+      const branchUpgrades = [
+        {
+          depName: 'some-dep',
+          groupName: 'some-group',
+          lazyGrouping: false,
+          foo: 1,
+          group: {
+            foo: 2,
+          },
+        },
+      ];
+      const res = upgrades.generateConfig(branchUpgrades);
+      expect(res.foo).toBe(2);
+      expect(res.groupName).toBeDefined();
+      expect(res).toMatchSnapshot();
+    });
+  });
+  it('groups multiple upgrades', () => {
+    const branchUpgrades = [
+      {
+        depName: 'some-dep',
+        groupName: 'some-group',
+        lazyGrouping: true,
+        foo: 1,
+        group: {
+          foo: 2,
+        },
+      },
+      {
+        depName: 'some-other-dep',
+        groupName: 'some-group',
+        lazyGrouping: true,
+        foo: 1,
+        group: {
+          foo: 2,
+        },
+      },
+    ];
+    const res = upgrades.generateConfig(branchUpgrades);
+    expect(res.foo).toBe(2);
+    expect(res.groupName).toBeDefined();
+    expect(res).toMatchSnapshot();
+  });
+  describe('groupByBranch(upgrades)', () => {
     it('returns empty object if no input array', async () => {
-      const res = await upgrades.branchifyUpgrades([], logger);
+      const res = await upgrades.groupByBranch([]);
       expect(res).toMatchSnapshot();
     });
     it('returns one branch if one input', async () => {
@@ -56,7 +118,7 @@ describe('workers/repository/upgrades', () => {
           version: '1.1.0',
         },
       ];
-      const res = await upgrades.branchifyUpgrades(input, logger);
+      const res = await upgrades.groupByBranch(input);
       expect(Object.keys(res.branchUpgrades).length).toBe(1);
       expect(res).toMatchSnapshot();
     });
@@ -75,7 +137,7 @@ describe('workers/repository/upgrades', () => {
           version: '1.1.0',
         },
       ];
-      const res = await upgrades.branchifyUpgrades(input, logger);
+      const res = await upgrades.groupByBranch(input);
       expect(Object.keys(res.branchUpgrades).length).toBe(3);
       expect(res).toMatchSnapshot();
     });
@@ -94,7 +156,7 @@ describe('workers/repository/upgrades', () => {
           version: '1.1.0',
         },
       ];
-      const res = await upgrades.branchifyUpgrades(input, logger);
+      const res = await upgrades.groupByBranch(input);
       expect(Object.keys(res.branchUpgrades).length).toBe(2);
       expect(res).toMatchSnapshot();
     });
@@ -117,7 +179,7 @@ describe('workers/repository/upgrades', () => {
           group: { branchName: 'renovate/my-group' },
         },
       ];
-      const res = await upgrades.branchifyUpgrades(input, logger);
+      const res = await upgrades.groupByBranch(input);
       expect(Object.keys(res.branchUpgrades).length).toBe(2);
       expect(res).toMatchSnapshot();
     });
@@ -140,11 +202,35 @@ describe('workers/repository/upgrades', () => {
           version: '1.1.0',
         },
       ];
-      const res = await upgrades.branchifyUpgrades(input, logger);
+      const res = await upgrades.groupByBranch(input);
       expect(Object.keys(res.branchUpgrades).length).toBe(2);
       expect(res.errors).toHaveLength(1);
       expect(res.warnings).toHaveLength(1);
       expect(res).toMatchSnapshot();
     });
   });
+  describe('branchifyUpgrades(upgrades, parentLogger)', () => {
+    it('returns empty', async () => {
+      upgrades.groupByBranch = jest.fn(() => ({
+        branchUpgrades: {},
+        errors: [],
+        warnings: [],
+      }));
+      const res = await upgrades.branchifyUpgrades({});
+      expect(res).toEqual([]);
+    });
+    it('processes multiple branches', async () => {
+      upgrades.groupByBranch = jest.fn(() => ({
+        branchUpgrades: {
+          a: [],
+          b: [],
+        },
+        errors: [],
+        warnings: [],
+      }));
+      upgrades.generateConfig = jest.fn(() => ({}));
+      const res = await upgrades.branchifyUpgrades({});
+      expect(res).toHaveLength(2);
+    });
+  });
 });