diff --git a/lib/api/github.js b/lib/api/github.js
index 3596cfb3f1944b7ea1e57c4afa30bdeb93d7c29b..d2f82df4b5cf8999b00675c04d42ddae8845ab17 100644
--- a/lib/api/github.js
+++ b/lib/api/github.js
@@ -1,4 +1,4 @@
-let logger = require('../helpers/logger');
+let logger = require('../logger');
 const ghGot = require('gh-got');
 
 const config = {};
diff --git a/lib/api/gitlab.js b/lib/api/gitlab.js
index f4bc93052aa96c096e7c27ff0fa814c5ac24acf1..2c539ca0b378b2b9c0e9c31f99e1d72137c93d9e 100644
--- a/lib/api/gitlab.js
+++ b/lib/api/gitlab.js
@@ -1,4 +1,4 @@
-let logger = require('../helpers/logger');
+let logger = require('../logger');
 const glGot = require('gl-got');
 
 const config = {};
diff --git a/lib/config/file.js b/lib/config/file.js
index 066a2847ac69cbad41fa48fefdfd5d9f951432ff..d844daa09992ee106d67b6026107482b1e97a9fb 100644
--- a/lib/config/file.js
+++ b/lib/config/file.js
@@ -1,4 +1,4 @@
-const logger = require('../helpers/logger');
+const logger = require('../logger');
 const path = require('path');
 
 module.exports = {
diff --git a/lib/helpers/github-app.js b/lib/config/github-app.js
similarity index 86%
rename from lib/helpers/github-app.js
rename to lib/config/github-app.js
index aedfa32110f168f3dd1166ac192828557fc8ede0..343046f3fb15e3c78b87a1dee855a4e5323c713b 100644
--- a/lib/helpers/github-app.js
+++ b/lib/config/github-app.js
@@ -1,5 +1,5 @@
 const jwt = require('jsonwebtoken');
-const logger = require('../helpers/logger');
+const logger = require('../logger');
 const ghApi = require('../api/github');
 
 module.exports = {
@@ -9,7 +9,7 @@ module.exports = {
 };
 
 function generateJwt(appId, pemFileContent) {
-  logger.debug(`githubAppHelper.generateJwt(${appId})`);
+  logger.debug(`githubApp.generateJwt(${appId})`);
   const payload = {
     // GitHub app identifier
     iss: appId,
@@ -24,9 +24,7 @@ function generateJwt(appId, pemFileContent) {
 }
 
 async function getUserRepositories(appToken, installationId) {
-  logger.debug(
-    `githubAppHelper.getUserRepositories(appToken, ${installationId})`
-  );
+  logger.debug(`githubApp.getUserRepositories(appToken, ${installationId})`);
   const userToken = await ghApi.getInstallationToken(appToken, installationId);
   logger.debug(`userToken=${userToken}`);
   const userRepositories = await ghApi.getInstallationRepositories(userToken);
@@ -38,7 +36,7 @@ async function getUserRepositories(appToken, installationId) {
 }
 
 async function getRepositories(config) {
-  logger.debug(`githubAppHelper.getRepositories`);
+  logger.debug(`githubApp.getRepositories`);
   const configuredRepositories = config.repositories.map(
     repository =>
       typeof repository === 'string' ? repository : repository.repository
@@ -67,9 +65,7 @@ async function getRepositories(config) {
       installedRepos = installedRepos.concat(installationRepos);
     }
   } catch (err) {
-    logger.error(
-      `githubAppHelper.getRepositories error: ${JSON.stringify(err)}`
-    );
+    logger.error(`githubApp.getRepositories error: ${JSON.stringify(err)}`);
   }
   logger.debug(`installedRepos=${JSON.stringify(installedRepos)}`);
   return installedRepos;
diff --git a/lib/config/index.js b/lib/config/index.js
index dc8c3368a5194502a9e388f3548f6b57df092203..cf1ed9312d04aa73c0d3c2454e93db5f279c175d 100644
--- a/lib/config/index.js
+++ b/lib/config/index.js
@@ -1,4 +1,4 @@
-const logger = require('../helpers/logger');
+const logger = require('../logger');
 const githubApi = require('../api/github');
 const gitlabApi = require('../api/gitlab');
 
@@ -9,7 +9,7 @@ const fileParser = require('./file');
 const cliParser = require('./cli');
 const envParser = require('./env');
 
-const githubAppHelper = require('../helpers/github-app');
+const githubApp = require('./github-app');
 
 module.exports = {
   parseConfigs,
@@ -76,7 +76,7 @@ async function parseConfigs(env, argv) {
     if (!config.githubAppKey) {
       throw new Error('A GitHub App Private Key must be provided');
     }
-    config.repositories = await githubAppHelper.getRepositories(config);
+    config.repositories = await githubApp.getRepositories(config);
     logger.info(`Found ${config.repositories.length} repositories installed`);
     logger.debug({ config }, 'GitHub App config');
   } else if (config.autodiscover) {
diff --git a/lib/helpers/platform.js b/lib/helpers/platform.js
deleted file mode 100644
index 2d629b9e78cf593c934bd03bcd3197cb7ef2c1ee..0000000000000000000000000000000000000000
--- a/lib/helpers/platform.js
+++ /dev/null
@@ -1,16 +0,0 @@
-const githubApi = require('../api/github');
-const gitlabApi = require('../api/gitlab');
-
-module.exports = {
-  // TODO: Centralise platform-specific functions here (e.g. wording)
-  getApi,
-};
-
-function getApi(platform) {
-  if (platform === 'github') {
-    return githubApi;
-  } else if (platform === 'gitlab') {
-    return gitlabApi;
-  }
-  throw new Error(`Unknown platform: ${platform}`);
-}
diff --git a/lib/helpers/logger/config-serializer.js b/lib/logger/config-serializer.js
similarity index 100%
rename from lib/helpers/logger/config-serializer.js
rename to lib/logger/config-serializer.js
diff --git a/lib/helpers/logger/index.js b/lib/logger/index.js
similarity index 100%
rename from lib/helpers/logger/index.js
rename to lib/logger/index.js
diff --git a/lib/helpers/logger/pretty-stdout.js b/lib/logger/pretty-stdout.js
similarity index 100%
rename from lib/helpers/logger/pretty-stdout.js
rename to lib/logger/pretty-stdout.js
diff --git a/lib/workers/branch.js b/lib/workers/branch/index.js
similarity index 94%
rename from lib/workers/branch.js
rename to lib/workers/branch/index.js
index 6f1f5a270146673d21064c2ac8c2d309a6621412..dcb5f611ab9355fba09926462790231ade6ede6b 100644
--- a/lib/workers/branch.js
+++ b/lib/workers/branch/index.js
@@ -1,9 +1,9 @@
 const handlebars = require('handlebars');
-const packageJsonHelper = require('../helpers/package-json');
-const npmHelper = require('../helpers/npm');
-const yarnHelper = require('../helpers/yarn');
-const prWorker = require('./pr');
-let logger = require('../helpers/logger');
+const packageJsonHelper = require('./package-json');
+const npm = require('./npm');
+const yarn = require('./yarn');
+const prWorker = require('../pr');
+let logger = require('../../logger');
 
 module.exports = {
   getParentBranch,
@@ -79,7 +79,7 @@ async function ensureBranch(upgrades) {
   for (const upgrade of upgrades) {
     if (upgrade.upgradeType === 'maintainYarnLock') {
       try {
-        const newYarnLock = await yarnHelper.maintainLockFile(upgrade);
+        const newYarnLock = await yarn.maintainLockFile(upgrade);
         if (newYarnLock) {
           commitFiles.push(newYarnLock);
         }
@@ -123,7 +123,7 @@ async function ensureBranch(upgrades) {
         contents: packageFiles[packageFile],
       });
       try {
-        const yarnLockFile = await yarnHelper.getLockFile(
+        const yarnLockFile = await yarn.getLockFile(
           packageFile,
           packageFiles[packageFile],
           api,
@@ -135,7 +135,7 @@ async function ensureBranch(upgrades) {
           logger.info(`Adding ${yarnLockFile.name}`);
           commitFiles.push(yarnLockFile);
         }
-        const packageLockFile = await npmHelper.getLockFile(
+        const packageLockFile = await npm.getLockFile(
           packageFile,
           packageFiles[packageFile],
           api,
diff --git a/lib/helpers/npm.js b/lib/workers/branch/npm.js
similarity index 98%
rename from lib/helpers/npm.js
rename to lib/workers/branch/npm.js
index 18e3de7ceeabde7467c799ae9a096064e120ef8e..67b547a31296fe65de30f9aa3074e42ed36c9a11 100644
--- a/lib/helpers/npm.js
+++ b/lib/workers/branch/npm.js
@@ -1,4 +1,4 @@
-const logger = require('../helpers/logger');
+const logger = require('../../logger');
 const fs = require('fs');
 const cp = require('child_process');
 const tmp = require('tmp');
diff --git a/lib/helpers/package-json.js b/lib/workers/branch/package-json.js
similarity index 100%
rename from lib/helpers/package-json.js
rename to lib/workers/branch/package-json.js
diff --git a/lib/helpers/yarn.js b/lib/workers/branch/yarn.js
similarity index 98%
rename from lib/helpers/yarn.js
rename to lib/workers/branch/yarn.js
index 9c975eecbb50c0b4792526d397464ac572edae61..7453f38066cb3e18f8842e415a4c49a0a0f623b6 100644
--- a/lib/helpers/yarn.js
+++ b/lib/workers/branch/yarn.js
@@ -1,4 +1,4 @@
-const logger = require('../helpers/logger');
+const logger = require('../../logger');
 const fs = require('fs');
 const cp = require('child_process');
 const tmp = require('tmp');
diff --git a/lib/workers/dep-type/index.js b/lib/workers/dep-type/index.js
index 3f3be63c9b0629eae3e40e655a16b4c439525efa..aad6d80ffe28f5738ae1529207e070b66eaf51f7 100644
--- a/lib/workers/dep-type/index.js
+++ b/lib/workers/dep-type/index.js
@@ -1,7 +1,7 @@
 const configParser = require('../../config');
 const pkgWorker = require('../package');
 const packageJson = require('./package-json');
-let logger = require('../../helpers/logger');
+let logger = require('../../logger');
 
 module.exports = {
   findUpgrades,
diff --git a/lib/workers/global/index.js b/lib/workers/global/index.js
index ad4a199b639368318986b05bdd060da9730d7fe4..ed8060745003733cfb8aff651bb3896d167fc3bc 100644
--- a/lib/workers/global/index.js
+++ b/lib/workers/global/index.js
@@ -1,4 +1,4 @@
-const logger = require('../../helpers/logger');
+const logger = require('../../logger');
 const configParser = require('../../config');
 const repositoryWorker = require('../repository');
 const versions = require('./versions');
diff --git a/lib/workers/package-file/index.js b/lib/workers/package-file/index.js
index 7ef3fb1bf0f80040c87f6a9c721eadc1f3d7e030..ff3164a9de99405c03b3ce039cc1b4f26ccd84f6 100644
--- a/lib/workers/package-file/index.js
+++ b/lib/workers/package-file/index.js
@@ -1,6 +1,6 @@
 const configParser = require('../../config');
 const depTypeWorker = require('../dep-type');
-let logger = require('../../helpers/logger');
+let logger = require('../../logger');
 
 module.exports = {
   findUpgrades,
diff --git a/lib/workers/package/index.js b/lib/workers/package/index.js
index 4126ffe88be05a9ae79e3b582130209eaacdb2af..d88669847b245ef371f4388587fa05fc2374e53f 100644
--- a/lib/workers/package/index.js
+++ b/lib/workers/package/index.js
@@ -1,7 +1,7 @@
 const npmApi = require('../../api/npm');
 const versions = require('./versions');
 
-let logger = require('../../helpers/logger');
+let logger = require('../../logger');
 
 module.exports = {
   findUpgrades,
diff --git a/lib/workers/package/versions.js b/lib/workers/package/versions.js
index afe075b015c7f02d355d10594bb169eb10e802c2..13b630e6abdd32adc9f2635d77d160fe1431c8c0 100644
--- a/lib/workers/package/versions.js
+++ b/lib/workers/package/versions.js
@@ -1,4 +1,4 @@
-const logger = require('../../helpers/logger');
+const logger = require('../../logger');
 const semver = require('semver');
 const stable = require('semver-stable');
 const _ = require('lodash');
diff --git a/lib/helpers/changelog.js b/lib/workers/pr/changelog.js
similarity index 100%
rename from lib/helpers/changelog.js
rename to lib/workers/pr/changelog.js
diff --git a/lib/workers/pr.js b/lib/workers/pr/index.js
similarity index 99%
rename from lib/workers/pr.js
rename to lib/workers/pr/index.js
index 059950c9744bd7f3970af70cfd1e1dd0757e55df..a5ebbcbce4211be41aff4c336b9a2ce1349d87be 100644
--- a/lib/workers/pr.js
+++ b/lib/workers/pr/index.js
@@ -1,5 +1,5 @@
 const handlebars = require('handlebars');
-const changelogHelper = require('../helpers/changelog');
+const changelogHelper = require('./changelog');
 const showdown = require('showdown');
 
 const converter = new showdown.Converter();
diff --git a/test/helpers/__snapshots__/github-app.spec.js.snap b/test/config/__snapshots__/github-app.spec.js.snap
similarity index 71%
rename from test/helpers/__snapshots__/github-app.spec.js.snap
rename to test/config/__snapshots__/github-app.spec.js.snap
index 6a84905b256786d9e2a9a8ebadf75bf6528baab8..362af4579fc5024ee47ab98f1c7f1c982a53f6bc 100644
--- a/test/helpers/__snapshots__/github-app.spec.js.snap
+++ b/test/config/__snapshots__/github-app.spec.js.snap
@@ -1,6 +1,6 @@
 // Jest Snapshot v1, https://goo.gl/fbAQLP
 
-exports[`helpers/github-app getRepositories returns filtered list of repos 1`] = `
+exports[`config/github-app getRepositories returns filtered list of repos 1`] = `
 Array [
   Object {
     "repository": "a/b",
@@ -13,7 +13,7 @@ Array [
 ]
 `;
 
-exports[`helpers/github-app getRepositories returns list of repos 1`] = `
+exports[`config/github-app getRepositories returns list of repos 1`] = `
 Array [
   Object {
     "repository": "a/b",
@@ -34,7 +34,7 @@ Array [
 ]
 `;
 
-exports[`helpers/github-app getUserRepositories returns a repository list 1`] = `
+exports[`config/github-app getUserRepositories returns a repository list 1`] = `
 Array [
   Object {
     "repository": "a",
diff --git a/test/helpers/github-app.spec.js b/test/config/github-app.spec.js
similarity index 69%
rename from test/helpers/github-app.spec.js
rename to test/config/github-app.spec.js
index ee26ffaa01ccae4f4a5ea9f625ba52e6a37af9a4..53ffae776b311b77ea9325dc327ac32a7dacf46f 100644
--- a/test/helpers/github-app.spec.js
+++ b/test/config/github-app.spec.js
@@ -1,4 +1,4 @@
-const githubAppHelper = require('../../lib/helpers/github-app');
+const githubApp = require('../../lib/config/github-app');
 const ghApi = require('../../lib/api/github');
 const fs = require('fs');
 const path = require('path');
@@ -9,10 +9,10 @@ const examplePrivateKey = fs.readFileSync(
   path.resolve(__dirname, '../_fixtures/jwt/example.pem')
 );
 
-describe('helpers/github-app', () => {
+describe('config/github-app', () => {
   describe('generateJwt', () => {
     it('returns a jwt for valid PEM file', () => {
-      expect(githubAppHelper.generateJwt(1, examplePrivateKey)).not.toBeNull();
+      expect(githubApp.generateJwt(1, examplePrivateKey)).not.toBeNull();
     });
   });
   describe('getUserRepositories', async () => {
@@ -21,16 +21,14 @@ describe('helpers/github-app', () => {
     });
     it('returns empty list', async () => {
       ghApi.getInstallationRepositories = jest.fn(() => ({ repositories: [] }));
-      expect(
-        await githubAppHelper.getUserRepositories('token', 123)
-      ).toHaveLength(0);
+      expect(await githubApp.getUserRepositories('token', 123)).toHaveLength(0);
     });
     it('returns a repository list', async () => {
       ghApi.getInstallationRepositories = jest.fn(() => ({
         repositories: [{ full_name: 'a' }, { full_name: 'b' }],
       }));
       expect(
-        await githubAppHelper.getUserRepositories('token', 123)
+        await githubApp.getUserRepositories('token', 123)
       ).toMatchSnapshot();
     });
   });
@@ -41,26 +39,26 @@ describe('helpers/github-app', () => {
       repositories: [],
     };
     beforeEach(() => {
-      githubAppHelper.generateJwt = jest.fn();
-      githubAppHelper.generateJwt.mockImplementationOnce(() => 'jwt');
-      githubAppHelper.getUserRepositories = jest.fn();
+      githubApp.generateJwt = jest.fn();
+      githubApp.generateJwt.mockImplementationOnce(() => 'jwt');
+      githubApp.getUserRepositories = jest.fn();
     });
     it('returns empty list if error', async () => {
       ghApi.getInstallations.mockImplementationOnce(() => {
         throw new Error('error');
       });
-      const results = await githubAppHelper.getRepositories(config);
+      const results = await githubApp.getRepositories(config);
       expect(results).toHaveLength(0);
     });
     it('returns empty list if no installations', async () => {
       ghApi.getInstallations.mockImplementationOnce(() => []);
-      const results = await githubAppHelper.getRepositories(config);
+      const results = await githubApp.getRepositories(config);
       expect(results).toHaveLength(0);
     });
     it('returns empty list if no repos per installation', async () => {
       ghApi.getInstallations.mockImplementationOnce(() => [{ id: 567 }]);
-      githubAppHelper.getUserRepositories.mockImplementationOnce(() => []);
-      const results = await githubAppHelper.getRepositories(config);
+      githubApp.getUserRepositories.mockImplementationOnce(() => []);
+      const results = await githubApp.getRepositories(config);
       expect(results).toHaveLength(0);
     });
     it('returns list of repos', async () => {
@@ -68,7 +66,7 @@ describe('helpers/github-app', () => {
         { id: 567 },
         { id: 568 },
       ]);
-      githubAppHelper.getUserRepositories.mockImplementationOnce(() => [
+      githubApp.getUserRepositories.mockImplementationOnce(() => [
         {
           repository: 'a/b',
           token: 'token_a',
@@ -78,7 +76,7 @@ describe('helpers/github-app', () => {
           token: 'token_a',
         },
       ]);
-      githubAppHelper.getUserRepositories.mockImplementationOnce(() => [
+      githubApp.getUserRepositories.mockImplementationOnce(() => [
         {
           repository: 'd/e',
           token: 'token_d',
@@ -88,7 +86,7 @@ describe('helpers/github-app', () => {
           token: 'token_d',
         },
       ]);
-      const results = await githubAppHelper.getRepositories(config);
+      const results = await githubApp.getRepositories(config);
       expect(results).toMatchSnapshot();
     });
     it('returns filtered list of repos', async () => {
@@ -96,7 +94,7 @@ describe('helpers/github-app', () => {
         { id: 567 },
         { id: 568 },
       ]);
-      githubAppHelper.getUserRepositories.mockImplementationOnce(() => [
+      githubApp.getUserRepositories.mockImplementationOnce(() => [
         {
           repository: 'a/b',
           token: 'token_a',
@@ -106,7 +104,7 @@ describe('helpers/github-app', () => {
           token: 'token_a',
         },
       ]);
-      githubAppHelper.getUserRepositories.mockImplementationOnce(() => [
+      githubApp.getUserRepositories.mockImplementationOnce(() => [
         {
           repository: 'd/e',
           token: 'token_d',
@@ -117,7 +115,7 @@ describe('helpers/github-app', () => {
         },
       ]);
       config.repositories = ['a/b', 'd/f', 'x/y'];
-      const results = await githubAppHelper.getRepositories(config);
+      const results = await githubApp.getRepositories(config);
       expect(results.length).toBe(2);
       expect(results).toMatchSnapshot();
     });
diff --git a/test/config/index.spec.js b/test/config/index.spec.js
index 31cc0fb07a4914ac732275dc9bda950429b2c88d..b63b46addccb302c671fa07c25288362b8eb6942 100644
--- a/test/config/index.spec.js
+++ b/test/config/index.spec.js
@@ -6,7 +6,7 @@ describe('config/index', () => {
     let defaultArgv;
     let ghGot;
     let glGot;
-    let githubAppHelper;
+    let githubApp;
     beforeEach(() => {
       jest.resetModules();
       configParser = require('../../lib/config/index.js');
@@ -15,9 +15,9 @@ describe('config/index', () => {
       ghGot = require('gh-got');
       jest.mock('gl-got');
       glGot = require('gl-got');
-      jest.mock('../../lib/helpers/github-app');
-      githubAppHelper = require('../../lib/helpers/github-app');
-      githubAppHelper.getRepositories = jest.fn();
+      jest.mock('../../lib/config/github-app');
+      githubApp = require('../../lib/config/github-app');
+      githubApp.getRepositories = jest.fn();
     });
     it('throws for invalid platform', async () => {
       const env = {};
@@ -92,7 +92,7 @@ describe('config/index', () => {
         '--github-app-id=5',
         '--github-app-key=abc',
       ]);
-      githubAppHelper.getRepositories.mockImplementationOnce(() => {
+      githubApp.getRepositories.mockImplementationOnce(() => {
         const result = [
           {
             repository: 'a/b',
@@ -102,7 +102,7 @@ describe('config/index', () => {
         return result;
       });
       await configParser.parseConfigs(env, defaultArgv);
-      expect(githubAppHelper.getRepositories.mock.calls.length).toBe(1);
+      expect(githubApp.getRepositories.mock.calls.length).toBe(1);
     });
     it('autodiscovers github platform', async () => {
       const env = {};
diff --git a/test/helpers/__snapshots__/platform.spec.js.snap b/test/helpers/__snapshots__/platform.spec.js.snap
deleted file mode 100644
index 856503e452159c116c24fbb330153df31b606722..0000000000000000000000000000000000000000
--- a/test/helpers/__snapshots__/platform.spec.js.snap
+++ /dev/null
@@ -1,3 +0,0 @@
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`helpers/platform getApi(platform) throws error 1`] = `[Error: Unknown platform: foo]`;
diff --git a/test/helpers/platform.spec.js b/test/helpers/platform.spec.js
deleted file mode 100644
index 60fd09ddc51586ea33548fd3c24a1fd6f98af12d..0000000000000000000000000000000000000000
--- a/test/helpers/platform.spec.js
+++ /dev/null
@@ -1,21 +0,0 @@
-const platformHelper = require('../../lib/helpers/platform');
-
-describe('helpers/platform', () => {
-  describe('getApi(platform)', () => {
-    it('returns github', () => {
-      platformHelper.getApi('github');
-    });
-    it('returns gitlab', () => {
-      platformHelper.getApi('gitlab');
-    });
-    it('throws error', () => {
-      let e;
-      try {
-        platformHelper.getApi('foo');
-      } catch (err) {
-        e = err;
-      }
-      expect(e).toMatchSnapshot();
-    });
-  });
-});
diff --git a/test/helpers/logger/__snapshots__/config-serializer.spec.js.snap b/test/logger/__snapshots__/config-serializer.spec.js.snap
similarity index 60%
rename from test/helpers/logger/__snapshots__/config-serializer.spec.js.snap
rename to test/logger/__snapshots__/config-serializer.spec.js.snap
index 693839e047201dbd253ded8ebab6f2004e2c3ac0..8e0bc44134a5a5713917c8acd88ac13f4e91f07b 100644
--- a/test/helpers/logger/__snapshots__/config-serializer.spec.js.snap
+++ b/test/logger/__snapshots__/config-serializer.spec.js.snap
@@ -1,6 +1,6 @@
 // Jest Snapshot v1, https://goo.gl/fbAQLP
 
-exports[`helpers/logger/config-serializer redacts sensitive fields 1`] = `
+exports[`logger/config-serializer redacts sensitive fields 1`] = `
 Object {
   "githubAppKey": "***********",
   "nottoken": "b",
@@ -8,7 +8,7 @@ Object {
 }
 `;
 
-exports[`helpers/logger/config-serializer replaces functions 1`] = `
+exports[`logger/config-serializer replaces functions 1`] = `
 Object {
   "api": "[Function]",
   "logger": "[Function]",
diff --git a/test/helpers/logger/__snapshots__/pretty-stdout.spec.js.snap b/test/logger/__snapshots__/pretty-stdout.spec.js.snap
similarity index 56%
rename from test/helpers/logger/__snapshots__/pretty-stdout.spec.js.snap
rename to test/logger/__snapshots__/pretty-stdout.spec.js.snap
index b465c2c8735d8176bdf2034bbf7bdd29808dfb21..6940a43ac5b3ab1b6f56c6c66bcce139e8046a90 100644
--- a/test/helpers/logger/__snapshots__/pretty-stdout.spec.js.snap
+++ b/test/logger/__snapshots__/pretty-stdout.spec.js.snap
@@ -1,6 +1,6 @@
 // Jest Snapshot v1, https://goo.gl/fbAQLP
 
-exports[`helpers/logger/pretty-stdout getDetails(rec) supports a config 1`] = `
+exports[`logger/pretty-stdout getDetails(rec) supports a config 1`] = `
 "       {\\"a\\": \\"b\\", \\"d\\": [\\"e\\", \\"f\\"]}
 "
 `;
diff --git a/test/helpers/logger/config-serializer.spec.js b/test/logger/config-serializer.spec.js
similarity index 73%
rename from test/helpers/logger/config-serializer.spec.js
rename to test/logger/config-serializer.spec.js
index 44baa875ace3e88260ceb5a33b5bc29835dcc490..9116d0f3e3c286af67c5f656e9caea0856e006c0 100644
--- a/test/helpers/logger/config-serializer.spec.js
+++ b/test/logger/config-serializer.spec.js
@@ -1,6 +1,6 @@
-const configSerializer = require('../../../lib/helpers/logger/config-serializer');
+const configSerializer = require('../../lib/logger/config-serializer');
 
-describe('helpers/logger/config-serializer', () => {
+describe('logger/config-serializer', () => {
   it('redacts sensitive fields', () => {
     const config = {
       token: 'a',
diff --git a/test/helpers/logger/pretty-stdout.spec.js b/test/logger/pretty-stdout.spec.js
similarity index 92%
rename from test/helpers/logger/pretty-stdout.spec.js
rename to test/logger/pretty-stdout.spec.js
index 61c5086ede3cc773b0748adb423f53b98fabc905..9d04efcfd0e195e8e0e5694d65599920549353a9 100644
--- a/test/helpers/logger/pretty-stdout.spec.js
+++ b/test/logger/pretty-stdout.spec.js
@@ -1,7 +1,7 @@
-const prettyStdout = require('../../../lib/helpers/logger/pretty-stdout');
+const prettyStdout = require('../../lib/logger/pretty-stdout');
 const chalk = require('chalk');
 
-describe('helpers/logger/pretty-stdout', () => {
+describe('logger/pretty-stdout', () => {
   describe('getMeta(rec)', () => {
     it('returns empty string if null rec', () => {
       expect(prettyStdout.getMeta(null)).toEqual('');
diff --git a/test/workers/__snapshots__/branch.spec.js.snap b/test/workers/branch/__snapshots__/index.spec.js.snap
similarity index 100%
rename from test/workers/__snapshots__/branch.spec.js.snap
rename to test/workers/branch/__snapshots__/index.spec.js.snap
diff --git a/test/helpers/__snapshots__/npm.spec.js.snap b/test/workers/branch/__snapshots__/npm.spec.js.snap
similarity index 100%
rename from test/helpers/__snapshots__/npm.spec.js.snap
rename to test/workers/branch/__snapshots__/npm.spec.js.snap
diff --git a/test/helpers/__snapshots__/yarn.spec.js.snap b/test/workers/branch/__snapshots__/yarn.spec.js.snap
similarity index 100%
rename from test/helpers/__snapshots__/yarn.spec.js.snap
rename to test/workers/branch/__snapshots__/yarn.spec.js.snap
diff --git a/test/workers/branch.spec.js b/test/workers/branch/index.spec.js
similarity index 82%
rename from test/workers/branch.spec.js
rename to test/workers/branch/index.spec.js
index a4caa5f9b36bd735b49ce7fd91c36ee4ef94aaba..c2a926aaee7f8db94dbaa788800211c028458b0a 100644
--- a/test/workers/branch.spec.js
+++ b/test/workers/branch/index.spec.js
@@ -1,14 +1,14 @@
-const branchWorker = require('../../lib/workers/branch');
-const prWorker = require('../../lib/workers/pr');
-const npmHelper = require('../../lib/helpers/npm');
-const yarnHelper = require('../../lib/helpers/yarn');
-const defaultConfig = require('../../lib/config/defaults').getConfig();
-const packageJsonHelper = require('../../lib/helpers/package-json');
+const branchWorker = require('../../../lib/workers/branch');
+const prWorker = require('../../../lib/workers/pr');
+const npm = require('../../../lib/workers/branch/npm');
+const yarn = require('../../../lib/workers/branch/yarn');
+const defaultConfig = require('../../../lib/config/defaults').getConfig();
+const packageJsonHelper = require('../../../lib/workers/branch/package-json');
 
-const logger = require('../_fixtures/logger');
+const logger = require('../../_fixtures/logger');
 
-jest.mock('../../lib/helpers/yarn');
-jest.mock('../../lib/helpers/package-json');
+jest.mock('../../../lib/workers/branch/yarn');
+jest.mock('../../../lib/workers/branch/package-json');
 
 describe('workers/branch', () => {
   describe('getParentBranch(branchName, config)', () => {
@@ -95,9 +95,9 @@ describe('workers/branch', () => {
     beforeEach(() => {
       packageJsonHelper.setNewValue = jest.fn();
       branchWorker.getParentBranch = jest.fn();
-      npmHelper.getLockFile = jest.fn();
-      yarnHelper.getLockFile = jest.fn();
-      yarnHelper.maintainLockFile = jest.fn();
+      npm.getLockFile = jest.fn();
+      yarn.getLockFile = jest.fn();
+      yarn.maintainLockFile = jest.fn();
       config = Object.assign({}, defaultConfig);
       config.api = {};
       config.api.getFileContent = jest.fn();
@@ -118,8 +118,8 @@ describe('workers/branch', () => {
       expect(await branchWorker.ensureBranch([config])).toBe(false);
       expect(branchWorker.getParentBranch.mock.calls.length).toBe(1);
       expect(packageJsonHelper.setNewValue.mock.calls.length).toBe(1);
-      expect(npmHelper.getLockFile.mock.calls.length).toBe(0);
-      expect(yarnHelper.getLockFile.mock.calls.length).toBe(0);
+      expect(npm.getLockFile.mock.calls.length).toBe(0);
+      expect(yarn.getLockFile.mock.calls.length).toBe(0);
     });
     it('commits one file if no yarn lock or package-lock.json found', async () => {
       branchWorker.getParentBranch.mockReturnValueOnce('dummy branch');
@@ -128,8 +128,8 @@ describe('workers/branch', () => {
       expect(await branchWorker.ensureBranch([config])).toBe(true);
       expect(branchWorker.getParentBranch.mock.calls.length).toBe(1);
       expect(packageJsonHelper.setNewValue.mock.calls.length).toBe(1);
-      expect(npmHelper.getLockFile.mock.calls.length).toBe(1);
-      expect(yarnHelper.getLockFile.mock.calls.length).toBe(1);
+      expect(npm.getLockFile.mock.calls.length).toBe(1);
+      expect(yarn.getLockFile.mock.calls.length).toBe(1);
       expect(config.api.commitFilesToBranch.mock.calls[0][1].length).toBe(1);
     });
     it('returns true if automerging pr', async () => {
@@ -141,8 +141,8 @@ describe('workers/branch', () => {
       expect(await branchWorker.ensureBranch([config])).toBe(true);
       expect(branchWorker.getParentBranch.mock.calls.length).toBe(1);
       expect(packageJsonHelper.setNewValue.mock.calls.length).toBe(1);
-      expect(npmHelper.getLockFile.mock.calls.length).toBe(1);
-      expect(yarnHelper.getLockFile.mock.calls.length).toBe(1);
+      expect(npm.getLockFile.mock.calls.length).toBe(1);
+      expect(yarn.getLockFile.mock.calls.length).toBe(1);
       expect(config.api.commitFilesToBranch.mock.calls[0][1].length).toBe(1);
     });
     it('automerges successful branches', async () => {
@@ -158,8 +158,8 @@ describe('workers/branch', () => {
       expect(config.api.getBranchStatus.mock.calls.length).toBe(1);
       expect(config.api.mergeBranch.mock).toMatchSnapshot();
       expect(packageJsonHelper.setNewValue.mock.calls.length).toBe(1);
-      expect(npmHelper.getLockFile.mock.calls.length).toBe(1);
-      expect(yarnHelper.getLockFile.mock.calls.length).toBe(1);
+      expect(npm.getLockFile.mock.calls.length).toBe(1);
+      expect(yarn.getLockFile.mock.calls.length).toBe(1);
       expect(config.api.commitFilesToBranch.mock.calls[0][1].length).toBe(1);
     });
     it('skips automerge if status not success', async () => {
@@ -175,8 +175,8 @@ describe('workers/branch', () => {
       expect(config.api.getBranchStatus.mock.calls.length).toBe(1);
       expect(config.api.mergeBranch.mock.calls.length).toBe(0);
       expect(packageJsonHelper.setNewValue.mock.calls.length).toBe(1);
-      expect(npmHelper.getLockFile.mock.calls.length).toBe(1);
-      expect(yarnHelper.getLockFile.mock.calls.length).toBe(1);
+      expect(npm.getLockFile.mock.calls.length).toBe(1);
+      expect(yarn.getLockFile.mock.calls.length).toBe(1);
       expect(config.api.commitFilesToBranch.mock.calls[0][1].length).toBe(1);
     });
     it('throws if automerge throws', async () => {
@@ -200,47 +200,47 @@ describe('workers/branch', () => {
       expect(config.api.getBranchStatus.mock.calls.length).toBe(1);
       expect(config.api.mergeBranch.mock).toMatchSnapshot();
       expect(packageJsonHelper.setNewValue.mock.calls.length).toBe(1);
-      expect(npmHelper.getLockFile.mock.calls.length).toBe(1);
-      expect(yarnHelper.getLockFile.mock.calls.length).toBe(1);
+      expect(npm.getLockFile.mock.calls.length).toBe(1);
+      expect(yarn.getLockFile.mock.calls.length).toBe(1);
       expect(config.api.commitFilesToBranch.mock.calls[0][1].length).toBe(1);
     });
     it('commits two files if yarn lock found', async () => {
       branchWorker.getParentBranch.mockReturnValueOnce('dummy branch');
-      yarnHelper.getLockFile.mockReturnValueOnce('non null response');
+      yarn.getLockFile.mockReturnValueOnce('non null response');
       packageJsonHelper.setNewValue.mockReturnValueOnce('new content');
       await branchWorker.ensureBranch([config]);
       expect(branchWorker.getParentBranch.mock.calls.length).toBe(1);
       expect(packageJsonHelper.setNewValue.mock.calls.length).toBe(1);
-      expect(npmHelper.getLockFile.mock.calls.length).toBe(1);
-      expect(yarnHelper.getLockFile.mock.calls.length).toBe(1);
+      expect(npm.getLockFile.mock.calls.length).toBe(1);
+      expect(yarn.getLockFile.mock.calls.length).toBe(1);
       expect(config.api.commitFilesToBranch.mock.calls[0][1].length).toBe(2);
     });
     it('commits two files if package lock found', async () => {
       branchWorker.getParentBranch.mockReturnValueOnce('dummy branch');
-      npmHelper.getLockFile.mockReturnValueOnce('non null response');
+      npm.getLockFile.mockReturnValueOnce('non null response');
       packageJsonHelper.setNewValue.mockReturnValueOnce('new content');
       await branchWorker.ensureBranch([config]);
       expect(branchWorker.getParentBranch.mock.calls.length).toBe(1);
       expect(packageJsonHelper.setNewValue.mock.calls.length).toBe(1);
-      expect(npmHelper.getLockFile.mock.calls.length).toBe(1);
-      expect(yarnHelper.getLockFile.mock.calls.length).toBe(1);
+      expect(npm.getLockFile.mock.calls.length).toBe(1);
+      expect(yarn.getLockFile.mock.calls.length).toBe(1);
       expect(config.api.commitFilesToBranch.mock.calls[0][1].length).toBe(2);
     });
     it('commits three files if yarn lock and package lock found', async () => {
       branchWorker.getParentBranch.mockReturnValueOnce('dummy branch');
-      npmHelper.getLockFile.mockReturnValueOnce('non null response');
-      yarnHelper.getLockFile.mockReturnValueOnce('non null response');
+      npm.getLockFile.mockReturnValueOnce('non null response');
+      yarn.getLockFile.mockReturnValueOnce('non null response');
       packageJsonHelper.setNewValue.mockReturnValueOnce('new content');
       await branchWorker.ensureBranch([config]);
       expect(branchWorker.getParentBranch.mock.calls.length).toBe(1);
       expect(packageJsonHelper.setNewValue.mock.calls.length).toBe(1);
-      expect(npmHelper.getLockFile.mock.calls.length).toBe(1);
-      expect(yarnHelper.getLockFile.mock.calls.length).toBe(1);
+      expect(npm.getLockFile.mock.calls.length).toBe(1);
+      expect(yarn.getLockFile.mock.calls.length).toBe(1);
       expect(config.api.commitFilesToBranch.mock.calls[0][1].length).toBe(3);
     });
     it('throws an error if no yarn lock generation possible', async () => {
       branchWorker.getParentBranch.mockReturnValueOnce('dummy branch');
-      yarnHelper.getLockFile.mockImplementationOnce(() => {
+      yarn.getLockFile.mockImplementationOnce(() => {
         throw new Error('yarn not found');
       });
       packageJsonHelper.setNewValue.mockReturnValueOnce('new content');
@@ -253,13 +253,13 @@ describe('workers/branch', () => {
       expect(err.message).toBe('yarn not found');
       expect(branchWorker.getParentBranch.mock.calls.length).toBe(1);
       expect(packageJsonHelper.setNewValue.mock.calls.length).toBe(1);
-      expect(yarnHelper.getLockFile.mock.calls.length).toBe(1);
-      expect(npmHelper.getLockFile.mock.calls.length).toBe(0);
+      expect(yarn.getLockFile.mock.calls.length).toBe(1);
+      expect(npm.getLockFile.mock.calls.length).toBe(0);
       expect(config.api.commitFilesToBranch.mock.calls.length).toBe(0);
     });
     it('throws an error if no package lock generation possible', async () => {
       branchWorker.getParentBranch.mockReturnValueOnce('dummy branch');
-      npmHelper.getLockFile.mockImplementationOnce(() => {
+      npm.getLockFile.mockImplementationOnce(() => {
         throw new Error('no package lock generated');
       });
       packageJsonHelper.setNewValue.mockReturnValueOnce('new content');
@@ -272,20 +272,20 @@ describe('workers/branch', () => {
       expect(err.message).toBe('no package lock generated');
       expect(branchWorker.getParentBranch.mock.calls.length).toBe(1);
       expect(packageJsonHelper.setNewValue.mock.calls.length).toBe(1);
-      expect(yarnHelper.getLockFile.mock.calls.length).toBe(1);
-      expect(npmHelper.getLockFile.mock.calls.length).toBe(1);
+      expect(yarn.getLockFile.mock.calls.length).toBe(1);
+      expect(npm.getLockFile.mock.calls.length).toBe(1);
       expect(config.api.commitFilesToBranch.mock.calls.length).toBe(0);
     });
     it('maintains lock files if needing updates', async () => {
       branchWorker.getParentBranch.mockReturnValueOnce('dummy branch');
-      yarnHelper.maintainLockFile.mockReturnValueOnce('non null response');
+      yarn.maintainLockFile.mockReturnValueOnce('non null response');
       config.upgradeType = 'maintainYarnLock';
       await branchWorker.ensureBranch([config]);
       expect(branchWorker.getParentBranch.mock.calls.length).toBe(1);
       expect(packageJsonHelper.setNewValue.mock.calls.length).toBe(0);
-      expect(yarnHelper.getLockFile.mock.calls.length).toBe(0);
-      expect(npmHelper.getLockFile.mock.calls.length).toBe(0);
-      expect(yarnHelper.maintainLockFile.mock.calls.length).toBe(1);
+      expect(yarn.getLockFile.mock.calls.length).toBe(0);
+      expect(npm.getLockFile.mock.calls.length).toBe(0);
+      expect(yarn.maintainLockFile.mock.calls.length).toBe(1);
       expect(config.api.commitFilesToBranch.mock.calls[0][1].length).toBe(1);
     });
     it('skips maintaining lock files if no updates', async () => {
@@ -294,15 +294,15 @@ describe('workers/branch', () => {
       await branchWorker.ensureBranch([config]);
       expect(branchWorker.getParentBranch.mock.calls.length).toBe(1);
       expect(packageJsonHelper.setNewValue.mock.calls.length).toBe(0);
-      expect(yarnHelper.getLockFile.mock.calls.length).toBe(0);
-      expect(npmHelper.getLockFile.mock.calls.length).toBe(0);
-      expect(yarnHelper.maintainLockFile.mock.calls.length).toBe(1);
+      expect(yarn.getLockFile.mock.calls.length).toBe(0);
+      expect(npm.getLockFile.mock.calls.length).toBe(0);
+      expect(yarn.maintainLockFile.mock.calls.length).toBe(1);
       expect(config.api.commitFilesToBranch.mock.calls.length).toBe(0);
     });
     it('throws error if cannot maintain yarn.lock file', async () => {
       branchWorker.getParentBranch.mockReturnValueOnce('dummy branch');
       config.upgradeType = 'maintainYarnLock';
-      yarnHelper.maintainLockFile.mockImplementationOnce(() => {
+      yarn.maintainLockFile.mockImplementationOnce(() => {
         throw new Error('yarn not found');
       });
       let err;
@@ -314,9 +314,9 @@ describe('workers/branch', () => {
       expect(err.message).toBe('Could not maintain yarn.lock file');
       expect(branchWorker.getParentBranch.mock.calls.length).toBe(1);
       expect(packageJsonHelper.setNewValue.mock.calls.length).toBe(0);
-      expect(yarnHelper.getLockFile.mock.calls.length).toBe(0);
-      expect(npmHelper.getLockFile.mock.calls.length).toBe(0);
-      expect(yarnHelper.maintainLockFile.mock.calls.length).toBe(1);
+      expect(yarn.getLockFile.mock.calls.length).toBe(0);
+      expect(npm.getLockFile.mock.calls.length).toBe(0);
+      expect(yarn.maintainLockFile.mock.calls.length).toBe(1);
       expect(config.api.commitFilesToBranch.mock.calls.length).toBe(0);
     });
   });
diff --git a/test/helpers/npm.spec.js b/test/workers/branch/npm.spec.js
similarity index 98%
rename from test/helpers/npm.spec.js
rename to test/workers/branch/npm.spec.js
index d8348980bcb0fd46a2fc4003050c4eefe4d5b36d..a7bb7e8ccf907e92bfa468858751a0c64cebc432 100644
--- a/test/helpers/npm.spec.js
+++ b/test/workers/branch/npm.spec.js
@@ -1,4 +1,4 @@
-const npmHelper = require('../../lib/helpers/npm');
+const npmHelper = require('../../../lib/workers/branch/npm');
 
 jest.mock('fs');
 jest.mock('child_process');
diff --git a/test/helpers/platform-json.spec.js b/test/workers/branch/package-json.spec.js
similarity index 86%
rename from test/helpers/platform-json.spec.js
rename to test/workers/branch/package-json.spec.js
index 793cbbacb6e73da1da919a1ab5d88a6682e48317..109babb99f21667b60a30198fc3f531d9e85aa1d 100644
--- a/test/helpers/platform-json.spec.js
+++ b/test/workers/branch/package-json.spec.js
@@ -1,18 +1,18 @@
 const fs = require('fs');
 const path = require('path');
-const packageJson = require('../../lib/helpers/package-json');
-const logger = require('../_fixtures/logger');
+const packageJson = require('../../../lib/workers/branch/package-json');
+const logger = require('../../_fixtures/logger');
 
 function readFixture(fixture) {
   return fs.readFileSync(
-    path.resolve(__dirname, `../_fixtures/package-json/${fixture}`),
+    path.resolve(__dirname, `../../_fixtures/package-json/${fixture}`),
     'utf8'
   );
 }
 
 const input01Content = readFixture('inputs/01.json');
 
-describe('helpers/package-json', () => {
+describe('workers/branch/package-json', () => {
   describe('.setNewValue(currentFileContent, depType, depName, newVersion, logger)', () => {
     it('replaces a dependency value', () => {
       const outputContent = readFixture('outputs/011.json');
diff --git a/test/helpers/yarn.spec.js b/test/workers/branch/yarn.spec.js
similarity index 98%
rename from test/helpers/yarn.spec.js
rename to test/workers/branch/yarn.spec.js
index 3ebf55d2c277144fa0d82b9be868f6675ded0384..6ca6f3d8b172069284aaf71f8249ad78d6889d57 100644
--- a/test/helpers/yarn.spec.js
+++ b/test/workers/branch/yarn.spec.js
@@ -1,4 +1,4 @@
-const yarnHelper = require('../../lib/helpers/yarn');
+const yarnHelper = require('../../../lib/workers/branch/yarn');
 
 jest.mock('fs');
 jest.mock('child_process');
diff --git a/test/workers/dep-type/package-json.spec.js b/test/workers/dep-type/package-json.spec.js
index ff9fe1531e5ee58983d0f3b248e92b5632cce7b8..85dd172aa9e027077e5aef3984ba395950f64b89 100644
--- a/test/workers/dep-type/package-json.spec.js
+++ b/test/workers/dep-type/package-json.spec.js
@@ -12,7 +12,7 @@ function readFixture(fixture) {
 const input01Content = readFixture('inputs/01.json');
 const input02Content = readFixture('inputs/02.json');
 
-describe('helpers/package-json', () => {
+describe('workers/dep-type/package-json', () => {
   describe('.extractDependencies(packageJson, depType)', () => {
     it('returns an array of correct length (dependencies)', () => {
       const extractedDependencies = packageJson.extractDependencies(
diff --git a/test/workers/__snapshots__/pr.spec.js.snap b/test/workers/pr/__snapshots__/index.spec.js.snap
similarity index 100%
rename from test/workers/__snapshots__/pr.spec.js.snap
rename to test/workers/pr/__snapshots__/index.spec.js.snap
diff --git a/test/helpers/changelog.spec.js b/test/workers/pr/changelog.spec.js
similarity index 89%
rename from test/helpers/changelog.spec.js
rename to test/workers/pr/changelog.spec.js
index 2c25e0dbba4ee9e01b3cdb0b9f07f4bc28b11ca7..b00e50aa9a50ae703bf20e2984f29f7941322d77 100644
--- a/test/helpers/changelog.spec.js
+++ b/test/workers/pr/changelog.spec.js
@@ -1,10 +1,10 @@
 const changelog = require('changelog');
-const changelogHelper = require('../../lib/helpers/changelog');
-const logger = require('../_fixtures/logger');
+const changelogHelper = require('../../../lib/workers/pr/changelog');
+const logger = require('../../_fixtures/logger');
 
 jest.mock('changelog');
 
-describe('helpers/changelog', () => {
+describe('workers/pr/changelog', () => {
   describe('changelogHelper.getChangeLog(depName, fromVersion, newVersion, logger)', () => {
     it('returns empty if no fromVersion', async () => {
       expect(
diff --git a/test/workers/pr.spec.js b/test/workers/pr/index.spec.js
similarity index 96%
rename from test/workers/pr.spec.js
rename to test/workers/pr/index.spec.js
index 6badece429204321e47641c864366c21110cd429..7f5d19eec1ffd6be51b4bda0e891187cdfacd422 100644
--- a/test/workers/pr.spec.js
+++ b/test/workers/pr/index.spec.js
@@ -1,10 +1,10 @@
-const prWorker = require('../../lib/workers/pr');
-const changelogHelper = require('../../lib/helpers/changelog');
-const defaultConfig = require('../../lib/config/defaults').getConfig();
+const prWorker = require('../../../lib/workers/pr');
+const changelogHelper = require('../../../lib/workers/pr/changelog');
+const defaultConfig = require('../../../lib/config/defaults').getConfig();
 
-const logger = require('../_fixtures/logger');
+const logger = require('../../_fixtures/logger');
 
-jest.mock('../../lib/helpers/changelog');
+jest.mock('../../../lib/workers/pr/changelog');
 changelogHelper.getChangeLog = jest.fn();
 changelogHelper.getChangeLog.mockReturnValue('Mocked changelog');
 changelogHelper.getChangeLogJSON = jest.fn();