diff --git a/lib/workers/branch/index.js b/lib/workers/branch/index.js
index c6fcf2d42f765c75de8016b1db08da22a2220076..da900af45b9ea3716a0f96055addf52b7d9f78f5 100644
--- a/lib/workers/branch/index.js
+++ b/lib/workers/branch/index.js
@@ -2,6 +2,7 @@ const handlebars = require('handlebars');
 const packageJsonHelper = require('./package-json');
 const npm = require('./npm');
 const yarn = require('./yarn');
+const schedule = require('./schedule');
 const prWorker = require('../pr');
 let logger = require('../../logger');
 
@@ -191,23 +192,22 @@ async function ensureBranch(config) {
 }
 
 async function processBranchUpgrades(branchUpgrades, errors, warnings) {
+  logger = branchUpgrades.logger || logger;
   logger.trace({ config: branchUpgrades }, 'processBranchUpgrades');
-  let createdBranch;
   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');
-  } else {
-    logger.debug('Branch has semantic commits disabled');
-    delete config.semanticPrefix;
+  // Check schedule
+  if (
+    config.schedule &&
+    config.schedule.length &&
+    schedule.isScheduledNow(config) === false
+  ) {
+    logger.info('Skipping branch as it is not scheduled');
+    return;
   }
-  // Use templates to generate strings
-  const branchName = handlebars.compile(config.branchName)(config);
-  const prTitle = handlebars.compile(config.prTitle)(config);
 
   logger = logger.child({
     repository: config.repository,
-    branch: branchName,
+    branch: config.branchName,
   });
   config.logger = logger;
 
@@ -218,14 +218,13 @@ async function processBranchUpgrades(branchUpgrades, errors, warnings) {
     if (
       // Groups and lock file maintenance should set this to true
       config.recreateClosed === false &&
-      (await config.api.checkForClosedPr(branchName, prTitle))
+      (await config.api.checkForClosedPr(config.branchName, config.prTitle))
     ) {
       logger.info(`Skipping branch as matching closed PR already existed`);
-      return null;
+      return;
     }
     const branchCreated = await module.exports.ensureBranch(config);
     if (branchCreated) {
-      createdBranch = branchName;
       const pr = await prWorker.ensurePr(
         config.upgrades,
         logger,
@@ -241,5 +240,4 @@ async function processBranchUpgrades(branchUpgrades, errors, warnings) {
     logger.debug(JSON.stringify(err));
     // Don't throw here - we don't want to stop the other renovations
   }
-  return createdBranch;
 }
diff --git a/lib/workers/package/schedule.js b/lib/workers/branch/schedule.js
similarity index 100%
rename from lib/workers/package/schedule.js
rename to lib/workers/branch/schedule.js
diff --git a/lib/workers/package-file/index.js b/lib/workers/package-file/index.js
index adddc6b59d6c35520313905ad663727653156208..baf473fe256034b12d5526ab53c182155a72eebe 100644
--- a/lib/workers/package-file/index.js
+++ b/lib/workers/package-file/index.js
@@ -1,6 +1,6 @@
+const path = require('path');
 const configParser = require('../../config');
 const depTypeWorker = require('../dep-type');
-const schedule = require('../package/schedule');
 
 let logger = require('../../logger');
 
@@ -55,16 +55,22 @@ async function findUpgrades(packageFileConfig) {
     );
   }
 
-  // Maintain lock files
-  const lockFileMaintenanceConf = Object.assign(
-    {},
-    config,
-    config.lockFileMaintenance
+  // Detect if a yarn.lock file is in use
+  const yarnLockFileName = path.join(
+    path.dirname(config.packageFile),
+    'yarn.lock'
   );
-  if (lockFileMaintenanceConf.enabled) {
-    logger.debug('lockFileMaintenance enabled');
-    lockFileMaintenanceConf.type = 'lockFileMaintenance';
-    if (schedule.isScheduledNow(lockFileMaintenanceConf)) {
+  if (await config.api.getFileContent(yarnLockFileName)) {
+    config.hasYarnLock = true;
+    // Maintain lock files
+    const lockFileMaintenanceConf = Object.assign(
+      {},
+      config,
+      config.lockFileMaintenance
+    );
+    if (lockFileMaintenanceConf.enabled) {
+      logger.debug('lockFileMaintenance enabled');
+      lockFileMaintenanceConf.type = 'lockFileMaintenance';
       logger.debug(`lock config=${JSON.stringify(lockFileMaintenanceConf)}`);
       upgrades.push(lockFileMaintenanceConf);
     }
diff --git a/lib/workers/package/index.js b/lib/workers/package/index.js
index 4411d3ed4ab7f421bd31363a66a8f48b79d09cb6..3ab2679844cf005b052daf7cf5d48871fb835ee1 100644
--- a/lib/workers/package/index.js
+++ b/lib/workers/package/index.js
@@ -1,6 +1,5 @@
 const npmApi = require('../../api/npm');
 const versions = require('./versions');
-const schedule = require('./schedule');
 const configParser = require('../../config');
 
 let logger = require('../../logger');
@@ -16,16 +15,6 @@ async function findUpgrades(config) {
     logger.debug('package is disabled');
     return [];
   }
-  // Check schedule
-  if (
-    config.repoIsOnboarded &&
-    config.schedule &&
-    config.schedule.length &&
-    schedule.isScheduledNow(config) === false
-  ) {
-    logger.debug('Skipping package as it is not scheduled');
-    return [];
-  }
   let results = [];
   const npmDep = await npmApi.getDependency(config.depName, logger);
   if (npmDep) {
diff --git a/lib/workers/repository/cleanup.js b/lib/workers/repository/cleanup.js
index bd78486b4e53d3fb5c3d304b5282e31728522290..5771c6b1f5064427f8025bb702ca0848f773b1db 100644
--- a/lib/workers/repository/cleanup.js
+++ b/lib/workers/repository/cleanup.js
@@ -2,64 +2,29 @@ module.exports = {
   pruneStaleBranches,
 };
 
-async function pruneStaleBranches(config, branchUpgradeNames) {
+async function pruneStaleBranches(config, branchList) {
   const logger = config.logger;
   logger.debug('Removing any stale branches');
   logger.trace(
     { config },
-    `pruneStaleBranches:\n${JSON.stringify(branchUpgradeNames)}`
+    `pruneStaleBranches:\n${JSON.stringify(branchList)}`
   );
   if (config.platform !== 'github') {
     logger.debug('Platform is not GitHub - returning');
     return;
   }
-  if (branchUpgradeNames.length === 0) {
-    logger.debug('No branchUpgradeNames - returning');
-    return;
-  }
   const renovateBranches = await config.api.getAllRenovateBranches();
   logger.debug(`renovateBranches=${renovateBranches}`);
   const remainingBranches = renovateBranches.filter(
-    branch => branchUpgradeNames.indexOf(branch) === -1
+    branch => branchList.indexOf(branch) === -1
   );
   logger.debug(`remainingBranches=${remainingBranches}`);
   if (remainingBranches.length === 0) {
     logger.debug('No branches to clean up');
     return;
   }
-  const allPrs = await config.api.getAllPrs();
   for (const branchName of remainingBranches) {
-    logger.debug({ branch: branchName }, `Checking orphan branch for deletion`);
-    // Default to deleting the branch if we don't find a PR
-    let deleteBranch = true;
-    let foundPr = false;
-    for (const pr of allPrs) {
-      if (pr.state === 'open' && pr.branchName === branchName) {
-        // We have a matching PR
-        foundPr = true;
-        logger.debug({ branch: branchName }, `Found matching PR#${pr.number}`);
-        const prDetails = config.api.getPr(pr.number);
-        if (prDetails.mergeable) {
-          // Don't delete the branch if we found a mergeable PR
-          logger.debug(
-            { branch: branchName },
-            'PR is mergeable, so do not delete'
-          );
-          deleteBranch = false;
-        } else {
-          logger.debug(
-            { branch: branchName },
-            'PR is not mergeable, we will delete'
-          );
-        }
-      }
-    }
-    if (deleteBranch) {
-      if (!foundPr) {
-        logger.debug({ branch: branchName }, 'Orphan branch has no PR');
-      }
-      logger.info({ branch: branchName }, `Deleting orphan branch`);
-      await config.api.deleteBranch(branchName);
-    }
+    logger.debug({ branch: branchName }, `Deleting orphan branch`);
+    await config.api.deleteBranch(branchName);
   }
 }
diff --git a/lib/workers/repository/index.js b/lib/workers/repository/index.js
index 10d73db1df146fd27ad0b8c6de8a5358681124eb..983a634d075b884b6969cb02885600c124d4e04e 100644
--- a/lib/workers/repository/index.js
+++ b/lib/workers/repository/index.js
@@ -78,17 +78,15 @@ async function renovateRepository(packageFileConfig) {
     config.logger.debug(`Updating ${branchUpgrades.length} branch(es)`);
     config.logger.trace({ config: branchUpgrades }, 'branchUpgrades');
     if (config.repoIsOnboarded) {
-      const branchList = [];
       for (const branchUpgrade of branchUpgrades) {
-        const createdBranchName = await branchWorker.processBranchUpgrades(
+        await branchWorker.processBranchUpgrades(
           branchUpgrade,
           config.errors,
           config.warnings
         );
-        if (createdBranchName) {
-          branchList.push(createdBranchName);
-        }
       }
+      const branchList = branchUpgrades.map(upgrade => upgrade.branchName);
+      config.logger.debug(`branchList=${branchList}`);
       await cleanup.pruneStaleBranches(config, branchList);
     } else {
       await onboarding.ensurePr(config, branchUpgrades);
diff --git a/lib/workers/repository/onboarding.js b/lib/workers/repository/onboarding.js
index 28a483de06b60fb20a205bf177d485e7296b01e5..96017a13475d55144e0d5970a4ab8e43e21bb232 100644
--- a/lib/workers/repository/onboarding.js
+++ b/lib/workers/repository/onboarding.js
@@ -1,4 +1,3 @@
-const handlebars = require('handlebars');
 const stringify = require('json-stringify-pretty-compact');
 
 const configParser = require('../../config');
@@ -95,21 +94,24 @@ With your current configuration, renovate will initially create the following Pu
 | ------ |
 `;
   branchUpgrades.forEach(branch => {
-    const branchName = handlebars.compile(branch.branchName)(branch);
-    const prTitle = handlebars.compile(branch.prTitle)(branch);
-    prDesc += `| **${prTitle}**<ul>`;
+    prDesc += `| **${branch.prTitle}**<ul>`;
     if (branch.schedule && branch.schedule.length) {
       prDesc += `<li>Schedule: ${JSON.stringify(branch.schedule)}</li>`;
     }
-    prDesc += `<li>Branch name: \`${branchName}\`</li>`;
+    prDesc += `<li>Branch name: \`${branch.branchName}\`</li>`;
     branch.upgrades.forEach(upgrade => {
-      if (upgrade.isPin) {
-        prDesc += '<li>Pins ';
+      if (upgrade.type === 'lockFileMaintenance') {
+        prDesc +=
+          '<li>Regenerates `yarn.lock` file to use latest dependency versions</li>';
       } else {
-        prDesc += '<li>Upgrades ';
+        if (upgrade.isPin) {
+          prDesc += '<li>Pins ';
+        } else {
+          prDesc += '<li>Upgrades ';
+        }
+        prDesc += `[${upgrade.depName}](${upgrade.repositoryUrl}) in \`${upgrade.depType}\` from \`${upgrade.currentVersion}\` to \`${upgrade.newVersion}\``;
+        prDesc += '</li>';
       }
-      prDesc += `[${upgrade.depName}](${upgrade.repositoryUrl}) in \`${upgrade.depType}\` from \`${upgrade.currentVersion}\` to \`${upgrade.newVersion}\``;
-      prDesc += '</li>';
     });
     prDesc += '</ul> |\n';
   });
diff --git a/lib/workers/repository/upgrades.js b/lib/workers/repository/upgrades.js
index abb416efec8a99a57fe90146a4a144a2d9e5e2d5..c258102f69454b0816087f24615f91db49d7435b 100644
--- a/lib/workers/repository/upgrades.js
+++ b/lib/workers/repository/upgrades.js
@@ -54,6 +54,18 @@ function generateConfig(branchUpgrades) {
     // Delete group config regardless of whether it was applied
     delete upgrade.group;
     delete upgrade.lazyGrouping;
+    // Delete the semanticPrefix for this upgrade if not enabled
+    if (upgrade.semanticCommits) {
+      logger.debug('Upgrade has semantic commits enabled');
+    } else {
+      logger.debug('Upgrade has semantic commits disabled');
+      delete upgrade.semanticPrefix;
+    }
+    // Use templates to generate strings
+    logger.debug('Compiling branchName and prTitle');
+    upgrade.branchName = handlebars.compile(upgrade.branchName)(upgrade);
+    upgrade.prTitle = handlebars.compile(upgrade.prTitle)(upgrade);
+    logger.debug(`${upgrade.branchName}, ${upgrade.prTitle}`);
     config.upgrades.push(upgrade);
   }
   // Now assign first upgrade's config as branch config
@@ -61,7 +73,7 @@ function generateConfig(branchUpgrades) {
 }
 
 function groupByBranch(upgrades) {
-  logger.trace({ config: upgrades }, 'groupUpgrades');
+  logger.trace({ config: upgrades }, 'groupByBranch');
   logger.info(`Processing ${upgrades.length} dependency upgrade(s)`);
   const result = {
     errors: [],
@@ -115,6 +127,7 @@ async function branchifyUpgrades(upgrades, parentLogger) {
     logger = logger.child({ branch: branchName });
     const branchUpgrades = res.branchUpgrades[branchName];
     const branchConfig = module.exports.generateConfig(branchUpgrades);
+    branchConfig.branchName = branchName;
     branchConfig.logger = logger;
     branchConfigs.push(branchConfig);
   }
diff --git a/test/workers/branch/index.spec.js b/test/workers/branch/index.spec.js
index c68af96f72688bd68dcb4270d43c3f1980fc776c..6fb49994fe53b03ab3c9bc2968444035d9f8acab 100644
--- a/test/workers/branch/index.spec.js
+++ b/test/workers/branch/index.spec.js
@@ -1,5 +1,6 @@
 const branchWorker = require('../../../lib/workers/branch');
 const prWorker = require('../../../lib/workers/pr');
+const schedule = require('../../../lib/workers/branch/schedule');
 const npm = require('../../../lib/workers/branch/npm');
 const yarn = require('../../../lib/workers/branch/yarn');
 const defaultConfig = require('../../../lib/config/defaults').getConfig();
@@ -15,6 +16,7 @@ describe('workers/branch', () => {
     let config;
     const branchName = 'foo';
     beforeEach(() => {
+      schedule.isScheduledNow = jest.fn();
       config = {
         api: {
           branchExists: jest.fn(() => true),
@@ -333,6 +335,12 @@ describe('workers/branch', () => {
       prWorker.ensurePr = jest.fn(() => true);
       config.upgrades = [{ depName: 'a' }];
     });
+    it('skips branch if not scheduled', async () => {
+      config.schedule = ['some-schedule'];
+      schedule.isScheduledNow.mockReturnValueOnce(false);
+      await branchWorker.processBranchUpgrades(config);
+      expect(branchWorker.ensureBranch.mock.calls.length).toBe(0);
+    });
     it('returns immediately if closed PR found', async () => {
       config.api.checkForClosedPr.mockReturnValue(true);
       await branchWorker.processBranchUpgrades(config);
diff --git a/test/workers/package/schedule.spec.js b/test/workers/branch/schedule.spec.js
similarity index 97%
rename from test/workers/package/schedule.spec.js
rename to test/workers/branch/schedule.spec.js
index 1e09b482d29a9cded251ec75cac8c66e7a400e56..742a72cb229686fae4af5ee780e5c3952a4629f1 100644
--- a/test/workers/package/schedule.spec.js
+++ b/test/workers/branch/schedule.spec.js
@@ -1,8 +1,8 @@
 const mockDate = require('mockdate');
-const schedule = require('../../../lib/workers/package/schedule');
+const schedule = require('../../../lib/workers/branch/schedule');
 const logger = require('../../_fixtures/logger');
 
-describe('workers/package/schedule', () => {
+describe('workers/branch/schedule', () => {
   describe('hasValidSchedule(schedule)', () => {
     beforeEach(() => {
       jest.resetAllMocks();
diff --git a/test/workers/package-file/index.spec.js b/test/workers/package-file/index.spec.js
index 5e85b27d1175f836f7d42200f785726ca71e2de1..47513f2fdcd6d0ccc56388b3cfa84a9312907bf4 100644
--- a/test/workers/package-file/index.spec.js
+++ b/test/workers/package-file/index.spec.js
@@ -1,20 +1,21 @@
 const packageFileWorker = require('../../../lib/workers/package-file');
 const depTypeWorker = require('../../../lib/workers/dep-type');
-const schedule = require('../../../lib/workers/package/schedule');
 const defaultConfig = require('../../../lib/config/defaults').getConfig();
 
 const logger = require('../../_fixtures/logger');
 
 jest.mock('../../../lib/workers/dep-type');
-jest.mock('../../../lib/workers/package/schedule');
+jest.mock('../../../lib/workers/branch/schedule');
 
 describe('packageFileWorker', () => {
   describe('findUpgrades(config)', () => {
     let config;
     beforeEach(() => {
       config = Object.assign({}, defaultConfig, {
+        packageFile: 'package.json',
         repoIsOnboarded: true,
         api: {
+          getFileContent: jest.fn(),
           getFileJson: jest.fn(),
         },
         depTypes: ['dependencies', 'devDependencies'],
@@ -62,17 +63,11 @@ describe('packageFileWorker', () => {
     });
     it('maintains yarn.lock', async () => {
       config.api.getFileJson.mockReturnValueOnce({});
-      depTypeWorker.findUpgrades.mockReturnValue([]);
-      schedule.isScheduledNow.mockReturnValueOnce(true);
+      config.api.getFileContent.mockReturnValueOnce('some-content');
+      depTypeWorker.findUpgrades.mockReturnValueOnce([]);
+      depTypeWorker.findUpgrades.mockReturnValueOnce([]);
       const res = await packageFileWorker.findUpgrades(config);
       expect(res).toHaveLength(1);
     });
-    it('skips yarn.lock', async () => {
-      config.api.getFileJson.mockReturnValueOnce({});
-      depTypeWorker.findUpgrades.mockReturnValue([]);
-      schedule.isScheduledNow.mockReturnValueOnce(false);
-      const res = await packageFileWorker.findUpgrades(config);
-      expect(res).toHaveLength(0);
-    });
   });
 });
diff --git a/test/workers/package/index.spec.js b/test/workers/package/index.spec.js
index 164e3250513b7ddf3561f97eacc7fefac1a453a8..01596fdf12c0f7f29975c42ea863e732cf564386 100644
--- a/test/workers/package/index.spec.js
+++ b/test/workers/package/index.spec.js
@@ -1,11 +1,10 @@
 const npmApi = require('../../../lib/api/npm');
-const schedule = require('../../../lib/workers/package/schedule');
 const versions = require('../../../lib/workers/package/versions');
 const pkgWorker = require('../../../lib/workers/package/index');
 const defaultConfig = require('../../../lib/config/defaults').getConfig();
 const configParser = require('../../../lib/config');
 
-jest.mock('../../../lib/workers/package/schedule');
+jest.mock('../../../lib/workers/branch/schedule');
 jest.mock('../../../lib/workers/package/versions');
 jest.mock('../../../lib/api/npm');
 
@@ -21,18 +20,9 @@ describe('lib/workers/package/index', () => {
       const res = await pkgWorker.findUpgrades(config);
       expect(res).toMatchObject([]);
     });
-    it('returns empty if package is not scheduled', async () => {
-      config.repoIsOnboarded = true;
-      config.schedule = 'some schedule';
-      schedule.isScheduledNow.mockReturnValueOnce(false);
-      const res = await pkgWorker.findUpgrades(config);
-      expect(res).toMatchObject([]);
-      expect(npmApi.getDependency.mock.calls.length).toBe(0);
-    });
     it('returns error if no npm dep found', async () => {
       config.repoIsOnboarded = true;
       config.schedule = 'some schedule';
-      schedule.isScheduledNow.mockReturnValueOnce(true);
       const res = await pkgWorker.findUpgrades(config);
       expect(res).toHaveLength(1);
       expect(res[0].type).toEqual('error');
diff --git a/test/workers/repository/__snapshots__/onboarding.spec.js.snap b/test/workers/repository/__snapshots__/onboarding.spec.js.snap
index 3e4e295b1ebd8fd1f8c99406931a0ee1dbe34a6a..bbe4ded354aa31f50bdbdb75a392755bfb0f25b2 100644
--- a/test/workers/repository/__snapshots__/onboarding.spec.js.snap
+++ b/test/workers/repository/__snapshots__/onboarding.spec.js.snap
@@ -149,6 +149,44 @@ With your current configuration, renovate will initially create the following Pu
 | **Pin a**<ul><li>Branch name: \`branch-a\`</li><li>Pins [a](https://a) in \`undefined\` from \`^1.0.0\` to \`1.1.0\`</li><li>Upgrades [b](https://b) in \`undefined\` from \`1.0.0\` to \`2.0.0\`</li></ul> |
 
 
+Would you like to change this? Simply edit the \`renovate.json\` in this branch and Renovate will update this Pull Request description the next time it runs.
+
+The [Configuration](https://github.com/singapore/renovate/blob/master/docs/configuration.md) and [Configuration FAQ](https://github.com/singapore/renovate/blob/master/docs/faq.md) documents should be helpful if you wish to modify this behaviour.
+
+---
+
+#### Important!
+
+You do not need to *merge* this Pull Request - renovate will begin even if it's closed *unmerged*.
+In fact, you only need to add a \`renovate.json\` file to your repository if you wish to override any default settings. The file is included as part of this PR only in case you wish to change default settings before you start.
+
+Alternatively, you can add the same configuration settings into a \\"renovate\\" section of \`package.json\`, which might be more convenient if you have only one.
+
+If the default settings are all suitable for you, simply close this Pull Request unmerged and your first renovation will begin the next time the program is run.
+",
+  ],
+]
+`;
+
+exports[`lib/workers/repository/onboarding ensurePr(config, branchUpgrades) maintains yarn.lock 1`] = `
+Array [
+  Array [
+    "renovate/configure",
+    "Configure Renovate",
+    "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.
+
+---
+
+
+With your current configuration, renovate will initially create the following Pull Requests:
+
+| Pull Requests (1) |
+| ------ |
+| **Lock File Maintenance**<ul><li>Schedule: \\"before 5am on monday\\"</li><li>Branch name: \`renovate/lock-files\`</li><li>Regenerates \`yarn.lock\` file to use latest dependency versions</li></ul> |
+
+
 Would you like to change this? Simply edit the \`renovate.json\` in this branch and Renovate will update this Pull Request description the next time it runs.
 
 The [Configuration](https://github.com/singapore/renovate/blob/master/docs/configuration.md) and [Configuration FAQ](https://github.com/singapore/renovate/blob/master/docs/faq.md) documents should be helpful if you wish to modify this behaviour.
diff --git a/test/workers/repository/__snapshots__/upgrades.spec.js.snap b/test/workers/repository/__snapshots__/upgrades.spec.js.snap
index 87019805872d65c06848816027359b1dbaaf1d75..b76c0d02a9de342458b45830b04de5bd97444ba4 100644
--- a/test/workers/repository/__snapshots__/upgrades.spec.js.snap
+++ b/test/workers/repository/__snapshots__/upgrades.spec.js.snap
@@ -2,12 +2,18 @@
 
 exports[`workers/repository/upgrades generateConfig(branchUpgrades) does not group single upgrade 1`] = `
 Object {
+  "branchName": "some-branch",
   "depName": "some-dep",
   "foo": 1,
+  "prTitle": "some-title",
+  "semanticCommits": true,
   "upgrades": Array [
     Object {
+      "branchName": "some-branch",
       "depName": "some-dep",
       "foo": 1,
+      "prTitle": "some-title",
+      "semanticCommits": true,
     },
   ],
 }
@@ -15,14 +21,18 @@ Object {
 
 exports[`workers/repository/upgrades generateConfig(branchUpgrades) groups single upgrade if not lazyGrouping 1`] = `
 Object {
+  "branchName": "some-branch",
   "depName": "some-dep",
   "foo": 2,
   "groupName": "some-group",
+  "prTitle": "some-title",
   "upgrades": Array [
     Object {
+      "branchName": "some-branch",
       "depName": "some-dep",
       "foo": 2,
       "groupName": "some-group",
+      "prTitle": "some-title",
     },
   ],
 }
@@ -34,18 +44,21 @@ Object {
     "bar-1.1.0": Array [
       Object {
         "branchName": "bar-{{version}}",
+        "prTitle": "some-title",
         "version": "1.1.0",
       },
     ],
     "foo-1.1.0": Array [
       Object {
         "branchName": "foo-{{version}}",
+        "prTitle": "some-title",
         "version": "1.1.0",
       },
     ],
     "foo-2.0.0": Array [
       Object {
         "branchName": "foo-{{version}}",
+        "prTitle": "some-title",
         "version": "2.0.0",
       },
     ],
@@ -61,16 +74,19 @@ Object {
     "bar-1.1.0": Array [
       Object {
         "branchName": "bar-{{version}}",
+        "prTitle": "some-title",
         "version": "1.1.0",
       },
     ],
     "foo": Array [
       Object {
         "branchName": "foo",
+        "prTitle": "some-title",
         "version": "2.0.0",
       },
       Object {
         "branchName": "foo",
+        "prTitle": "some-title",
         "version": "1.1.0",
       },
     ],
@@ -86,6 +102,7 @@ Object {
     "foo": Array [
       Object {
         "branchName": "foo",
+        "prTitle": "some-title",
         "version": "2.0.0",
       },
     ],
@@ -97,6 +114,7 @@ Object {
         },
         "groupName": "My Group",
         "groupSlug": "my-group",
+        "prTitle": "some-title",
         "version": "1.1.0",
       },
       Object {
@@ -106,6 +124,7 @@ Object {
         },
         "groupName": "My Group",
         "groupSlug": "my-group",
+        "prTitle": "some-title",
         "version": "1.1.0",
       },
     ],
@@ -121,12 +140,14 @@ Object {
     "bar-1.1.0": Array [
       Object {
         "branchName": "bar-{{version}}",
+        "prTitle": "some-title",
         "version": "1.1.0",
       },
     ],
     "foo-1.1.0": Array [
       Object {
         "branchName": "foo-{{version}}",
+        "prTitle": "some-title",
         "version": "1.1.0",
       },
     ],
@@ -139,6 +160,7 @@ Object {
   "warnings": Array [
     Object {
       "branchName": "foo-{{version}}",
+      "prTitle": "some-title",
       "type": "warning",
       "version": "2.0.0",
     },
@@ -160,6 +182,7 @@ Object {
     "foo-1.1.0": Array [
       Object {
         "branchName": "foo-{{version}}",
+        "prTitle": "some-title",
         "version": "1.1.0",
       },
     ],
@@ -171,19 +194,25 @@ Object {
 
 exports[`workers/repository/upgrades groups multiple upgrades 1`] = `
 Object {
+  "branchName": "some-branch",
   "depName": "some-dep",
   "foo": 2,
   "groupName": "some-group",
+  "prTitle": "some-title",
   "upgrades": Array [
     Object {
+      "branchName": "some-branch",
       "depName": "some-dep",
       "foo": 2,
       "groupName": "some-group",
+      "prTitle": "some-title",
     },
     Object {
+      "branchName": "some-branch",
       "depName": "some-other-dep",
       "foo": 2,
       "groupName": "some-group",
+      "prTitle": "some-title",
     },
   ],
 }
diff --git a/test/workers/repository/cleanup.spec.js b/test/workers/repository/cleanup.spec.js
index 492e58b7ba0f87101ff65b1547afea56a64209f3..bf711aa34a36f150d5ab09dea1ce930622ae031c 100644
--- a/test/workers/repository/cleanup.spec.js
+++ b/test/workers/repository/cleanup.spec.js
@@ -22,10 +22,6 @@ describe('workers/repository/cleanup', () => {
       await cleanup.pruneStaleBranches(config, branchNames);
       expect(config.api.getAllRenovateBranches.mock.calls).toHaveLength(0);
     });
-    it('returns if no branch names', async () => {
-      await cleanup.pruneStaleBranches(config, branchNames);
-      expect(config.api.getAllRenovateBranches.mock.calls).toHaveLength(0);
-    });
     it('returns if no remaining branches', async () => {
       branchNames = ['renovate/a', 'renovate/b'];
       config.api.getAllRenovateBranches.mockReturnValueOnce(branchNames);
@@ -33,52 +29,13 @@ describe('workers/repository/cleanup', () => {
       expect(config.api.getAllRenovateBranches.mock.calls).toHaveLength(1);
       expect(config.api.getAllPrs.mock.calls).toHaveLength(0);
     });
-    it('returns if remaining branch has mergeable PR', async () => {
-      branchNames = ['renovate/a', 'renovate/b'];
-      config.api.getAllRenovateBranches.mockReturnValueOnce(
-        branchNames.concat(['renovate/c'])
-      );
-      config.api.getAllPrs.mockReturnValueOnce([
-        { number: 4, state: 'open', branchName: 'test-a' },
-        { number: 5, state: 'open', branchName: 'renovate/c' },
-      ]);
-      config.api.getPr.mockReturnValueOnce({ mergeable: true });
-      await cleanup.pruneStaleBranches(config, branchNames);
-      expect(config.api.getAllRenovateBranches.mock.calls).toHaveLength(1);
-      expect(config.api.getAllPrs.mock.calls).toHaveLength(1);
-      expect(config.api.getPr.mock.calls).toHaveLength(1);
-      expect(config.api.deleteBranch.mock.calls).toHaveLength(0);
-    });
-    it('deletes if remaining branch has non-mergeable PR', async () => {
-      branchNames = ['renovate/a', 'renovate/b'];
-      config.api.getAllRenovateBranches.mockReturnValueOnce(
-        branchNames.concat(['renovate/c'])
-      );
-      config.api.getAllPrs.mockReturnValueOnce([
-        { number: 4, state: 'open', branchName: 'test-a' },
-        { number: 5, state: 'open', branchName: 'renovate/c' },
-      ]);
-      config.api.getPr.mockReturnValueOnce({ mergeable: false });
-      await cleanup.pruneStaleBranches(config, branchNames);
-      expect(config.api.getAllRenovateBranches.mock.calls).toHaveLength(1);
-      expect(config.api.getAllPrs.mock.calls).toHaveLength(1);
-      expect(config.api.getPr.mock.calls).toHaveLength(1);
-      expect(config.api.deleteBranch.mock.calls).toHaveLength(1);
-    });
-    it('deletes if no matching PR', async () => {
+    it('deletes remaining branch', async () => {
       branchNames = ['renovate/a', 'renovate/b'];
       config.api.getAllRenovateBranches.mockReturnValueOnce(
         branchNames.concat(['renovate/c'])
       );
-      config.api.getAllPrs.mockReturnValueOnce([
-        { number: 4, state: 'open', branchName: 'test-a' },
-        { number: 5, state: 'open', branchName: 'renovate/a' },
-      ]);
-      config.api.getPr.mockReturnValueOnce({ mergeable: false });
       await cleanup.pruneStaleBranches(config, branchNames);
       expect(config.api.getAllRenovateBranches.mock.calls).toHaveLength(1);
-      expect(config.api.getAllPrs.mock.calls).toHaveLength(1);
-      expect(config.api.getPr.mock.calls).toHaveLength(0);
       expect(config.api.deleteBranch.mock.calls).toHaveLength(1);
     });
   });
diff --git a/test/workers/repository/onboarding.spec.js b/test/workers/repository/onboarding.spec.js
index a3653dbbd459481af4a904b14311b82d28206eb5..3d64d5a9f1c53c5190648e4c8083d82c8b03d402 100644
--- a/test/workers/repository/onboarding.spec.js
+++ b/test/workers/repository/onboarding.spec.js
@@ -98,6 +98,24 @@ If the default settings are all suitable for you, simply close this Pull Request
       expect(config.api.updatePr.mock.calls.length).toBe(0);
       expect(config.api.createPr.mock.calls).toMatchSnapshot();
     });
+    it('maintains yarn.lock', async () => {
+      branchUpgrades = [
+        {
+          branchName: 'renovate/lock-files',
+          prTitle: 'Lock File Maintenance',
+          schedule: 'before 5am on monday',
+          upgrades: [
+            {
+              type: 'lockFileMaintenance',
+            },
+          ],
+        },
+      ];
+      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 = [
         {
diff --git a/test/workers/repository/upgrades.spec.js b/test/workers/repository/upgrades.spec.js
index 4dfe450eaae3d6258595c8f087cf817eb163b55c..cf8579582d2acf10f0266952dc5386bf4a79b750 100644
--- a/test/workers/repository/upgrades.spec.js
+++ b/test/workers/repository/upgrades.spec.js
@@ -50,6 +50,9 @@ describe('workers/repository/upgrades', () => {
         {
           depName: 'some-dep',
           groupName: 'some-group',
+          branchName: 'some-branch',
+          prTitle: 'some-title',
+          semanticCommits: true,
           lazyGrouping: true,
           foo: 1,
           group: {
@@ -67,6 +70,8 @@ describe('workers/repository/upgrades', () => {
         {
           depName: 'some-dep',
           groupName: 'some-group',
+          branchName: 'some-branch',
+          prTitle: 'some-title',
           lazyGrouping: false,
           foo: 1,
           group: {
@@ -85,6 +90,8 @@ describe('workers/repository/upgrades', () => {
       {
         depName: 'some-dep',
         groupName: 'some-group',
+        branchName: 'some-branch',
+        prTitle: 'some-title',
         lazyGrouping: true,
         foo: 1,
         group: {
@@ -94,6 +101,8 @@ describe('workers/repository/upgrades', () => {
       {
         depName: 'some-other-dep',
         groupName: 'some-group',
+        branchName: 'some-branch',
+        prTitle: 'some-title',
         lazyGrouping: true,
         foo: 1,
         group: {
@@ -116,6 +125,7 @@ describe('workers/repository/upgrades', () => {
         {
           branchName: 'foo-{{version}}',
           version: '1.1.0',
+          prTitle: 'some-title',
         },
       ];
       const res = await upgrades.groupByBranch(input);
@@ -127,14 +137,17 @@ describe('workers/repository/upgrades', () => {
         {
           branchName: 'foo-{{version}}',
           version: '1.1.0',
+          prTitle: 'some-title',
         },
         {
           branchName: 'foo-{{version}}',
           version: '2.0.0',
+          prTitle: 'some-title',
         },
         {
           branchName: 'bar-{{version}}',
           version: '1.1.0',
+          prTitle: 'some-title',
         },
       ];
       const res = await upgrades.groupByBranch(input);
@@ -146,14 +159,17 @@ describe('workers/repository/upgrades', () => {
         {
           branchName: 'foo',
           version: '1.1.0',
+          prTitle: 'some-title',
         },
         {
           branchName: 'foo',
           version: '2.0.0',
+          prTitle: 'some-title',
         },
         {
           branchName: 'bar-{{version}}',
           version: '1.1.0',
+          prTitle: 'some-title',
         },
       ];
       const res = await upgrades.groupByBranch(input);
@@ -164,16 +180,19 @@ describe('workers/repository/upgrades', () => {
       const input = [
         {
           branchName: 'foo',
+          prTitle: 'some-title',
           version: '1.1.0',
           groupName: 'My Group',
           group: { branchName: 'renovate/{{groupSlug}}' },
         },
         {
           branchName: 'foo',
+          prTitle: 'some-title',
           version: '2.0.0',
         },
         {
           branchName: 'bar-{{version}}',
+          prTitle: 'some-title',
           version: '1.1.0',
           groupName: 'My Group',
           group: { branchName: 'renovate/my-group' },
@@ -190,15 +209,18 @@ describe('workers/repository/upgrades', () => {
         },
         {
           branchName: 'foo-{{version}}',
+          prTitle: 'some-title',
           version: '1.1.0',
         },
         {
           type: 'warning',
           branchName: 'foo-{{version}}',
+          prTitle: 'some-title',
           version: '2.0.0',
         },
         {
           branchName: 'bar-{{version}}',
+          prTitle: 'some-title',
           version: '1.1.0',
         },
       ];