diff --git a/.eslintignore b/.eslintignore
index dd358e38fe3be7b963ed943ce80e6e607ce98105..eb68c90aa4911d91c9f024df890a3e4190a6160d 100644
--- a/.eslintignore
+++ b/.eslintignore
@@ -13,3 +13,4 @@ coverage
 
 # generated typescript code
 **/*.generated.ts
+
diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index 6a7e86f668b5e36636c7140f441bf0094a3fef5e..5056e46b93c0f11149b06272375549919115bce7 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -259,8 +259,8 @@ jobs:
   release:
     needs: [lint, test, test-docker]
     runs-on: ubuntu-latest
-    # release shouldn't need more than 30 min
-    timeout-minutes: 30
+    # release shouldn't need more than 5 min
+    timeout-minutes: 5
 
     steps:
       - name: Set up Node.js ${{ env.NODE_VERSION }}
@@ -282,7 +282,6 @@ jobs:
       - uses: actions/checkout@v2
 
       - name: Cache Yarn packages
-        id: yarn_cache_packages
         uses: actions/cache@v1
         with:
           path: ${{ steps.init.outputs.yarn_cache }}
@@ -297,28 +296,6 @@ jobs:
       - name: Installing dependencies
         run: yarn install --frozen-lockfile --link-duplicates
 
-      - name: Build
-        run: yarn build
-
-      - name: Set up Docker Buildx ${{ env.BUILDX_VERSION }}
-        uses: crazy-max/ghaction-docker-buildx@v1
-        with:
-          version: ${{ env.BUILDX_VERSION }}
-
-      - name: Docker registry login
-        if: github.ref == 'refs/heads/master'
-        run: echo "${{ secrets.DOCKER_RENOVATERELEASE_TOKEN }}" | docker login -u renovaterelease --password-stdin
-
-      - name: Update Docker images cache
-        continue-on-error: true
-        if: github.ref == 'refs/heads/master'
-        run: |
-          docker buildx bake \
-            --progress plain \
-            --file docker/bake.hcl \
-            --file docker/cache.hcl \
-            cache
-
       - name: semantic-release
         run: |
           echo '//registry.npmjs.org/:_authToken=${NPM_TOKEN}' >> ~/.npmrc
diff --git a/.github/workflows/release-docker.yml b/.github/workflows/release-docker.yml
index 758530d2b88a376683bbf5ff305fc877dcaf6104..0b5840588bb0738099733b2075f3eb57101d75e4 100644
--- a/.github/workflows/release-docker.yml
+++ b/.github/workflows/release-docker.yml
@@ -3,14 +3,80 @@ on:
   repository_dispatch:
     types: [renovate-release]
 
+env:
+  CI: true
+  DOCKER_REPO: renovate/renovate
+  YARN_CACHE_KEY: v1
+  BUILDX_VERSION: v0.3.1
+  NODE_VERSION: 12
+  # https://github.com/chalk/supports-color/issues/106
+  FORCE_COLOR: true
+
 jobs:
-  release:
+  cache-docker:
+    runs-on: ubuntu-latest
+    steps:
+      - name: Init platform
+        id: init
+        run: |
+          git config --global core.autocrlf false
+          git config --global core.symlinks true
+          git config --global user.email 'bot@renovateapp.com'
+          git config --global user.name  'Renovate Bot'
+
+      - uses: actions/checkout@v2
+        with:
+          ref: ${{ github.event.client_payload.sha }}
+
+      - name: Set up Docker Buildx ${{ env.BUILDX_VERSION }}
+        uses: crazy-max/ghaction-docker-buildx@v1
+        with:
+          version: ${{ env.BUILDX_VERSION }}
+
+      - name: Docker registry login
+        run: echo "${{ secrets.DOCKER_RENOVATERELEASE_TOKEN }}" | docker login -u renovaterelease --password-stdin
+
+      - name: Update Docker images cache
+        continue-on-error: true
+        run: |
+          docker buildx bake \
+            --progress plain \
+            --file docker/bake.hcl \
+            --file docker/cache.hcl \
+            cache
+
+  release-docker:
     runs-on: ubuntu-latest
     steps:
+      - name: Set up Node.js ${{ env.NODE_VERSION }}
+        uses: actions/setup-node@v1
+        with:
+          node-version: ${{ env.NODE_VERSION }}
+
+      - name: Init platform
+        id: init
+        run: |
+          git config --global core.autocrlf false
+          git config --global core.symlinks true
+          git config --global user.email 'bot@renovateapp.com'
+          git config --global user.name  'Renovate Bot'
+
       - uses: actions/checkout@v2
         with:
-          ref: ${{ github.event.client_payload.ref }}
+          ref: ${{ github.event.client_payload.sha }}
+
+      - name: Set up Docker Buildx ${{ env.BUILDX_VERSION }}
+        uses: crazy-max/ghaction-docker-buildx@v1
+        with:
+          version: ${{ env.BUILDX_VERSION }}
+
+      - name: Docker registry login
+        run: echo "${{ secrets.DOCKER_RENOVATERELEASE_TOKEN }}" | docker login -u renovaterelease --password-stdin
+
+      - name: Prepare ${{ github.event.client_payload.version }}
+        run: |
+          npm --no-git-tag-version version ${{ github.event.client_payload.version }}
 
-      - run: echo 'docker release'
-      - run: echo ${{ github.event.client_payload.sha }}
-      - run: echo ${{ github.event.client_payload.version }}
+      - name: Publish ${{ github.event.client_payload.version }}
+        run: |
+          ./.github/workflows/release-docker.sh ${{ github.event.client_payload.version }} ${{ github.event.client_payload.sha }}
diff --git a/.github/workflows/release-npm.yml b/.github/workflows/release-npm.yml
index 6aff7fc71a3348200b60bc06bc504705b8545009..6423ebe0da29e6250792037536c487ab2950478f 100644
--- a/.github/workflows/release-npm.yml
+++ b/.github/workflows/release-npm.yml
@@ -3,14 +3,64 @@ on:
   repository_dispatch:
     types: [renovate-release]
 
+env:
+  CI: true
+  YARN_CACHE_KEY: v1
+  BUILDX_VERSION: v0.3.1
+  NODE_VERSION: 12
+  # https://github.com/chalk/supports-color/issues/106
+  FORCE_COLOR: true
+
 jobs:
-  release:
+  release-npm:
     runs-on: ubuntu-latest
     steps:
+      - name: Set up Node.js ${{ env.NODE_VERSION }}
+        uses: actions/setup-node@v1
+        with:
+          node-version: ${{ env.NODE_VERSION }}
+
+      - name: Init platform
+        id: init
+        run: |
+          echo "::set-output name=yarn_cache::$(yarn cache dir)"
+          git config --global core.autocrlf false
+          git config --global core.symlinks true
+          git config --global user.email 'bot@renovateapp.com'
+          git config --global user.name  'Renovate Bot'
+          yarn config set version-git-tag false
+          npm config set scripts-prepend-node-path true
+
       - uses: actions/checkout@v2
         with:
-          ref: ${{ github.event.client_payload.ref }}
+          ref: ${{ github.event.client_payload.sha }}
+
+      - name: Cache Yarn packages
+        id: yarn_cache_packages
+        uses: actions/cache@v1
+        with:
+          path: ${{ steps.init.outputs.yarn_cache }}
+          key: ${{ env.YARN_CACHE_KEY }}-${{ runner.os }}-yarn_cache-${{ hashFiles('**/yarn.lock') }}
+
+      - name: Cache node_modules
+        uses: actions/cache@v1
+        with:
+          path: node_modules
+          key: ${{ runner.os }}-${{ env.NODE_VERSION }}-yarn-${{ hashFiles('**/yarn.lock') }}
+
+      - name: Installing dependencies
+        run: yarn install --frozen-lockfile --link-duplicates
+
+      - name: Build ${{ github.event.client_payload.version }}
+        run: yarn build
+
+      - name: Prepare ${{ github.event.client_payload.version }}
+        run: |
+          npm --no-git-tag-version version ${{ github.event.client_payload.version }}
 
