diff --git a/.github/workflows/bintray.yml b/.github/workflows/bintray.yml
deleted file mode 100644
index 719ce36bf..000000000
--- a/.github/workflows/bintray.yml
+++ /dev/null
@@ -1,123 +0,0 @@
-# This is a basic workflow to help you get started with Actions
-
-name: Bintray Publish
-
-# Controls when the action will run. Triggers the workflow on push or pull request 
-# events but only for the master branch
-on:
-  release:
-    types: [ created, prereleased ]
-  push:
-    tags:
-      - '*-dev*'
-
-# A workflow run is made up of one or more jobs that can run sequentially or in parallel
-jobs:
-  # This workflow contains a single job called "build"
-  publish-mirai:
-    runs-on: ubuntu-latest
-    steps:
-      - name: Checkout repository
-        uses: actions/checkout@v2
-
-      - name: Checkout submodules
-        run: git submodule update --init --recursive --remote
-
-      - name: Set up JDK 1.8
-        uses: actions/setup-java@v1
-        with:
-          java-version: 1.8
-
-      - name: chmod -R 777 *
-        run: chmod -R 777 *
-
-      - name: Init gradle project
-        run: ./gradlew clean --info
-
-      - name: Check keys
-        run: >
-          ./gradlew :mirai-core-utils:ensureBintrayAvailable
-          :mirai-core-api:ensureBintrayAvailable
-          :mirai-core:ensureBintrayAvailable
-          :mirai-console:ensureBintrayAvailable
-          -Dbintray_user=${{ secrets.BINTRAY_USER }} -Pbintray_user=${{ secrets.BINTRAY_USER }}
-          -Dbintray_key=${{ secrets.BINTRAY_KEY }} -Pbintray_key=${{ secrets.BINTRAY_KEY }}
-
-      - name: fillBuildConstants
-        run: >
-          ./gradlew
-          fillBuildConstants --info --stacktrace
-          -Dbintray_user=${{ secrets.BINTRAY_USER }} -Pbintray_user=${{ secrets.BINTRAY_USER }}
-          -Dbintray_key=${{ secrets.BINTRAY_KEY }} -Pbintray_key=${{ secrets.BINTRAY_KEY }}
-
-      - name: Assemble
-        run: ./gradlew assemble --info --stacktrace
-
-      - name: Check
-        run: ./gradlew check --info --stacktrace
-
-      - name: Gradle :mirai-core-utils:publish
-        run: >
-          ./gradlew :mirai-core-utils:publish --info --stacktrace
-          -Dbintray_user=${{ secrets.BINTRAY_USER }} -Pbintray_user=${{ secrets.BINTRAY_USER }}
-          -Dbintray_key=${{ secrets.BINTRAY_KEY }} -Pbintray_key=${{ secrets.BINTRAY_KEY }}
-
-      - name: Gradle :mirai-core-api:publish
-        run: >
-          ./gradlew :mirai-core-api:publish --info --stacktrace
-          -Dbintray_user=${{ secrets.BINTRAY_USER }} -Pbintray_user=${{ secrets.BINTRAY_USER }}
-          -Dbintray_key=${{ secrets.BINTRAY_KEY }} -Pbintray_key=${{ secrets.BINTRAY_KEY }}
-
-      - name: Gradle :mirai-core:publish
-        run: >
-          ./gradlew :mirai-core:publish --info --stacktrace
-          -Dbintray_user=${{ secrets.BINTRAY_USER }} -Pbintray_user=${{ secrets.BINTRAY_USER }}
-          -Dbintray_key=${{ secrets.BINTRAY_KEY }} -Pbintray_key=${{ secrets.BINTRAY_KEY }}
-
-      - name: Gradle :mirai-core-all:bintrayUpload
-        run: >
-          ./gradlew :mirai-core-all:bintrayUpload --info
-          -Dbintray_user=${{ secrets.BINTRAY_USER }} -Pbintray_user=${{ secrets.BINTRAY_USER }}
-          -Dbintray_key=${{ secrets.BINTRAY_KEY }} -Pbintray_key=${{ secrets.BINTRAY_KEY }}
-
-      - name: Gradle :mirai-console:bintrayUpload
-        run: >
-          ./gradlew
-          :mirai-console:bintrayUpload --info
-          -Dbintray_user=${{ secrets.BINTRAY_USER }} -Pbintray_user=${{ secrets.BINTRAY_USER }}
-          -Dbintray_key=${{ secrets.BINTRAY_KEY }} -Pbintray_key=${{ secrets.BINTRAY_KEY }}
-
-      - name: Gradle :mirai-console-terminal:bintrayUpload
-        run: >
-          ./gradlew
-          :mirai-console-terminal:bintrayUpload --info
-          -Dbintray_user=${{ secrets.BINTRAY_USER }} -Pbintray_user=${{ secrets.BINTRAY_USER }}
-          -Dbintray_key=${{ secrets.BINTRAY_KEY }} -Pbintray_key=${{ secrets.BINTRAY_KEY }}
-
-      - name: Gradle :mirai-console-compiler-common:bintrayUpload
-        run: >
-          ./gradlew
-          :mirai-console-compiler-common:bintrayUpload --info
-          -Dbintray_user=${{ secrets.BINTRAY_USER }} -Pbintray_user=${{ secrets.BINTRAY_USER }}
-          -Dbintray_key=${{ secrets.BINTRAY_KEY }} -Pbintray_key=${{ secrets.BINTRAY_KEY }}
-
-      - name: Gradle :mirai-console-compiler-annotations:bintrayUpload
-        run: >
-          ./gradlew
-          :mirai-console-compiler-annotations:bintrayUpload --info
-          -Dbintray_user=${{ secrets.BINTRAY_USER }} -Pbintray_user=${{ secrets.BINTRAY_USER }}
-          -Dbintray_key=${{ secrets.BINTRAY_KEY }} -Pbintray_key=${{ secrets.BINTRAY_KEY }}
-
-      - name: Gradle :mirai-console-intellij:bintrayUpload
-        run: >
-          ./gradlew
-          :mirai-console-intellij:bintrayUpload --info
-          -Dbintray_user=${{ secrets.BINTRAY_USER }} -Pbintray_user=${{ secrets.BINTRAY_USER }}
-          -Dbintray_key=${{ secrets.BINTRAY_KEY }} -Pbintray_key=${{ secrets.BINTRAY_KEY }}
-
-      - name: Publish Gradle plugin
-        run: >
-          ./gradlew
-          :mirai-console-gradle:publishPlugins --info --stacktrace
-          -Dgradle.publish.key=${{ secrets.GRADLE_PUBLISH_KEY }} -Pgradle.publish.key=${{ secrets.GRADLE_PUBLISH_KEY }}
-          -Dgradle.publish.secret=${{ secrets.GRADLE_PUBLISH_SECRET }} -Pgradle.publish.secret=${{ secrets.GRADLE_PUBLISH_SECRET }}
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
new file mode 100644
index 000000000..933e45141
--- /dev/null
+++ b/.github/workflows/release.yml
@@ -0,0 +1,120 @@
+# This is a basic workflow to help you get started with Actions
+
+name: Release Publish
+
+# Controls when the action will run. Triggers the workflow on push or pull request 
+# events but only for the master branch
+on:
+  release:
+    types: [ created, prereleased ]
+  push:
+    tags:
+      - '*-dev*'
+
+# A workflow run is made up of one or more jobs that can run sequentially or in parallel
+jobs:
+  # This workflow contains a single job called "build"
+  publish-mirai:
+    runs-on: ubuntu-latest
+    steps:
+      - name: Checkout repository
+        uses: actions/checkout@v2
+
+      - name: Checkout submodules
+        run: git submodule update --init --recursive --remote
+
+      - name: Set up JDK 1.8
+        uses: actions/setup-java@v1
+        with:
+          java-version: 1.8
+
+      - name: chmod -R 777 *
+        run: chmod -R 777 *
+
+      - name: Init gradle project
+        run: ./gradlew clean --info
+
+      - name: Keys setup
+        shell: bash
+        run: |
+          mkdir build-gpg-sign
+          echo "$GPG_PRIVATE" > build-gpg-sign/keys.gpg
+          echo "$GPG_PUBLIC_" > build-gpg-sign/keys.gpg.pub
+          mkdir build-secret-keys
+          echo "$SONATYPE_USER" > build-secret-keys/sonatype.key
+          echo "$SONATYPE_KEY" >> build-secret-keys/sonatype.key
+          echo "$BINTRAY_USER" > build-secret-keys/bintray.key
+          echo "$BINTRAY_KEY" >> build-secret-keys/bintray.key
+        env:
+          GPG_PRIVATE: ${{ secrets.GPG_PRIVATE_KEY }}
+          GPG_PUBLIC_: ${{ secrets.GPG_PUBLIC_KEY }}
+          SONATYPE_USER: ${{ secrets.SONATYPE_USER }}
+          SONATYPE_KEY: ${{ secrets.SONATYPE_KEY }}
+          BINTRAY_USER: ${{ secrets.BINTRAY_USER }}
+          BINTRAY_KEY: ${{ secrets.BINTRAY_KEY }}
+
+      - name: Check keys
+        run: >
+          ./gradlew
+          :mirai-core-utils:ensureBintrayAvailable
+          :mirai-core-api:ensureBintrayAvailable
+          :mirai-core:ensureBintrayAvailable
+          :mirai-console:ensureBintrayAvailable
+          :mirai-core-utils:ensureMavenCentralAvailable
+          :mirai-core-api:ensureMavenCentralAvailable
+          :mirai-core:ensureMavenCentralAvailable
+          :mirai-console:ensureMavenCentralAvailable
+
+      - name: fillBuildConstants
+        run: >
+          ./gradlew
+          fillBuildConstants --info --stacktrace
+
+      - name: Assemble
+        run: ./gradlew assemble --info --stacktrace
+
+      - name: Check
+        run: ./gradlew check --info --stacktrace
+
+      - name: Gradle :mirai-core-utils:publish
+        run: >
+          ./gradlew :mirai-core-utils:publish --info --stacktrace
+
+      - name: Gradle :mirai-core-api:publish
+        run: >
+          ./gradlew :mirai-core-api:publish --info --stacktrace
+
+      - name: Gradle :mirai-core:publish
+        run: >
+          ./gradlew :mirai-core:publish --info --stacktrace
+
+      - name: Gradle :mirai-core-all:publish
+        run: >
+          ./gradlew :mirai-core-all:publish --info
+
+      - name: Gradle :mirai-console:publish
+        run: >
+          ./gradlew
+          :mirai-console:publish --info
+
+      - name: Gradle :mirai-console-terminal:publish
+        run: >
+          ./gradlew
+          :mirai-console-terminal:publish --info
+
+      - name: Gradle :mirai-console-compiler-common:publish
+        run: >
+          ./gradlew
+          :mirai-console-compiler-common:publish --info
+
+      - name: Gradle :mirai-console-compiler-annotations:publish
+        run: >
+          ./gradlew
+          :mirai-console-compiler-annotations:publish --info
+
+      - name: Publish Gradle plugin
+        run: >
+          ./gradlew
+          :mirai-console-gradle:publishPlugins --info --stacktrace
+          -Dgradle.publish.key=${{ secrets.GRADLE_PUBLISH_KEY }} -Pgradle.publish.key=${{ secrets.GRADLE_PUBLISH_KEY }}
+          -Dgradle.publish.secret=${{ secrets.GRADLE_PUBLISH_SECRET }} -Pgradle.publish.secret=${{ secrets.GRADLE_PUBLISH_SECRET }}
diff --git a/buildSrc/src/main/kotlin/GpgSigner.kt b/buildSrc/src/main/kotlin/GpgSigner.kt
index 9b17d7c2d..8ee91e941 100644
--- a/buildSrc/src/main/kotlin/GpgSigner.kt
+++ b/buildSrc/src/main/kotlin/GpgSigner.kt
@@ -57,14 +57,14 @@ open class GpgSigner(private val workdir: File) {
                     if (keyFilePub.isFile) {
                         signer.importKey(keyFilePub)
                     } else {
-                        rootProject.logger.warn("Missing public key storage")
-                        rootProject.logger.warn("GPG Sign 2nd verity may failed.")
+                        println("[GPG SIGN] Missing public key storage")
+                        println("[GPG SIGN] GPG Sign 2nd verity may failed.")
                     }
                 }
             } else {
-                rootProject.logger.warn("GPG Key not found.")
-                rootProject.logger.warn("GPG Signer will not setup")
-                rootProject.logger.warn("Key file location: $keyFile")
+                println("[GPG SIGN] GPG Key not found.")
+                println("[GPG SIGN] GPG Signer will not setup")
+                println("[GPG SIGN] Key file location: $keyFile")
             }
         }
     }
