diff --git a/lib/config/common.ts b/lib/config/common.ts
index 808756b354d3ee8509d507035442c0e533d255b9..1b91283eb77075134aa5cac753470d134a447204 100644
--- a/lib/config/common.ts
+++ b/lib/config/common.ts
@@ -17,15 +17,17 @@ export interface RenovateSharedConfig {
   managers?: string | string[];
   platform?: string;
   productLinks?: Record<string, string>;
+  prPriority?: number;
   rebaseStalePrs?: boolean;
   recreateClosed?: boolean;
   requiredStatusChecks?: string[];
-  schedule?: string | string[];
+  schedule?: string[];
 
   semanticCommits?: boolean;
   semanticCommitScope?: string;
   semanticCommitType?: string;
   statusCheckVerify?: boolean;
+  suppressNotifications?: string[];
   timezone?: string;
 }
 
@@ -61,6 +63,8 @@ export interface RenovateConfig
   onboarding?: boolean;
   onboardingConfig?: RenovateSharedConfig;
   packageRules?: PackageRule[];
+  prConcurrentLimit?: number;
+  prHourlyLimit?: number;
   privateKey?: string | Buffer;
   repoIsOnboarded?: boolean;
   repositories?: RenovateRepository[];
diff --git a/lib/config/utils.ts b/lib/config/utils.ts
index 659185a29085b5d1e666c6ed2adfe6887b1a4af0..a514874f1f505b451e026193240c7a6797d14448 100644
--- a/lib/config/utils.ts
+++ b/lib/config/utils.ts
@@ -3,13 +3,13 @@ import { logger } from '../logger';
 import { clone } from '../util/clone';
 import * as definitions from './definitions';
 