-      - run: echo 'npm release'
-      - run: echo ${{ github.event.client_payload.sha }}
-      - run: echo ${{ github.event.client_payload.version }}
+      - name: Publish ${{ github.event.client_payload.version }}
+        run: |
+          echo '//registry.npmjs.org/:_authToken=${NPM_TOKEN}' >> ~/.npmrc
+          npm publish
+        env:
+          NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
diff --git a/.gitignore b/.gitignore
index 1a12fbfd8637ac64d54d1d3fb915113741f3b542..7df61596ac4aa195e374f1dc4b956b52766898bf 100644
--- a/.gitignore
+++ b/.gitignore
@@ -16,5 +16,7 @@ junit.xml
 /test-results
 renovate-schema.json
 
+# generated code
 **/*.generated.ts
+tools/dist
 test/datasource/nuget/_fixtures/obj
diff --git a/.prettierignore b/.prettierignore
index 1edda6b04ce61838aa69248071ba11c7c6ea6359..e7b8a8db914ebd23b730d80663cb8672223a909e 100644
--- a/.prettierignore
+++ b/.prettierignore
@@ -15,3 +15,4 @@ bin/yarn*
 
 # generated typescript code
 **/*.generated.ts
+tools/dist
diff --git a/package.json b/package.json
index f5da19f36b13d0eda0f1ddcca775a4987a5be80d..22e7ba3f44d6f7c6602a102bcf6adc0e743d156f 100644
--- a/package.json
+++ b/package.json
@@ -9,7 +9,7 @@
   "scripts": {
     "build": "run-s clean generate:* compile:* copy-static-files",
     "build:docker": "run-s generate:* compile:ts copy-static-files",
-    "clean": "rimraf dist lib/**/*.generated.ts",
+    "clean": "rimraf dist tools/dist lib/**/*.generated.ts",
     "clean-cache": "node bin/clean-cache.js",
     "compile:ts": "tsc -p tsconfig.app.json",
     "compile:dts": "tsc -p tsconfig.dts.json",
diff --git a/tools/release.mjs b/tools/release.mjs
index 8d8e9e5fb2f271753f2ad09c9b575f7f0b8072b7..e3783ddf464e44b9a568835b01c6966e008b27b0 100644
--- a/tools/release.mjs
+++ b/tools/release.mjs
@@ -1,29 +1,29 @@
 import shell from 'shelljs';
-import { program, exec } from './utils.mjs';
+import { program } from './utils.mjs';
 
 const version = program.release;
-const sha = program.sha;
+// const sha = program.sha;
 
-let err = false;
+// let err = false;
 
 shell.echo(`Publishing version: ${version}`);
 
-shell.echo('Publishing npm package ...');
-if (
-  !exec(`npm --no-git-tag-version version ${version}`) ||
-  !exec(`npm publish`)
-) {
-  err = true;
-}
+// shell.echo('Publishing npm package ...');
+// if (
+//   !exec(`npm --no-git-tag-version version ${version}`) ||
+//   !exec(`npm publish`)
+// ) {
+//   err = true;
+// }
 
-shell.echo('Publishing docker images ...');
-if (!exec(`./.github/workflows/release-docker.sh ${version} ${sha}`)) {
-  err = true;
-}
+// shell.echo('Publishing docker images ...');
+// if (!exec(`./.github/workflows/release-docker.sh ${version} ${sha}`)) {
+//   err = true;
+// }
 
 // eslint-disable-next-line promise/valid-params
 import('./dispatch-release.mjs').catch();
 
-if (err) {
-  shell.exit(2);
-}
+// if (err) {
+//   shell.exit(2);
+// }