diff --git a/buildSrc/src/main/kotlin/JvmPublishing.kt b/buildSrc/src/main/kotlin/JvmPublishing.kt
index 0ff429720..3a996f364 100644
--- a/buildSrc/src/main/kotlin/JvmPublishing.kt
+++ b/buildSrc/src/main/kotlin/JvmPublishing.kt
@@ -30,6 +30,18 @@ fun Project.configureRemoteRepos() {
             }
         }
     }
+    tasks.register("ensureMavenCentralAvailable") {
+        doLast {
+            if (GpgSigner.signer == GpgSigner.NoopSigner) {
+                error("GPG Signer isn't available.")
+            }
+            val keys = SecretKeys.getCache(project)
+            if (!keys.loadKey("sonatype").isValid) {
+                error("Maven Central isn't available.")
+            }
+        }
+    }
+
     publishing {
         // sonatype
         val keys = SecretKeys.getCache(project)
diff --git a/buildSrc/src/main/kotlin/keys/SecretKeys.kt b/buildSrc/src/main/kotlin/keys/SecretKeys.kt
index 6338cffec..e849e5f99 100644
--- a/buildSrc/src/main/kotlin/keys/SecretKeys.kt
+++ b/buildSrc/src/main/kotlin/keys/SecretKeys.kt
@@ -10,6 +10,7 @@
 package keys
 
 import org.gradle.api.Project
+import java.io.BufferedReader
 
 open class SecretKeys(
     val type: String,
@@ -66,7 +67,15 @@ open class SecretKeys(
                     ?: secretKeys.resolve("$type.key.txt")
                 if (secretKeyFile.isFile) {
                     secretKeyFile.bufferedReader().use {
-                        return SecretKeys(type, it.readLine().trim(), it.readLine().trim())
+                        fun BufferedReader.readLineNonEmpty(): String {
+                            while (true) {
+                                val nextLine = readLine() ?: return ""
+                                if (nextLine.isNotBlank()) {
+                                    return nextLine.trim()
+                                }
+                            }
+                        }
+                        return SecretKeys(type, it.readLineNonEmpty(), it.readLineNonEmpty())
                     }
                 }
             }