-export function mergeChildConfig<T extends RenovateConfig = RenovateConfig>(
-  parent: T,
-  child: RenovateConfig
-): T {
+export function mergeChildConfig<
+  T extends RenovateConfig = RenovateConfig,
+  TChild extends RenovateConfig = RenovateConfig
+>(parent: T, child: TChild): T & TChild {
   logger.trace({ parent, child }, `mergeChildConfig`);
   if (!child) {
-    return parent;
+    return parent as never;
   }
   const parentConfig = clone(parent);
   const childConfig = clone(child);
diff --git a/lib/manager/common.ts b/lib/manager/common.ts
index 692e9d4aba20ea1ef327abd0ced8d07392277f55..eb819f7e388e0325e2ce72fecb3fa9bb508101d8 100644
--- a/lib/manager/common.ts
+++ b/lib/manager/common.ts
@@ -1,5 +1,6 @@
 import { ReleaseType } from 'semver';
 import { RangeStrategy } from '../versioning';
+import { ValidationMessage } from '../config/common';
 
 export type Result<T> = T | Promise<T>;
 
@@ -119,10 +120,11 @@ export interface Package<T> extends ManagerData<T> {
 }
 
 export interface PackageDependency<T = Record<string, any>> extends Package<T> {
-  warnings?: { message: string }[];
+  warnings?: ValidationMessage[];
   commitMessageTopic?: string;
   currentDigestShort?: string;
   datasource?: string;
+  deprecationMessage?: string;
   digestOneAndOnly?: boolean;
   fromVersion?: string;
   lockedVersion?: string;
@@ -134,6 +136,7 @@ export interface PackageDependency<T = Record<string, any>> extends Package<T> {
   skipReason?: string;
   source?: string;
   sourceLine?: number;
+  updates?: PackageUpdateResult[];
   versionLine?: number;
 }
 
diff --git a/lib/workers/common.ts b/lib/workers/common.ts
index 1ee5527627139e370e53cbd1dc8b65d27dc1b738..052d359ec741a2ae3b39b53c11f25e519b3df631 100644
--- a/lib/workers/common.ts
+++ b/lib/workers/common.ts
@@ -1,7 +1,7 @@
 import { PrBodyUpgrade, PrBodyConfig } from './pr/body/common';
 import { PackageDependency } from '../manager/common';
 import { ChangeLogConfig } from './pr/changelog';
-import { RenovateConfig } from '../config';
+import { RenovateSharedConfig } from '../config';
 import { StabilityConfig, UnpublishableConfig } from './branch/status-checks';
 import { CommitConfig } from './branch/commit';
 
@@ -14,7 +14,7 @@ export type PrUpgrade = PrBodyUpgrade &
     githubName?: string | undefined;
   };
 
-export type BranchConfig = RenovateConfig &
+export type BranchConfig = RenovateSharedConfig &
   StabilityConfig &
   UnpublishableConfig &
   CommitConfig &
diff --git a/lib/workers/pr/body/common.ts b/lib/workers/pr/body/common.ts
index c3de2c62f5b0590178714efcba58aa746d76941c..0aceae4fc81005f9f5a89aaf37dac576c0b6d67f 100644
--- a/lib/workers/pr/body/common.ts
+++ b/lib/workers/pr/body/common.ts
@@ -20,6 +20,7 @@ export type PrBodyConfig<T extends PrBodyUpgrade = PrBodyUpgrade> = {
   prBodyTemplate: string;
   prBodyColumns: string[];
   prBodyDefinitions: Record<string, string>;
+  prTitle?: string;
   updateType: string;
   isGroup?: boolean;
   isPin?: boolean;
diff --git a/lib/workers/pr/body/config-description.ts b/lib/workers/pr/body/config-description.ts
index cc3476dece7d0c7fa72c4b6b4ec159370447c66c..86ee60ac386f4a13034a7f672f8c6a4c24d6b48b 100644
--- a/lib/workers/pr/body/config-description.ts
+++ b/lib/workers/pr/body/config-description.ts
@@ -9,7 +9,7 @@ export async function getPrConfigDescription(
   prBody += emojify(`:date: **Schedule**: `);
   if (
     config.schedule &&
-    config.schedule !== 'at any time' &&
+    (config.schedule as never) !== 'at any time' &&
     config.schedule[0] !== 'at any time'
   ) {
     prBody += `"${config.schedule}"`;
diff --git a/lib/workers/repository/onboarding/pr/config-description.ts b/lib/workers/repository/onboarding/pr/config-description.ts
index 8350abdba3d4b7fd62ed4402a7e6b7dd6c5b38f5..cdcfef07988e1b8b7e126ffc616b0cb70c02c141 100644
--- a/lib/workers/repository/onboarding/pr/config-description.ts
+++ b/lib/workers/repository/onboarding/pr/config-description.ts
@@ -11,7 +11,7 @@ export function getScheduleDesc(config: RenovateConfig): string[] {
   logger.trace({ config });
   if (
     !config.schedule ||
-    config.schedule === 'at any time' ||
+    (config.schedule as never) === 'at any time' ||
     config.schedule[0] === 'at any time'
   ) {
     logger.debug('No schedule');
diff --git a/lib/workers/repository/onboarding/pr/index.ts b/lib/workers/repository/onboarding/pr/index.ts
index 20cd937501ebef1b39b05f77ebbad387519fbf18..0f79201d66dccd426b4364eb4d2bfd60e7b1bbee 100644
--- a/lib/workers/repository/onboarding/pr/index.ts
+++ b/lib/workers/repository/onboarding/pr/index.ts
@@ -4,7 +4,7 @@ import { logger } from '../../../../logger';
 import { getConfigDesc } from './config-description';
 import { getErrors, getWarnings, getDepWarnings } from './errors-warnings';
 import { getBaseBranchDesc } from './base-branch';
-import { getPrList, BranchConfig } from './pr-list';
+import { getPrList, PrBranchConfig } from './pr-list';
 import { emojify } from '../../../../util/emoji';
 import { RenovateConfig } from '../../../../config';
 import { PackageFile } from '../../../../manager/common';
@@ -12,7 +12,7 @@ import { PackageFile } from '../../../../manager/common';
 export async function ensureOnboardingPr(
   config: RenovateConfig,
   packageFiles: Record<string, PackageFile[]> | null,
-  branches: BranchConfig[]
+  branches: PrBranchConfig[]
 ): Promise<void> {
   if (config.repoIsOnboarded) {
     return;
diff --git a/lib/workers/repository/onboarding/pr/pr-list.ts b/lib/workers/repository/onboarding/pr/pr-list.ts
index 9143eb018d9c7a13f6036a0d865178210bdc6d7d..5f8908e4d1130499673bdc41b345039548935002 100644
--- a/lib/workers/repository/onboarding/pr/pr-list.ts
+++ b/lib/workers/repository/onboarding/pr/pr-list.ts
@@ -1,19 +1,16 @@
 import { emojify } from '../../../../util/emoji';
 import { logger } from '../../../../logger';
 import { RenovateConfig } from '../../../../config';
-import { Upgrade } from '../../../../manager/common';
+import { BranchConfig } from '../../../common';
 
-export interface BranchConfig {
-  upgrades: Upgrade[];
-  baseBranch?: string;
-  branchName: string;
-  schedule?: string[];
-  prTitle: string;
-}
+export type PrBranchConfig = Pick<
+  BranchConfig,
+  'upgrades' | 'baseBranch' | 'branchName' | 'schedule' | 'prTitle'
+>;
 
 export function getPrList(
   config: RenovateConfig,
-  branches: BranchConfig[]
+  branches: PrBranchConfig[]
 ): string {
   logger.debug('getPrList()');
   logger.trace({ config });
diff --git a/lib/workers/repository/process/deprecated.js b/lib/workers/repository/process/deprecated.ts
similarity index 83%
rename from lib/workers/repository/process/deprecated.js
rename to lib/workers/repository/process/deprecated.ts
index 5bfc1bb7493dc35cbb10515bd908c24e8f54a323..560edb846dd54ce984624ad3da8474f45d4a7f67 100644
--- a/lib/workers/repository/process/deprecated.js
+++ b/lib/workers/repository/process/deprecated.ts
@@ -1,11 +1,12 @@
-const { logger } = require('../../../logger');
-const { platform } = require('../../../platform');
+import { logger } from '../../../logger';
+import { platform } from '../../../platform';
+import { PackageFile } from '../../../manager/common';
+import { RenovateConfig } from '../../../config';
 
-module.exports = {
-  raiseDeprecationWarnings,
-};
-
-async function raiseDeprecationWarnings(config, packageFiles) {
+export async function raiseDeprecationWarnings(
+  config: RenovateConfig,
+  packageFiles: Record<string, PackageFile[]>
+): Promise<void> {
   if (!config.repoIsOnboarded) {
     return;
   }
@@ -16,7 +17,10 @@ async function raiseDeprecationWarnings(config, packageFiles) {
     return;
   }
   for (const [manager, files] of Object.entries(packageFiles)) {
-    const deprecatedPackages = {};
+    const deprecatedPackages: Record<
+      string,
+      { deprecationMessage?: string; depPackageFiles: string[] }
+    > = {};
     for (const packageFile of files) {
       for (const dep of packageFile.deps) {
         const { deprecationMessage } = dep;
@@ -33,7 +37,7 @@ async function raiseDeprecationWarnings(config, packageFiles) {
     }
 
     logger.debug({ deprecatedPackages });
-    const issueTitleList = [];
+    const issueTitleList: string[] = [];
     const issueTitlePrefix = 'Dependency deprecation warning:';
     for (const [depName, val] of Object.entries(deprecatedPackages)) {
       const { deprecationMessage, depPackageFiles } = val;
diff --git a/lib/workers/repository/process/extract-update.js b/lib/workers/repository/process/extract-update.js
deleted file mode 100644
index 58545304cb6f87916e421e3c11a37553101c95cc..0000000000000000000000000000000000000000
--- a/lib/workers/repository/process/extract-update.js
+++ /dev/null
@@ -1,28 +0,0 @@
-const { logger } = require('../../../logger');
-const { writeUpdates } = require('./write');
-const { sortBranches } = require('./sort');
-const { fetchUpdates } = require('./fetch');
-const { raiseDeprecationWarnings } = require('./deprecated');
-const { branchifyUpgrades } = require('../updates/branchify');
-const { extractAllDependencies } = require('../extract');
-
-module.exports = {
-  extractAndUpdate,
-};
-
-async function extractAndUpdate(config) {
-  logger.debug('extractAndUpdate()');
-  /** @type {any} */
-  const packageFiles = await extractAllDependencies(config);
-  logger.trace({ config: packageFiles }, 'packageFiles');
-  await fetchUpdates(config, packageFiles);
-  logger.debug({ config: packageFiles }, 'packageFiles with updates');
-  await raiseDeprecationWarnings(config, packageFiles);
-  const { branches, branchList } = branchifyUpgrades(config, packageFiles);
-  sortBranches(branches);
-  let res;
-  if (config.repoIsOnboarded) {
-    res = await writeUpdates(config, packageFiles, branches);
-  }
-  return { res, branches, branchList, packageFiles };
-}
diff --git a/lib/workers/repository/process/extract-update.ts b/lib/workers/repository/process/extract-update.ts
new file mode 100644
index 0000000000000000000000000000000000000000..a53c71665aa2a43029354fd75821a1d926ec3911
--- /dev/null
+++ b/lib/workers/repository/process/extract-update.ts
@@ -0,0 +1,36 @@
+import { logger } from '../../../logger';
+import { writeUpdates, WriteUpdateResult } from './write';
+import { sortBranches } from './sort';
+import { fetchUpdates } from './fetch';
+import { raiseDeprecationWarnings } from './deprecated';
+import { branchifyUpgrades } from '../updates/branchify';
+import { extractAllDependencies } from '../extract';
+import { PackageFile } from '../../../manager/common';
+import { RenovateConfig } from '../../../config';
+import { BranchConfig } from '../../common';
+
+export type ExtractAndUpdateResult = {
+  res: WriteUpdateResult | undefined;
+  branches: BranchConfig[];
+  branchList: string[];
+  packageFiles?: Record<string, PackageFile[]>;
+};
+
+export async function extractAndUpdate(
+  config: RenovateConfig
+): Promise<ExtractAndUpdateResult> {
+  logger.debug('extractAndUpdate()');
+  const packageFiles = await extractAllDependencies(config);
+  logger.trace({ config: packageFiles }, 'packageFiles');
+  await fetchUpdates(config, packageFiles);
+  logger.debug({ config: packageFiles }, 'packageFiles with updates');
+  await raiseDeprecationWarnings(config, packageFiles);
+  const { branches, branchList } = branchifyUpgrades(config, packageFiles);
+  sortBranches(branches);
+  let res: WriteUpdateResult | undefined;
+  // istanbul ignore else
+  if (config.repoIsOnboarded) {
+    res = await writeUpdates(config, packageFiles, branches);
+  }
+  return { res, branches, branchList, packageFiles };
+}
diff --git a/lib/workers/repository/process/fetch.js b/lib/workers/repository/process/fetch.ts
similarity index 61%
rename from lib/workers/repository/process/fetch.js
rename to lib/workers/repository/process/fetch.ts
index a50316202782704f79bc095163a0d2e4a7c47c54..5492f87ab0e9ada6199e40c1faf86c8f9824f356 100644
--- a/lib/workers/repository/process/fetch.js
+++ b/lib/workers/repository/process/fetch.ts
@@ -1,17 +1,25 @@
 import is from '@sindresorhus/is';
+import pAll from 'p-all';
+import { logger } from '../../../logger';
+import { getPackageUpdates } from '../../../manager';
+import {
+  getManagerConfig,
+  mergeChildConfig,
+  RenovateConfig,
+  ManagerConfig,
+} from '../../../config';
+import { applyPackageRules } from '../../../util/package-rules';
+import { lookupUpdates, LookupUpdateConfig, UpdateResult } from './lookup';
+import {
+  PackageFile,
+  PackageDependency,
+  PackageUpdateResult,
+} from '../../../manager/common';
 
-const pAll = require('p-all');
-const { logger } = require('../../../logger');
-
-const { getPackageUpdates } = require('../../../manager');
-const { mergeChildConfig } = require('../../../config');
-const { applyPackageRules } = require('../../../util/package-rules');
-const { getManagerConfig } = require('../../../config');
-const { lookupUpdates } = require('./lookup');
-
-export { fetchUpdates };
-
-async function fetchDepUpdates(packageFileConfig, dep) {
+async function fetchDepUpdates(
+  packageFileConfig: ManagerConfig & PackageFile,
+  dep: PackageDependency
+): Promise<void> {
   /* eslint-disable no-param-reassign */
   dep.updates = [];
   if (dep.skipReason) {
@@ -19,6 +27,7 @@ async function fetchDepUpdates(packageFileConfig, dep) {
   }
   const { manager, packageFile } = packageFileConfig;
   const { depName, currentValue } = dep;
+  // TODO: fix types
   let depConfig = mergeChildConfig(packageFileConfig, dep);
   depConfig = applyPackageRules(depConfig);
   if (depConfig.ignoreDeps.includes(depName)) {
@@ -37,9 +46,9 @@ async function fetchDepUpdates(packageFileConfig, dep) {
     logger.debug({ dependency: dep.depName }, 'Dependency is disabled');
     dep.skipReason = 'disabled';
   } else {
-    let lookupResults;
+    let lookupResults: UpdateResult | PackageUpdateResult[];
     if (depConfig.datasource) {
-      lookupResults = await lookupUpdates(depConfig);
+      lookupResults = await lookupUpdates(depConfig as LookupUpdateConfig);
     } else {
       lookupResults = await getPackageUpdates(manager, depConfig);
     }
@@ -69,23 +78,34 @@ async function fetchDepUpdates(packageFileConfig, dep) {
   /* eslint-enable no-param-reassign */
 }
 
-async function fetchManagerPackagerFileUpdates(config, managerConfig, pFile) {
+async function fetchManagerPackagerFileUpdates(
+  config: RenovateConfig,
+  managerConfig: ManagerConfig,
+  pFile: PackageFile
+): Promise<void> {
   const packageFileConfig = mergeChildConfig(managerConfig, pFile);
-  const queue = pFile.deps.map(dep => () =>
+  const queue = pFile.deps.map(dep => (): Promise<void> =>
     fetchDepUpdates(packageFileConfig, dep)
   );
   await pAll(queue, { concurrency: 10 });
 }
 
-async function fetchManagerUpdates(config, packageFiles, manager) {
+async function fetchManagerUpdates(
+  config: RenovateConfig,
+  packageFiles: Record<string, PackageFile[]>,
+  manager: string
+): Promise<void> {
   const managerConfig = getManagerConfig(config, manager);
-  const queue = packageFiles[manager].map(pFile => () =>
+  const queue = packageFiles[manager].map(pFile => (): Promise<void> =>
     fetchManagerPackagerFileUpdates(config, managerConfig, pFile)
   );
   await pAll(queue, { concurrency: 5 });
 }
 
-async function fetchUpdates(config, packageFiles) {
+export async function fetchUpdates(
+  config: RenovateConfig,
+  packageFiles: Record<string, PackageFile[]>
+): Promise<void> {
   logger.debug(`manager.fetchUpdates()`);
   const allManagerJobs = Object.keys(packageFiles).map(manager =>
     fetchManagerUpdates(config, packageFiles, manager)
diff --git a/lib/workers/repository/process/index.js b/lib/workers/repository/process/index.ts
similarity index 79%
rename from lib/workers/repository/process/index.js
rename to lib/workers/repository/process/index.ts
index f7dc5f243286a226ac720c1cbd5886abee1f0df5..9efbbd61c11d47e05c54ff451db8af7a26fa7972 100644
--- a/lib/workers/repository/process/index.js
+++ b/lib/workers/repository/process/index.ts
@@ -1,13 +1,13 @@
-const { logger, setMeta } = require('../../../logger');
-const { mergeChildConfig } = require('../../../config');
-const { extractAndUpdate } = require('./extract-update');
-const { platform } = require('../../../platform');
+import { logger, setMeta } from '../../../logger';
+import { mergeChildConfig, RenovateConfig } from '../../../config';
+import { extractAndUpdate, ExtractAndUpdateResult } from './extract-update';
+import { platform } from '../../../platform';
+import { WriteUpdateResult } from './write';
+import { BranchConfig } from '../../common';
 
-module.exports = {
-  processRepo,
-};
-
-async function processRepo(config) {
+export async function processRepo(
+  config: RenovateConfig
+): Promise<ExtractAndUpdateResult> {
   logger.debug('processRepo()');
   /* eslint-disable no-param-reassign */
   config.masterIssueChecks = {};
@@ -43,9 +43,9 @@ async function processRepo(config) {
   }
   if (config.baseBranches && config.baseBranches.length) {
     logger.info({ baseBranches: config.baseBranches }, 'baseBranches');
-    let res;
-    let branches = [];
-    let branchList = [];
+    let res: WriteUpdateResult | undefined;
+    let branches: BranchConfig[] = [];
+    let branchList: string[] = [];
     for (const baseBranch of config.baseBranches) {
       setMeta({
         repository: config.repository,
diff --git a/lib/workers/repository/process/limits.js b/lib/workers/repository/process/limits.ts
similarity index 66%
rename from lib/workers/repository/process/limits.js
rename to lib/workers/repository/process/limits.ts
index ab94b325a3f6047c830a6346254a33ef056e4f1a..1b4e395d92daa2d89ee3cdd9fb48da6aebcc9c37 100644
--- a/lib/workers/repository/process/limits.js
+++ b/lib/workers/repository/process/limits.ts
@@ -1,14 +1,15 @@
-const moment = require('moment');
-const { logger } = require('../../../logger');
-const { platform } = require('../../../platform');
+import moment from 'moment';
+import { logger } from '../../../logger';
+import { platform } from '../../../platform';
+import { RenovateConfig } from '../../../config';
+import { BranchConfig } from '../../common';
 
-module.exports = {
-  getPrHourlyRemaining,
-  getConcurrentPrsRemaining,
-  getPrsRemaining,
-};
+export type LimitBranchConfig = Pick<BranchConfig, 'branchName'> &
+  Partial<BranchConfig>;
 
-async function getPrHourlyRemaining(config) {
+export async function getPrHourlyRemaining(
+  config: RenovateConfig
+): Promise<number> {
   if (config.prHourlyLimit) {
     logger.debug('Calculating hourly PRs remaining');
     const prList = await platform.getPrList();
@@ -41,7 +42,10 @@ async function getPrHourlyRemaining(config) {
   return 99;
 }
 
-async function getConcurrentPrsRemaining(config, branches) {
+export async function getConcurrentPrsRemaining(
+  config: RenovateConfig,
+  branches: LimitBranchConfig[]
+): Promise<number> {
   if (config.prConcurrentLimit) {
     logger.debug(`Enforcing prConcurrentLimit (${config.prConcurrentLimit})`);
     let currentlyOpen = 0;
@@ -58,12 +62,12 @@ async function getConcurrentPrsRemaining(config, branches) {
   return 99;
 }
 
-async function getPrsRemaining(config, branches) {
-  const hourlyRemaining = await module.exports.getPrHourlyRemaining(config);
-  const concurrentRemaining = await module.exports.getConcurrentPrsRemaining(
-    config,
-    branches
-  );
+export async function getPrsRemaining(
+  config: RenovateConfig,
+  branches: LimitBranchConfig[]
+): Promise<number> {
+  const hourlyRemaining = await getPrHourlyRemaining(config);
+  const concurrentRemaining = await getConcurrentPrsRemaining(config, branches);
   return hourlyRemaining < concurrentRemaining
     ? hourlyRemaining
     : concurrentRemaining;
diff --git a/lib/workers/repository/process/lookup/rollback.ts b/lib/workers/repository/process/lookup/rollback.ts
index 43ae0cbd67a2f8aac44c1da4938d4ffac70fc25e..0972187068f5f14fca4af7945ad51bc127266f6b 100644
--- a/lib/workers/repository/process/lookup/rollback.ts
+++ b/lib/workers/repository/process/lookup/rollback.ts
@@ -5,7 +5,7 @@ import { LookupUpdate } from './common';
 export interface RollbackConfig {
   currentValue?: string;
   depName?: string;
-  packageFile: Record<string, any>;
+  packageFile: string;
   versionScheme: string;
 }
 
diff --git a/lib/workers/repository/process/sort.js b/lib/workers/repository/process/sort.ts
similarity index 66%
rename from lib/workers/repository/process/sort.js
rename to lib/workers/repository/process/sort.ts
index b6a8f9b3a48ae5649dd96fa94b18a66bab319d8a..b715e32546298de699d775379cd6a9cf7f789e19 100644
--- a/lib/workers/repository/process/sort.js
+++ b/lib/workers/repository/process/sort.ts
@@ -1,8 +1,13 @@
-const { logger } = require('../../../logger');
+import { logger } from '../../../logger';
+import { BranchConfig } from '../../common';
 
-module.exports = { sortBranches };
+export type SortBranchConfig = Pick<
+  BranchConfig,
+  'prPriority' | 'updateType' | 'prTitle'
+> &
+  Partial<BranchConfig>;
 
-function sortBranches(branches) {
+export function sortBranches(branches: SortBranchConfig[]): void {
   // Sort branches
   const sortOrder = [
     'pin',
diff --git a/lib/workers/repository/process/write.js b/lib/workers/repository/process/write.ts
similarity index 51%
rename from lib/workers/repository/process/write.js
rename to lib/workers/repository/process/write.ts
index 68857248d1f3bdb067075f2b96296f38bdfc0f02..89eef5f71da3a610928923805d35e81584e9b58b 100644
--- a/lib/workers/repository/process/write.js
+++ b/lib/workers/repository/process/write.ts
@@ -1,13 +1,19 @@
-const { logger } = require('../../../logger');
-const branchWorker = require('../../branch');
-const { getPrsRemaining } = require('./limits');
-const limits = require('../../global/limits');
+import { logger } from '../../../logger';
+import { processBranch } from '../../branch';
+import { getPrsRemaining } from './limits';
+import { getLimitRemaining } from '../../global/limits';
+import { RenovateConfig } from '../../../config';
+import { PackageFile } from '../../../manager/common';
+import { AdditionalPackageFiles } from '../../../manager/npm/post-update';
+import { BranchConfig } from '../../common';
 
-module.exports = {
-  writeUpdates,
-};
+export type WriteUpdateResult = 'done' | 'automerged';
 
-async function writeUpdates(config, packageFiles, allBranches) {
+export async function writeUpdates(
+  config: RenovateConfig,
+  packageFiles: Record<string, PackageFile[]> | AdditionalPackageFiles,
+  allBranches: BranchConfig[]
+): Promise<WriteUpdateResult> {
   let branches = allBranches;
   logger.info(
     `Processing ${branches.length} branch${
@@ -26,10 +32,9 @@ async function writeUpdates(config, packageFiles, allBranches) {
   });
   let prsRemaining = await getPrsRemaining(config, branches);
   for (const branch of branches) {
-    const res = await branchWorker.processBranch(
+    const res = await processBranch(
       branch,
-      prsRemaining <= 0 ||
-        limits.getLimitRemaining('prCommitsPerRunLimit') <= 0,
+      prsRemaining <= 0 || getLimitRemaining('prCommitsPerRunLimit') <= 0,
       packageFiles
     );
     branch.res = res;
diff --git a/lib/workers/repository/updates/branchify.ts b/lib/workers/repository/updates/branchify.ts
index 28e040750cc5fdbddeaf47c147d2f8ffd9d8eeb2..40375a037930172e910871a1829662f294a9f9b7 100644
--- a/lib/workers/repository/updates/branchify.ts
+++ b/lib/workers/repository/updates/branchify.ts
@@ -22,6 +22,7 @@ function cleanBranchName(branchName: string): string {
     .replace(/\s/g, ''); // whitespace
 }
 
+// TODO: fix return type
 export function branchifyUpgrades(
   config: RenovateConfig,
   packageFiles: Record<string, any[]>
diff --git a/test/config/massage.spec.ts b/test/config/massage.spec.ts
index 8e0a7ab029adc3214ba43544e5ac9e87aeca4e7b..c0359612906c1e55f955439c659fad54dccfaf54 100644
--- a/test/config/massage.spec.ts
+++ b/test/config/massage.spec.ts
@@ -10,7 +10,7 @@ describe('config/massage', () => {
     });
     it('massages strings to array', () => {
       const config: RenovateConfig = {
-        schedule: 'before 5am',
+        schedule: 'before 5am' as never,
       };
       const res = massage.massageConfig(config);
       expect(Array.isArray(res.schedule)).toBe(true);
diff --git a/test/config/migration.spec.ts b/test/config/migration.spec.ts
index 0c6dc5851178c2cd68997fd03b809f29c4f3cbdb..1a9fb6d8e137147d216c50272042fb9c68e87926 100644
--- a/test/config/migration.spec.ts
+++ b/test/config/migration.spec.ts
@@ -42,7 +42,7 @@ describe('config/migration', () => {
         },
         meteor: true,
         autodiscover: 'true' as never,
-        schedule: 'on the last day of the month',
+        schedule: 'on the last day of the month' as never,
         commitMessage: '{{semanticPrefix}}some commit message',
         prTitle: '{{semanticPrefix}}some pr title',
         semanticPrefix: 'fix(deps): ',
@@ -77,7 +77,7 @@ describe('config/migration', () => {
           exposeEnv: false,
           gitFs: true,
           automerge: 'any' as never,
-          schedule: 'before 5am every day',
+          schedule: 'before 5am every day' as never,
         },
         devDependencies: {
           automerge: 'minor',
@@ -117,10 +117,10 @@ describe('config/migration', () => {
     it('migrates before and after schedules', () => {
       const config = {
         major: {
-          schedule: 'after 10pm and before 7am',
+          schedule: 'after 10pm and before 7am' as never,
         },
         minor: {
-          schedule: 'after 10pm and before 7am on every weekday',
+          schedule: 'after 10pm and before 7am on every weekday' as never,
         },
       };
       const parentConfig = { ...defaultConfig };
@@ -144,7 +144,7 @@ describe('config/migration', () => {
     });
     it('migrates every friday', () => {
       const config = {
-        schedule: 'every friday',
+        schedule: 'every friday' as never,
       };
       const parentConfig = { ...defaultConfig };
       const { isMigrated, migratedConfig } = configMigration.migrateConfig(
@@ -168,7 +168,7 @@ describe('config/migration', () => {
     });
     it('does not migrate every weekday', () => {
       const config = {
-        schedule: 'every weekday',
+        schedule: 'every weekday' as never,
       };
       const parentConfig = { ...defaultConfig };
       const { isMigrated, migratedConfig } = configMigration.migrateConfig(
@@ -180,7 +180,7 @@ describe('config/migration', () => {
     });
     it('does not migrate multi days', () => {
       const config = {
-        schedule: 'after 5:00pm on wednesday and thursday',
+        schedule: 'after 5:00pm on wednesday and thursday' as never,
       };
       const parentConfig = { ...defaultConfig };
       const { isMigrated, migratedConfig } = configMigration.migrateConfig(
@@ -193,7 +193,7 @@ describe('config/migration', () => {
     });
     it('does not migrate hour range', () => {
       const config = {
-        schedule: 'after 1:00pm and before 5:00pm',
+        schedule: 'after 1:00pm and before 5:00pm' as never,
       };
       const parentConfig = { ...defaultConfig };
       const { isMigrated, migratedConfig } = configMigration.migrateConfig(
diff --git a/test/workers/repository/onboarding/pr/__snapshots__/pr-list.spec.js.snap b/test/workers/repository/onboarding/pr/__snapshots__/pr-list.spec.ts.snap
similarity index 100%
rename from test/workers/repository/onboarding/pr/__snapshots__/pr-list.spec.js.snap
rename to test/workers/repository/onboarding/pr/__snapshots__/pr-list.spec.ts.snap
diff --git a/test/workers/repository/onboarding/pr/errors-warnings.spec.js b/test/workers/repository/onboarding/pr/errors-warnings.spec.js
index 02cb7f7204147e85a7dec3a2a4d8c3c3136ccc50..bbdfd32e7a2f76d803e33feee5af79a21035b880 100644
--- a/test/workers/repository/onboarding/pr/errors-warnings.spec.js
+++ b/test/workers/repository/onboarding/pr/errors-warnings.spec.js
@@ -37,7 +37,7 @@ describe('workers/repository/onboarding/pr/errors-warnings', () => {
             packageFile: 'package.json',
             deps: [
               {
-                warnings: [{ message: 'Warning 1' }],
+                warnings: [{ message: 'Warning 1', depName: undefined }],
               },
               {},
             ],
@@ -46,7 +46,7 @@ describe('workers/repository/onboarding/pr/errors-warnings', () => {
             packageFile: 'backend/package.json',
             deps: [
               {
-                warnings: [{ message: 'Warning 1' }],
+                warnings: [{ message: 'Warning 1', depName: undefined }],
               },
             ],
           },
@@ -56,7 +56,7 @@ describe('workers/repository/onboarding/pr/errors-warnings', () => {
             packageFile: 'Dockerfile',
             deps: [
               {
-                warnings: [{ message: 'Warning 2' }],
+                warnings: [{ message: 'Warning 2', depName: undefined }],
               },
             ],
           },
diff --git a/test/workers/repository/onboarding/pr/pr-list.spec.js b/test/workers/repository/onboarding/pr/pr-list.spec.ts
similarity index 86%
rename from test/workers/repository/onboarding/pr/pr-list.spec.js
rename to test/workers/repository/onboarding/pr/pr-list.spec.ts
index 8b48cfe225c83221223c99871066292f2f9fc41c..7dccb778907e84357c6caefb26efa87c380bb2f4 100644
--- a/test/workers/repository/onboarding/pr/pr-list.spec.js
+++ b/test/workers/repository/onboarding/pr/pr-list.spec.ts
@@ -1,17 +1,12 @@
-const defaultConfig = require('../../../../../lib/config/defaults').getConfig();
-
-const {
-  getPrList,
-} = require('../../../../../lib/workers/repository/onboarding/pr/pr-list');
+import { getConfig, RenovateConfig } from '../../../../util';
+import { getPrList } from '../../../../../lib/workers/repository/onboarding/pr/pr-list';
 
 describe('workers/repository/onboarding/pr/pr-list', () => {
   describe('getPrList()', () => {
-    let config;
+    let config: RenovateConfig;
     beforeEach(() => {
       jest.resetAllMocks();
-      config = {
-        ...defaultConfig,
-      };
+      config = getConfig();
     });
     it('handles emptyu', () => {
       const branches = [];
@@ -27,7 +22,7 @@ describe('workers/repository/onboarding/pr/pr-list', () => {
           upgrades: [
             {
               updateType: 'lockFileMaintenance',
-            },
+            } as never,
           ],
         },
       ];
@@ -53,7 +48,7 @@ describe('workers/repository/onboarding/pr/pr-list', () => {
               depName: 'b',
               newValue: '1.5.3',
             },
-          ],
+          ] as never,
         },
         {
           prTitle: 'Update a to v2',
@@ -66,7 +61,7 @@ describe('workers/repository/onboarding/pr/pr-list', () => {
               depType: 'devDependencies',
               newValue: '2.0.1',
               isLockfileUpdate: true,
-            },
+            } as never,
           ],
         },
       ];
diff --git a/test/workers/repository/process/__snapshots__/deprecated.spec.js.snap b/test/workers/repository/process/__snapshots__/deprecated.spec.ts.snap
similarity index 100%
rename from test/workers/repository/process/__snapshots__/deprecated.spec.js.snap
rename to test/workers/repository/process/__snapshots__/deprecated.spec.ts.snap
diff --git a/test/workers/repository/process/__snapshots__/fetch.spec.js.snap b/test/workers/repository/process/__snapshots__/fetch.spec.ts.snap
similarity index 100%
rename from test/workers/repository/process/__snapshots__/fetch.spec.js.snap
rename to test/workers/repository/process/__snapshots__/fetch.spec.ts.snap
diff --git a/test/workers/repository/process/__snapshots__/index.spec.js.snap b/test/workers/repository/process/__snapshots__/index.spec.ts.snap
similarity index 100%
rename from test/workers/repository/process/__snapshots__/index.spec.js.snap
rename to test/workers/repository/process/__snapshots__/index.spec.ts.snap
diff --git a/test/workers/repository/process/__snapshots__/sort.spec.js.snap b/test/workers/repository/process/__snapshots__/sort.spec.ts.snap
similarity index 100%
rename from test/workers/repository/process/__snapshots__/sort.spec.js.snap
rename to test/workers/repository/process/__snapshots__/sort.spec.ts.snap
diff --git a/test/workers/repository/process/deprecated.spec.js b/test/workers/repository/process/deprecated.spec.ts
similarity index 88%
rename from test/workers/repository/process/deprecated.spec.js
rename to test/workers/repository/process/deprecated.spec.ts
index 01034aec4b3e4dbc0077be8b8cbeda3e89ec90e7..42e7b9ed9d7010ccb69c57e487c94c54f6b73caf 100644
--- a/test/workers/repository/process/deprecated.spec.js
+++ b/test/workers/repository/process/deprecated.spec.ts
@@ -1,9 +1,5 @@
-const {
-  raiseDeprecationWarnings,
-} = require('../../../../lib/workers/repository/process/deprecated');
-
-/** @type any */
-const { platform } = require('../../../../lib/platform');
+import { raiseDeprecationWarnings } from '../../../../lib/workers/repository/process/deprecated';
+import { platform } from '../../../util';
 
 describe('workers/repository/process/deprecated', () => {
   describe('raiseDeprecationWarnings()', () => {
@@ -61,7 +57,7 @@ describe('workers/repository/process/deprecated', () => {
           state: 'open',
         },
       ];
-      platform.getIssueList = jest.fn(() => mockIssue);
+      platform.getIssueList.mockResolvedValue(mockIssue);
       await raiseDeprecationWarnings(config, packageFiles);
       expect(platform.ensureIssue.mock.calls).toMatchSnapshot();
       expect(platform.getIssueList).toHaveBeenCalledTimes(1);
diff --git a/test/workers/repository/process/extract-update.spec.js b/test/workers/repository/process/extract-update.spec.ts
similarity index 72%
rename from test/workers/repository/process/extract-update.spec.js
rename to test/workers/repository/process/extract-update.spec.ts
index bceaa51573f9a10f06f9b59e42234758b009c831..2b143145c33ec2e608a421015e36f23f96b457f3 100644
--- a/test/workers/repository/process/extract-update.spec.js
+++ b/test/workers/repository/process/extract-update.spec.ts
@@ -1,8 +1,6 @@
-const {
-  extractAndUpdate,
-} = require('../../../../lib/workers/repository/process/extract-update');
-/** @type any */
-const branchify = require('../../../../lib/workers/repository/updates/branchify');
+import { extractAndUpdate } from '../../../../lib/workers/repository/process/extract-update';
+import * as _branchify from '../../../../lib/workers/repository/updates/branchify';
+import { mocked } from '../../../util';
 
 jest.mock('../../../../lib/workers/repository/process/write');
 jest.mock('../../../../lib/workers/repository/process/sort');
@@ -10,6 +8,8 @@ jest.mock('../../../../lib/workers/repository/process/fetch');
 jest.mock('../../../../lib/workers/repository/updates/branchify');
 jest.mock('../../../../lib/workers/repository/extract');
 
+const branchify = mocked(_branchify);
+
 branchify.branchifyUpgrades.mockReturnValueOnce({});
 
 describe('workers/repository/process/extract-update', () => {
diff --git a/test/workers/repository/process/fetch.spec.js b/test/workers/repository/process/fetch.spec.ts
similarity index 83%
rename from test/workers/repository/process/fetch.spec.js
rename to test/workers/repository/process/fetch.spec.ts
index 056b2e8b8bdb523d4459fcba34d7b5c67fad6dab..94fcb9197900968fcf3c12017a458f9e347f2c14 100644
--- a/test/workers/repository/process/fetch.spec.js
+++ b/test/workers/repository/process/fetch.spec.ts
@@ -1,12 +1,11 @@
 import { fetchUpdates } from '../../../../lib/workers/repository/process/fetch';
 import * as _npm from '../../../../lib/manager/npm';
-import { lookupUpdates as _lookupUpdates } from '../../../../lib/workers/repository/process/lookup';
+import * as lookup from '../../../../lib/workers/repository/process/lookup';
+import { mocked } from '../../../util';
+import { ManagerApi } from '../../../../lib/manager/common';
 
-/** @type any */
-const npm = _npm;
-
-/** @type any */
-const lookupUpdates = _lookupUpdates;
+const npm: ManagerApi = _npm;
+const lookupUpdates = mocked(lookup).lookupUpdates;
 
 jest.mock('../../../../lib/workers/repository/process/lookup');
 
@@ -32,7 +31,7 @@ describe('workers/repository/process/fetch', () => {
           enabled: false,
         },
       ];
-      const packageFiles = {
+      const packageFiles: any = {
         npm: [
           {
             packageFile: 'package.json',
@@ -59,7 +58,7 @@ describe('workers/repository/process/fetch', () => {
     });
     it('fetches updates', async () => {
       config.rangeStrategy = 'auto';
-      const packageFiles = {
+      const packageFiles: any = {
         npm: [
           {
             packageFile: 'package.json',
@@ -75,8 +74,9 @@ describe('workers/repository/process/fetch', () => {
           },
         ],
       };
-      lookupUpdates.mockReturnValue(['a', 'b']);
-      npm.getPackageUpdates = jest.fn(() => ['a', 'b']);
+      // TODO: fix types
+      npm.getPackageUpdates = jest.fn(_ => ['a', 'b'] as never);
+      lookupUpdates.mockResolvedValue(['a', 'b'] as never);
       await fetchUpdates(config, packageFiles);
       expect(packageFiles).toMatchSnapshot();
       expect(packageFiles.npm[0].deps[0].skipReason).toBeUndefined();
diff --git a/test/workers/repository/process/index.spec.js b/test/workers/repository/process/index.spec.ts
similarity index 64%
rename from test/workers/repository/process/index.spec.js
rename to test/workers/repository/process/index.spec.ts
index 3f73348553518f5361c5a57462c7c18d1d84cb04..b2c04243cef0050f431e90c3f56e4f8bbfdc0d7b 100644
--- a/test/workers/repository/process/index.spec.js
+++ b/test/workers/repository/process/index.spec.ts
@@ -1,11 +1,11 @@
-const {
-  processRepo,
-} = require('../../../../lib/workers/repository/process/index');
-/** @type any */
-const extractUpdate = require('../../../../lib/workers/repository/process/extract-update');
+import { processRepo } from '../../../../lib/workers/repository/process/index';
+import * as _extractUpdate from '../../../../lib/workers/repository/process/extract-update';
+import { mocked } from '../../../util';
 
 jest.mock('../../../../lib/workers/repository/process/extract-update');
 
+const extractAndUpdate = mocked(_extractUpdate).extractAndUpdate;
+
 let config;
 beforeEach(() => {
   jest.resetAllMocks();
@@ -19,7 +19,7 @@ describe('workers/repository/process/index', () => {
       expect(res).toMatchSnapshot();
     });
     it('processes baseBranches', async () => {
-      extractUpdate.extractAndUpdate.mockReturnValue({});
+      extractAndUpdate.mockResolvedValue({} as never);
       config.baseBranches = ['branch1', 'branch2'];
       const res = await processRepo(config);
       expect(res).toMatchSnapshot();
diff --git a/test/workers/repository/process/limits.spec.js b/test/workers/repository/process/limits.spec.ts
similarity index 58%
rename from test/workers/repository/process/limits.spec.js
rename to test/workers/repository/process/limits.spec.ts
index 3db2692f9dd7b06318dca1e66d9ba1ff579211fc..6db1619c84d5ed1cf53a9ffbffc37c804086015d 100644
--- a/test/workers/repository/process/limits.spec.js
+++ b/test/workers/repository/process/limits.spec.ts
@@ -1,29 +1,31 @@
-const moment = require('moment');
-/** @type any */
-const limits = require('../../../../lib/workers/repository/process/limits');
+import moment from 'moment';
+import * as limits from '../../../../lib/workers/repository/process/limits';
+import { platform, getConfig, RenovateConfig } from '../../../util';
 
-/** @type any */
-const { platform } = require('../../../../lib/platform');
-
-let config;
+let config: RenovateConfig;
 beforeEach(() => {
   jest.resetAllMocks();
-  config = { ...require('../../../config/config/_fixtures') };
+  config = getConfig();
 });
 
 describe('workers/repository/process/limits', () => {
   describe('getPrHourlyRemaining()', () => {
     it('calculates hourly limit remaining', async () => {
       config.prHourlyLimit = 2;
-      platform.getPrList.mockReturnValueOnce([
-        { created_at: moment().format() },
+      platform.getPrList.mockResolvedValueOnce([
+        {
+          created_at: moment().format(),
+          branchName: null,
+          title: null,
+          state: null,
+        },
       ]);
       const res = await limits.getPrHourlyRemaining(config);
       expect(res).toEqual(1);
     });
     it('returns 99 if errored', async () => {
       config.prHourlyLimit = 2;
-      platform.getPrList.mockReturnValueOnce([null]);
+      platform.getPrList.mockResolvedValueOnce([null]);
       const res = await limits.getPrHourlyRemaining(config);
       expect(res).toEqual(99);
     });
@@ -31,8 +33,8 @@ describe('workers/repository/process/limits', () => {
   describe('getConcurrentPrsRemaining()', () => {
     it('calculates concurrent limit remaining', async () => {
       config.prConcurrentLimit = 20;
-      platform.branchExists.mockReturnValueOnce(true);
-      const branches = [{}, {}];
+      platform.branchExists.mockResolvedValueOnce(true);
+      const branches = [{ branchName: 'test' }, { branchName: undefined }];
       const res = await limits.getConcurrentPrsRemaining(config, branches);
       expect(res).toEqual(19);
     });
@@ -41,17 +43,17 @@ describe('workers/repository/process/limits', () => {
       expect(res).toEqual(99);
     });
   });
+
   describe('getPrsRemaining()', () => {
     it('returns hourly limit', async () => {
-      limits.getPrHourlyRemaining = jest.fn(() => 5);
-      limits.getConcurrentPrsRemaining = jest.fn(() => 10);
-      const res = await limits.getPrsRemaining();
+      config.prHourlyLimit = 5;
+      platform.getPrList.mockResolvedValueOnce([]);
+      const res = await limits.getPrsRemaining(config, []);
       expect(res).toEqual(5);
     });
     it('returns concurrent limit', async () => {
-      limits.getPrHourlyRemaining = jest.fn(() => 10);
-      limits.getConcurrentPrsRemaining = jest.fn(() => 5);
-      const res = await limits.getPrsRemaining();
+      config.prConcurrentLimit = 5;
+      const res = await limits.getPrsRemaining(config, []);
       expect(res).toEqual(5);
     });
   });
diff --git a/test/workers/repository/process/lookup/__snapshots__/index.spec.js.snap b/test/workers/repository/process/lookup/__snapshots__/index.spec.ts.snap
similarity index 100%
rename from test/workers/repository/process/lookup/__snapshots__/index.spec.js.snap
rename to test/workers/repository/process/lookup/__snapshots__/index.spec.ts.snap
diff --git a/test/workers/repository/process/lookup/index.spec.js b/test/workers/repository/process/lookup/index.spec.ts
similarity index 95%
rename from test/workers/repository/process/lookup/index.spec.js
rename to test/workers/repository/process/lookup/index.spec.ts
index 7db0e55342cae3ae6b6b26a77df4ef6164734e31..8b02b70b89dcc49b42e7059f2533c7b30bc9699a 100644
--- a/test/workers/repository/process/lookup/index.spec.js
+++ b/test/workers/repository/process/lookup/index.spec.ts
@@ -1,29 +1,29 @@
-const nock = require('nock');
-const lookup = require('../../../../../lib/workers/repository/process/lookup');
-const qJson = require('../../../../config/npm/_fixtures/01.json');
-const helmetJson = require('../../../../config/npm/_fixtures/02.json');
-const coffeelintJson = require('../../../../config/npm/_fixtures/coffeelint.json');
-const webpackJson = require('../../../../config/npm/_fixtures/webpack.json');
-const nextJson = require('../../../../config/npm/_fixtures/next.json');
-const vueJson = require('../../../../config/npm/_fixtures/vue.json');
-const typescriptJson = require('../../../../config/npm/_fixtures/typescript.json');
-/** @type any */
-const docker = require('../../../../../lib/datasource/docker');
-/** @type any */
-const gitSubmodules = require('../../../../../lib/datasource/git-submodules');
-const defaults = require('../../../../../lib/config/defaults');
+import nock from 'nock';
+import * as lookup from '../../../../../lib/workers/repository/process/lookup';
+import qJson from '../../../../config/npm/_fixtures/01.json';
+import helmetJson from '../../../../config/npm/_fixtures/02.json';
+import coffeelintJson from '../../../../config/npm/_fixtures/coffeelint.json';
+import webpackJson from '../../../../config/npm/_fixtures/webpack.json';
+import nextJson from '../../../../config/npm/_fixtures/next.json';
+import vueJson from '../../../../config/npm/_fixtures/vue.json';
+import typescriptJson from '../../../../config/npm/_fixtures/typescript.json';
+import * as _docker from '../../../../../lib/datasource/docker';
+import * as _gitSubmodules from '../../../../../lib/datasource/git-submodules';
+import { mocked, getConfig } from '../../../../util';
 
 jest.mock('../../../../../lib/datasource/docker');
 jest.mock('../../../../../lib/datasource/git-submodules');
 
 qJson.latestVersion = '1.4.1';
 
-/** @type any */
+const docker = mocked(_docker);
+const gitSubmodules = mocked(_gitSubmodules);
+
 let config;
 
 describe('workers/repository/process/lookup', () => {
   beforeEach(() => {
-    config = { ...defaults.getConfig() };
+    config = getConfig();
     config.manager = 'npm';
     config.versionScheme = 'npm';
     config.rangeStrategy = 'replace';
@@ -1087,7 +1087,7 @@ describe('workers/repository/process/lookup', () => {
       config.depName = 'node';
       config.datasource = 'docker';
       config.pinDigests = true;
-      docker.getPkgReleases.mockReturnValueOnce({
+      docker.getPkgReleases.mockResolvedValueOnce({
         releases: [
           {
             version: '8.0.0',
@@ -1097,8 +1097,8 @@ describe('workers/repository/process/lookup', () => {
           },
         ],
       });
-      docker.getDigest.mockReturnValueOnce('sha256:abcdef1234567890');
-      docker.getDigest.mockReturnValueOnce('sha256:0123456789abcdef');
+      docker.getDigest.mockResolvedValueOnce('sha256:abcdef1234567890');
+      docker.getDigest.mockResolvedValueOnce('sha256:0123456789abcdef');
       const res = await lookup.lookupUpdates(config);
       expect(res).toMatchSnapshot();
     });
@@ -1108,7 +1108,7 @@ describe('workers/repository/process/lookup', () => {
         config.depName = 'node';
         config.datasource = 'docker';
         config.versionScheme = 'docker';
-        docker.getPkgReleases.mockReturnValueOnce({
+        docker.getPkgReleases.mockResolvedValueOnce({
           releases: [
             { version: '8.1.0' },
             { version: '8.1.5' },
@@ -1130,7 +1130,7 @@ describe('workers/repository/process/lookup', () => {
       config.depName = 'node';
       config.datasource = 'docker';
       config.pinDigests = true;
-      docker.getPkgReleases.mockReturnValueOnce({
+      docker.getPkgReleases.mockResolvedValueOnce({
         releases: [
           {
             version: '8.0.0',
@@ -1140,7 +1140,7 @@ describe('workers/repository/process/lookup', () => {
           },
         ],
       });
-      docker.getDigest.mockReturnValueOnce('sha256:abcdef1234567890');
+      docker.getDigest.mockResolvedValueOnce('sha256:abcdef1234567890');
       const res = await lookup.lookupUpdates(config);
       expect(res).toMatchSnapshot();
     });
@@ -1149,7 +1149,7 @@ describe('workers/repository/process/lookup', () => {
       config.depName = 'node';
       config.datasource = 'docker';
       config.pinDigests = true;
-      docker.getPkgReleases.mockReturnValueOnce({
+      docker.getPkgReleases.mockResolvedValueOnce({
         releases: [
           {
             version: '8.0.0',
@@ -1162,7 +1162,7 @@ describe('workers/repository/process/lookup', () => {
           },
         ],
       });
-      docker.getDigest.mockReturnValueOnce('sha256:abcdef1234567890');
+      docker.getDigest.mockResolvedValueOnce('sha256:abcdef1234567890');
       const res = await lookup.lookupUpdates(config);
       expect(res).toMatchSnapshot();
     });
@@ -1171,7 +1171,7 @@ describe('workers/repository/process/lookup', () => {
       config.depName = 'node';
       config.datasource = 'docker';
       config.pinDigests = true;
-      docker.getPkgReleases.mockReturnValueOnce({
+      docker.getPkgReleases.mockResolvedValueOnce({
         releases: [
           {
             version: '8.0.0',
@@ -1184,7 +1184,7 @@ describe('workers/repository/process/lookup', () => {
           },
         ],
       });
-      docker.getDigest.mockReturnValueOnce(null);
+      docker.getDigest.mockResolvedValueOnce(null);
       const res = await lookup.lookupUpdates(config);
       expect(res.updates).toHaveLength(0);
     });
@@ -1194,7 +1194,7 @@ describe('workers/repository/process/lookup', () => {
       config.datasource = 'docker';
       config.currentDigest = 'sha256:zzzzzzzzzzzzzzz';
       config.pinDigests = true;
-      docker.getPkgReleases.mockReturnValueOnce({
+      docker.getPkgReleases.mockResolvedValueOnce({
         releases: [
           {
             version: '8.0.0',
@@ -1204,8 +1204,8 @@ describe('workers/repository/process/lookup', () => {
           },
         ],
       });
-      docker.getDigest.mockReturnValueOnce('sha256:abcdef1234567890');
-      docker.getDigest.mockReturnValueOnce('sha256:0123456789abcdef');
+      docker.getDigest.mockResolvedValueOnce('sha256:abcdef1234567890');
+      docker.getDigest.mockResolvedValueOnce('sha256:0123456789abcdef');
       const res = await lookup.lookupUpdates(config);
       expect(res).toMatchSnapshot();
     });
@@ -1215,7 +1215,7 @@ describe('workers/repository/process/lookup', () => {
       config.datasource = 'docker';
       config.currentDigest = 'sha256:zzzzzzzzzzzzzzz';
       config.pinDigests = true;
-      docker.getPkgReleases.mockReturnValueOnce({
+      docker.getPkgReleases.mockResolvedValueOnce({
         releases: [
           {
             version: 'alpine',
@@ -1228,14 +1228,14 @@ describe('workers/repository/process/lookup', () => {
           },
         ],
       });
-      docker.getDigest.mockReturnValueOnce('sha256:abcdef1234567890');
+      docker.getDigest.mockResolvedValueOnce('sha256:abcdef1234567890');
       const res = await lookup.lookupUpdates(config);
       expect(res).toMatchSnapshot();
     });
     it('handles git submodule update', async () => {
       config.datasource = 'gitSubmodules';
       config.versionScheme = 'git';
-      gitSubmodules.getPkgReleases.mockReturnValueOnce({
+      gitSubmodules.getPkgReleases.mockResolvedValueOnce({
         releases: [
           {
             version: '4b825dc642cb6eb9a060e54bf8d69288fbee4904',
diff --git a/test/workers/repository/process/sort.spec.js b/test/workers/repository/process/sort.spec.ts
similarity index 93%
rename from test/workers/repository/process/sort.spec.js
rename to test/workers/repository/process/sort.spec.ts
index 63d24e11435a413ecc3a45c67cb06db726e66a51..1800330eff77a5b3cfa8712649f0367d51ec2bd3 100644
--- a/test/workers/repository/process/sort.spec.js
+++ b/test/workers/repository/process/sort.spec.ts
@@ -1,6 +1,4 @@
-const {
-  sortBranches,
-} = require('../../../../lib/workers/repository/process/sort');
+import { sortBranches } from '../../../../lib/workers/repository/process/sort';
 
 describe('workers/repository/process/sort', () => {
   describe('sortBranches()', () => {
diff --git a/test/workers/repository/process/write.spec.js b/test/workers/repository/process/write.spec.js
deleted file mode 100644
index 0a40870c9227f1ed26de091e5de5bfcc210274ab..0000000000000000000000000000000000000000
--- a/test/workers/repository/process/write.spec.js
+++ /dev/null
@@ -1,39 +0,0 @@
-const {
-  writeUpdates,
-} = require('../../../../lib/workers/repository/process/write');
-/** @type any */
-const branchWorker = require('../../../../lib/workers/branch');
-/** @type any */
-const limits = require('../../../../lib/workers/repository/process/limits');
-/** @type any */
-
-branchWorker.processBranch = jest.fn();
-
-limits.getPrsRemaining = jest.fn(() => 99);
-
-let config;
-beforeEach(() => {
-  jest.resetAllMocks();
-  config = { ...require('../../../config/config/_fixtures') };
-});
-
-describe('workers/repository/write', () => {
-  describe('writeUpdates()', () => {
-    const packageFiles = {};
-    it('skips branches blocked by pin', async () => {
-      const branches = [{ updateType: 'pin' }, { blockedByPin: true }, {}];
-      const res = await writeUpdates(config, packageFiles, branches);
-      expect(res).toEqual('done');
-      expect(branchWorker.processBranch).toHaveBeenCalledTimes(2);
-    });
-    it('stops after automerge', async () => {
-      const branches = [{}, {}, {}, {}];
-      branchWorker.processBranch.mockReturnValueOnce('created');
-      branchWorker.processBranch.mockReturnValueOnce('delete');
-      branchWorker.processBranch.mockReturnValueOnce('automerged');
-      const res = await writeUpdates(config, packageFiles, branches);
-      expect(res).toEqual('automerged');
-      expect(branchWorker.processBranch).toHaveBeenCalledTimes(3);
-    });
-  });
-});
diff --git a/test/workers/repository/process/write.spec.ts b/test/workers/repository/process/write.spec.ts
new file mode 100644
index 0000000000000000000000000000000000000000..dfff63fd6e0bb82beb82841d34215c3f96379d9f
--- /dev/null
+++ b/test/workers/repository/process/write.spec.ts
@@ -0,0 +1,43 @@
+import { writeUpdates } from '../../../../lib/workers/repository/process/write';
+import * as _branchWorker from '../../../../lib/workers/branch';
+import * as _limits from '../../../../lib/workers/repository/process/limits';
+import { mocked, getConfig, RenovateConfig } from '../../../util';
+import { BranchConfig } from '../../../../lib/workers/common';
+
+const branchWorker = mocked(_branchWorker);
+const limits = mocked(_limits);
+
+branchWorker.processBranch = jest.fn();
+
+limits.getPrsRemaining = jest.fn().mockResolvedValue(99);
+
+let config: RenovateConfig;
+beforeEach(() => {
+  jest.resetAllMocks();
+  config = getConfig();
+});
+
+describe('workers/repository/write', () => {
+  describe('writeUpdates()', () => {
+    const packageFiles = {};
+    it('skips branches blocked by pin', async () => {
+      const branches: BranchConfig[] = [
+        { updateType: 'pin' },
+        { blockedByPin: true },
+        {},
+      ] as never;
+      const res = await writeUpdates(config, packageFiles, branches);
+      expect(res).toEqual('done');
+      expect(branchWorker.processBranch).toHaveBeenCalledTimes(2);
+    });
+    it('stops after automerge', async () => {
+      const branches: BranchConfig[] = [{}, {}, {}, {}] as never;
+      branchWorker.processBranch.mockResolvedValueOnce('pr-created');
+      branchWorker.processBranch.mockResolvedValueOnce('already-existed');
+      branchWorker.processBranch.mockResolvedValueOnce('automerged');
+      const res = await writeUpdates(config, packageFiles, branches);
+      expect(res).toEqual('automerged');
+      expect(branchWorker.processBranch).toHaveBeenCalledTimes(3);
+    });
+  });
+});