diff --git a/lib/workers/global/index.ts b/lib/workers/global/index.ts
index c2675d672d60c54d2e432bb943947404cf4a2e39..81c618625ba4320f43056e875958a63189f2d4b4 100644
--- a/lib/workers/global/index.ts
+++ b/lib/workers/global/index.ts
@@ -1,41 +1,18 @@
-import os from 'os';
 import path from 'path';
 import is from '@sindresorhus/is';
 import fs from 'fs-extra';
 import * as configParser from '../../config';
 import { getErrors, logger, setMeta } from '../../logger';
-import { initPlatform } from '../../platform';
 import { setUtilConfig } from '../../util';
-import * as globalCache from '../../util/cache/global';
-import { setEmojiConfig } from '../../util/emoji';
 import * as hostRules from '../../util/host-rules';
 import * as repositoryWorker from '../repository';
 import { autodiscoverRepositories } from './autodiscover';
+import { globalFinalize, globalInitialize } from './initialize';
 import * as limits from './limits';
 
 type RenovateConfig = configParser.RenovateConfig;
 type RenovateRepository = configParser.RenovateRepository;
 
-async function setDirectories(input: RenovateConfig): Promise<RenovateConfig> {
-  const config: RenovateConfig = { ...input };
-  process.env.TMPDIR = process.env.RENOVATE_TMPDIR || os.tmpdir();
-  if (config.baseDir) {
-    logger.debug('Using configured baseDir: ' + config.baseDir);
-  } else {
-    config.baseDir = path.join(process.env.TMPDIR, 'renovate');
-    logger.debug('Using baseDir: ' + config.baseDir);
-  }
-  await fs.ensureDir(config.baseDir);
-  if (config.cacheDir) {
-    logger.debug('Using configured cacheDir: ' + config.cacheDir);
-  } else {
-    config.cacheDir = path.join(config.baseDir, 'cache');
-    logger.debug('Using cacheDir: ' + config.cacheDir);
-  }
-  await fs.ensureDir(config.cacheDir);
-  return config;
-}
-
 export async function getRepositoryConfig(
   globalConfig: RenovateConfig,
   repository: RenovateRepository
@@ -57,22 +34,26 @@ function getGlobalConfig(): Promise<RenovateConfig> {
   return configParser.parseConfigs(process.env, process.argv);
 }
 
+function haveReachedLimits(): boolean {
+  if (limits.getLimitRemaining('prCommitsPerRunLimit') <= 0) {
+    logger.info('Max commits created for this run.');
+    return true;
+  }
+  return false;
+}
+
 export async function start(): Promise<0 | 1> {
+  let config: RenovateConfig;
   try {
-    let config = await getGlobalConfig();
-    config = await initPlatform(config);
-    config = await setDirectories(config);
-    globalCache.init(config);
+    // read global config from file, env and cli args
+    config = await getGlobalConfig();
+    // initialize all submodules
+    config = await globalInitialize(config);
+    // autodiscover repositories (needs to come after platform initialization)
     config = await autodiscoverRepositories(config);
-
-    limits.init(config);
-    setEmojiConfig(config);
     // Iterate through repositories sequentially
     for (const repository of config.repositories) {
-      if (limits.getLimitRemaining('prCommitsPerRunLimit') <= 0) {
-        logger.debug(
-          'Max commits created for this run. Skipping all remaining repositories.'
-        );
+      if (haveReachedLimits()) {
         break;
       }
       const repoConfig = await getRepositoryConfig(config, repository);
@@ -83,16 +64,17 @@ export async function start(): Promise<0 | 1> {
         repoConfig.hostRules = [];
       }
       await repositoryWorker.renovateRepository(repoConfig);
+      setMeta({});
     }
-    setMeta({});
-    globalCache.cleanup(config);
-    logger.debug(`Renovate exiting successfully`);
   } catch (err) /* istanbul ignore next */ {
     if (err.message.startsWith('Init: ')) {
       logger.fatal(err.message.substring(6));
     } else {
       logger.fatal({ err }, `Fatal error: ${err.message}`);
     }
+  } finally {
+    globalFinalize(config);
+    logger.debug(`Renovate exiting`);
   }
   const loggerErrors = getErrors();
   /* istanbul ignore if */
diff --git a/lib/workers/global/initialize.ts b/lib/workers/global/initialize.ts
new file mode 100644
index 0000000000000000000000000000000000000000..4e36e1f54c45c49d6dc3356beab2497804172d78
--- /dev/null
+++ b/lib/workers/global/initialize.ts
@@ -0,0 +1,45 @@
+import os from 'os';
+import path from 'path';
+import fs from 'fs-extra';
+import { RenovateConfig } from '../../config/common';
+import { logger } from '../../logger';
+import { initPlatform } from '../../platform';
+import * as globalCache from '../../util/cache/global';
+import { setEmojiConfig } from '../../util/emoji';
+import * as limits from './limits';
+
+async function setDirectories(input: RenovateConfig): Promise<RenovateConfig> {
+  const config: RenovateConfig = { ...input };
+  process.env.TMPDIR = process.env.RENOVATE_TMPDIR || os.tmpdir();
+  if (config.baseDir) {
+    logger.debug('Using configured baseDir: ' + config.baseDir);
+  } else {
+    config.baseDir = path.join(process.env.TMPDIR, 'renovate');
+    logger.debug('Using baseDir: ' + config.baseDir);
+  }
+  await fs.ensureDir(config.baseDir);
+  if (config.cacheDir) {
+    logger.debug('Using configured cacheDir: ' + config.cacheDir);
+  } else {
+    config.cacheDir = path.join(config.baseDir, 'cache');
+    logger.debug('Using cacheDir: ' + config.cacheDir);
+  }
+  await fs.ensureDir(config.cacheDir);
+  return config;
+}
+
+export async function globalInitialize(
+  config_: RenovateConfig
+): Promise<RenovateConfig> {
+  let config = config_;
+  config = await initPlatform(config);
+  config = await setDirectories(config);
+  globalCache.init(config);
+  limits.init(config);
+  setEmojiConfig(config);
+  return config;
+}
+
+export function globalFinalize(config: RenovateConfig): void {
+  globalCache.cleanup(config);
+}