IGNITE-16847 Add release profile, GitHub Actions and scripts for extensions release (#121)

diff --git a/.github/workflows/prepare-rc.yml b/.github/workflows/prepare-rc.yml
new file mode 100644
index 0000000..a11eece
--- /dev/null
+++ b/.github/workflows/prepare-rc.yml
@@ -0,0 +1,198 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+
+#
+# This action will produce a zip-archive with all the stuff required for signing and
+# deploying an extension release candidate maven artifacts, extension sources and
+# binary zip-archive (if applicable). It will also create a rc-tag pointed to the last
+# commit in the release branch.
+#
+
+name: "Extension Prepare Release Candidate"
+
+on: workflow_dispatch
+
+env:
+  SERVER_URL: 'https://dist.apache.org/repos/dist/dev/ignite/ignite-extensions/'
+
+jobs:
+  prepare:
+    if: github.repository == 'apache/ignite-extensions'
+    runs-on: ubuntu-latest
+    name: Prepare RC for `${{ github.ref_name }}`
+    steps:
+      - name: Validate Extension Release Branch
+        id: check
+        run: | 
+          prefix='false'
+          [[ ${{ github.ref_name }} =~ ^release/ ]] && prefix='true'
+          echo "::set-output name=isReleaseBranch::${prefix}"
+
+      - name: Interrupt If not a Release Branch
+        if: ${{ steps.check.outputs.isReleaseBranch == 'false' }}
+        uses: actions/github-script@v3
+        with:
+          script: |
+            core.setFailed("You should run this action from the release branch which has the 'release/' prefix: ${{ github.ref_name }} ")
+
+      - name: Setup Inputs
+        shell: bash
+        # see https://www.gnu.org/software/bash/manual/html_node/Shell-Parameter-Expansion.html
+        run: |
+          branch=${{ github.ref_name }}
+          ext=${branch#"release/"}
+          ext_ver=${ext##*-}
+          ext_name=${ext%-*}
+          ext_dir=modules/${ext_name#"ignite-"}
+          echo "Extension Version:     $ext_ver"
+          echo "Extension Module Name: $ext_name"
+          echo "Extension Directory:   $ext_dir"
+          echo "EXTENSION_VERSION=${ext_ver}" >> $GITHUB_ENV
+          echo "EXTENSION_NAME=${ext_name}" >> $GITHUB_ENV
+          echo "EXTENSION_DIR=${ext_dir}" >> $GITHUB_ENV
+          echo "EXTENSION_BRANCH=${{ github.ref_name }}" >> $GITHUB_ENV
+
+      - name: Checkout Release Branch
+        uses: actions/checkout@v3
+        with:
+          ref: ${{ github.ref_name }}
+
+      - name: Fetch Release Tags
+        run: |
+          git fetch --prune --unshallow --tags
+          echo $(git tag -l)
+          echo "GIT_HOME=$(pwd)" >> $GITHUB_ENV
+
+      - name: Set up Java
+        uses: actions/setup-java@v2
+        with:
+          java-version: 8
+          distribution: 'adopt'
+
+      - name: Extract POM Version and Compare With Branch Version
+        id: pom
+        shell: bash
+        run: |
+          mvn -pl ${{ env.EXTENSION_DIR }} help:evaluate -Dexpression=project.artifactId
+          ver=$(mvn -pl ${{ env.EXTENSION_DIR }} help:evaluate -Dexpression=project.version -q -DforceStdout)
+          pom_ver=$(echo ${ver} | sed -e 's/^[[:space:]]*//')
+          missmatch='true'
+          [ "$pom_ver" == "${{ env.EXTENSION_VERSION }}" ] && missmatch='false'
+          echo "Extension pom version: ${pom_ver}"
+          echo "::set-output name=versionMissmatch::${missmatch}"
+          echo "VERSION_POM=${pom_ver}" >> $GITHUB_ENV
+
+      - name: Compare Release Versions With Branch Version
+        if: ${{ steps.pom.outputs.versionMissmatch == 'true' }}
+        uses: actions/github-script@v3
+        with:
+          script: |
+            core.setFailed('Versions missmatch [branch=${{ env.EXTENSION_VERSION }}, pom=${{ env.VERSION_POM }}]')
+
+      # Get the RC tag reachable from the branch HEAD matching pattern.
+      - name: Extracting Release RC tag
+        shell: bash
+        run: |
+          tag_prefix=${{ env.EXTENSION_NAME }}-${{ env.EXTENSION_VERSION }}-rc
+          git describe --match "${tag_prefix}*" --abbrev=0 --tags HEAD || true
+          branch_tag=$(git describe --match "${tag_prefix}*" --abbrev=0 --tags HEAD || true)
+          rc_tag=$(echo ${branch_tag:-${tag_prefix}0})
+          rc_tag_id=$((${rc_tag#"${tag_prefix}"} + 1))
+          new_tag=${tag_prefix}${rc_tag_id}
+          echo "New Extension RC tag: ${new_tag}"
+          echo "EXTENSION_RC_TAG=${new_tag}" >> $GITHUB_ENV
+
+      - name: Prepare Release Properties
+        run: |
+          dist=${{ env.GIT_HOME }}/target/${{ env.EXTENSION_RC_TAG }}
+          mkdir -p ${dist} && cd "$_"
+          touch release.properties
+          echo EXTENSION_NAME=${{ env.EXTENSION_NAME}} >> release.properties
+          echo EXTENSION_VERSION=${{ env.EXTENSION_VERSION}} >> release.properties
+          echo EXTENSION_RC_TAG=${{ env.EXTENSION_RC_TAG}} >> release.properties
+          echo EXTENSION_DIR=${{ env.EXTENSION_DIR}} >> release.properties
+          echo EXTENSION_BRANCH=${{ env.EXTENSION_BRANCH}} >> release.properties
+          echo revision=$(git rev-list --max-count=1 HEAD 2>/dev/null || true) >> release.properties
+          cat release.properties
+          echo "EXTENSION_DIST=${dist}" >> $GITHUB_ENV
+
+      # The mvn must be started from the module root directory to collect assembly sources.
+      - name: Build Java and Prepare Packages
+        run: |
+          cd ${{ env.GIT_HOME }}/${{ env.EXTENSION_DIR }}
+          mvn deploy -am -DskipTests -Pextension-release -DuniqueVersion=false ${toLocalRepo} 
+          cd -
+        env:
+          toLocalRepo: '-D altDeploymentRepository=local::default::file:${{ env.EXTENSION_DIST }}/maven'
+
+      - name: Check there is no SNAPSHOT versions
+        run: mvn -f ${{ env.EXTENSION_DIR }} -am org.apache.maven.plugins:maven-enforcer-plugin:3.0.0-M3:enforce -Drules=requireReleaseVersion,requireReleaseDeps
+
+      - name: Copy Binary and Sources
+        run: |
+          svn_dir=${{ env.EXTENSION_DIST }}/svn/vote
+          mkdir -p ${svn_dir}
+          cd ${{ env.GIT_HOME }}/${{ env.EXTENSION_DIR }}
+          list=$(find . -regex '.*\.zip' -o -regex '.*\.zip\.sha512')
+          for file in $list; do cp -v ${file} ${svn_dir}; done
+          cd -
+
+      - name: Copy Release Scripts
+        run: |
+          cd ${{ env.GIT_HOME }}
+          cp -v ./scripts/vote* ${{ env.EXTENSION_DIST }}
+          cp -v ./scripts/settings.xml ${{ env.EXTENSION_DIST }}
+          chmod +x ${{ env.EXTENSION_DIST }}/*.sh
+
+      - name: Create RC tag `${{ env.EXTENSION_RC_TAG }}`
+        uses: actions/github-script@v5
+        with:
+          script: |
+            github.rest.git.createRef({
+              owner: context.repo.owner,
+              repo: context.repo.repo,
+              ref: 'refs/tags/${{ env.EXTENSION_RC_TAG }}',
+              sha: context.sha
+            })
+
+      - name: Checkout Sources Into Distribution
+        uses: actions/checkout@v3
+        with:
+          path: ${{ env.EXTENSION_DIST }}/git
+          ref: ${{ github.ref_name }}
+
+      - name: Configure Git for Release
+        run: |
+          cd ${{ env.EXTENSION_DIST }}/git
+          git config user.name github-actions
+          git config user.email github-actions@github.com
+          git fetch --prune --unshallow --tags
+
+      - name: Zip the Distribution
+        run: |
+          sudo apt-get -y install zip
+          cd ${{ env.EXTENSION_DIST }}/..
+          zip -r ${{ env.EXTENSION_RC_TAG }}.zip ${{ env.EXTENSION_RC_TAG }}/
+          cd -
+
+      - name: Upload Job Artifacts
+        uses: actions/upload-artifact@v3
+        with:
+          name: ${{ env.EXTENSION_RC_TAG }}
+          path: ${{ env.GIT_HOME }}/target/${{ env.EXTENSION_RC_TAG }}.zip
diff --git a/.github/workflows/release-checker.yml b/.github/workflows/release-checker.yml
new file mode 100644
index 0000000..4bfb3a4
--- /dev/null
+++ b/.github/workflows/release-checker.yml
@@ -0,0 +1,125 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+
+#
+# This action will check that an extension release candidate is ready for the vote
+# (verify checksums, verify the release signature, rc tag is exist etc.).
+#
+
+name: "Extension Check Release Candidate"
+
+on:
+  workflow_dispatch:
+    inputs:
+      extension-name:
+        description: 'The name of Ignite Extension (e.g. ignite-aws-ext)'
+        required: true
+      release-version:
+        description: 'The Extension release version (e.g. 1.0.0)'
+        required: true
+
+env:
+  SERVER_URL: 'https://dist.apache.org/repos/dist/dev/ignite/ignite-extensions/'
+
+jobs:
+  check:
+    if: github.repository == 'apache/ignite-extensions'
+    runs-on: ubuntu-latest
+    steps:
+      - name: Setup Inputs
+        id: vars
+        shell: bash
+        # see https://www.gnu.org/software/bash/manual/html_node/Shell-Parameter-Expansion.html
+        run: |
+          name=${{ github.event.inputs.extension-name }}
+          ver=${{ github.event.inputs.release-version }}
+          mod_ver=$(echo ${ver} | sed -e 's/^[[:space:]]*//')
+          mod_name=$(echo ${name} | sed -e 's/^[[:space:]]*//')
+          mod_dir=modules/${name#"ignite-"}
+          echo "Extension Version:     $mod_ver"
+          echo "Extension Module Name: $mod_name"
+          echo "Extension Directory:   $mod_dir"
+          echo "EXTENSION_VERSION=${mod_ver}" >> $GITHUB_ENV
+          echo "EXTENSION_NAME=${mod_name}" >> $GITHUB_ENV
+          echo "EXTENSION_DIR=${mod_dir}" >> $GITHUB_ENV
+
+      - name: Checkout Release Branch
+        uses: actions/checkout@v3
+        with:
+          ref: 'release/${{ github.event.inputs.extension-name }}-${{ github.event.inputs.release-version }}'
+
+      - name: Checkout Release tags
+        run: |
+          git fetch --prune --unshallow --tags
+          echo $(git tag -l)
+          echo "GIT_ROOT=$(pwd)" >> $GITHUB_ENV
+
+      - name: Set up Java
+        uses: actions/setup-java@v2
+        with:
+          java-version: 8
+          distribution: 'adopt'
+
+      - name: Extract Branch POM Version and Compare
+        shell: bash
+        run: |
+          mvn -pl ${{ env.EXTENSION_DIR }} help:evaluate -Dexpression=project.artifactId
+          ver=$(mvn -pl ${{ env.EXTENSION_DIR }} help:evaluate -Dexpression=project.version -q -DforceStdout)
+          pom_ver=$(echo ${ver} | sed -e 's/^[[:space:]]*//')
+          missmatch='true'
+          [ "$pom_ver" == "${{ env.EXTENSION_VERSION }}" ] && missmatch='false'
+          echo "Extension pom version: ${pom_ver}"
+          echo "VERSIONS_MISMATCH=${missmatch}" >> $GITHUB_ENV
+          echo "VERSION_POM=${pom_ver}" >> $GITHUB_ENV
+
+      - name: Compare Release Versions With Branch Version
+        if: ${{ env.VERSIONS_MISMATCH == 'true' }}
+        uses: actions/github-script@v3
+        with:
+          script: |
+            core.setFailed('Versions missmatch [branch=${{ env.EXTENSION_VERSION }}, pom=${{ env.VERSION_POM }}]')
+
+      # The RC tag must points to the last commit in the release branch.
+      - name: Extracting RC tag
+        run: |
+          rc_tag=$(git describe --tags --exact-match --abbrev=0)
+          echo "Extension RC tag: ${rc_tag}"
+          echo "EXTENSION_RC_TAG=${rc_tag}" >> $GITHUB_ENV
+
+      - name: Download Binary and Sources
+        run: |
+          wget --recursive --no-parent --no-directories --tries=3 --retry-on-http-error=429,503,504 --accept '.zip,.asc,.sha512' \
+            --execute robots=off "${{ env.SERVER_URL }}${{ env.EXTENSION_RC_TAG }}/" -P ${{ env.EXTENSION_RC_TAG }}
+          ls ${{ env.EXTENSION_RC_TAG }}
+
+      - name: Validate Binary and Sources Checksums
+        run: |
+          cd ${{ env.EXTENSION_RC_TAG }}
+          sha512sum -c *.sha512
+
+      - name: Validate PGP Signatures
+        run: |
+          wget https://dist.apache.org/repos/dist/release/ignite/KEYS
+          gpg --import KEYS
+          for asc in $(find . -name "*.asc" -type f); do gpg --verify $asc; done
+
+      - name: Extenstion Sources Compilation with Checkstyle
+        run: |
+          cd ${{ env.GIT_ROOT }}
+          mvn install -f ${{ env.EXTENSION_DIR }} -am -Pcheckstyle -DskipTests -B -V
diff --git a/DEVNOTES.md b/DEVNOTES.md
new file mode 100644
index 0000000..b484beb
--- /dev/null
+++ b/DEVNOTES.md
@@ -0,0 +1,119 @@
+# NOTES
+
+---
+
+## Build Instructions
+
+### Build all Extensions
+
+```shell
+mvn clean install -DskipTests -Pcheckstyle
+```
+
+### Build an Extension
+
+```shell
+mvn clean install -f modules/sptring-boot-ext -Pcheckstyle
+```
+
+OR
+
+```shell
+mvn clean install -pl :ignite-aws-ext -am -Pcheckstyle
+```
+
+## Release Instructions
+
+### Prerequisites
+
+- Personal PGP Key Pair (see [Generating a Key Pair][1])  
+- GnuGP installed (see [Installing GnuPG][2])
+- Repository credentials configured (see [scripts/settings.xml][3])
+- You're using an encrypted your ASF password (see [Maven Password Encryption Guide][4])
+
+You can refer to the [Release Publishing Guide][5] and [Publishing Maven Releases to Maven Central Repository][6] 
+of the Apache Software Foundation release process for better understanding the whole process.
+
+[1]: <https://central.sonatype.org/publish/requirements/gpg/#generating-a-key-pair> "Generating a Key Pair"
+[2]: <https://central.sonatype.org/publish/requirements/gpg/#installing-gnupg> "Installing GnuPG"
+[3]: <https://github.com/apache/ignite-extensions/blob/master/scripts/settings.xml> "Extensions settings.xml"
+[4]: <https://maven.apache.org/guides/mini/guide-encryption.html> "Maven Encryption Guide"
+[5]: <https://infra.apache.org/release-publishing.html#distribution> "Apache Software Foundation the Release Publishing Guide"
+[6]: <https://infra.apache.org/publishing-maven-artifacts.html> "Publishing Maven Releases to Maven Central Repository"
+
+### Prepare a new Release Candidate
+
+- Create and push an extension release branch with the following branch name format: `release/[extension-project-name]-[extension-version]`.
+
+   ```shell
+   git remote set-url origin https://github.com/apache/ignite-extensions.git
+   git checkout master
+   git checkout -b release/ignite-aws-ext-1.0.0
+   git push origin release/ignite-aws-ext-1.0.0
+   ```
+
+- Update Extension parent reference version and the extension module version using the `scripts/update-versions.sh`.
+
+   ```shell
+   # Usage: scripts/update-versions.sh [<ignite-parent-version>] <module-path> <module-release-version>
+   scripts/update-versions.sh [2.13.0] modules/asw-ext/ 1.0.0
+   ```
+  
+- Run the [Extension Prepare Release Candidate][7] GitHub Action using the release branch as job source 
+this job will also create a rc-tag which points to the last commit in the release branch.
+- From the execution job result download the `zip` artifact containing all the stuff required for 
+signing and deploying release artifacts.
+- Run the `vote_[mvn][pgp]_jar_deploy.sh` to sign and deploy extensions jar's to Maven Central.
+- Run the `vote_[pgp]_sign_dist.sh` to sign the extension binary and source zip-archives.
+- Run the `vote_[svn]_upload_dist.sh` to upload signed zip-archives.
+- Run the [Extension Check Release Candidate][8] GitHub Action to verify the papered release candidate.
+
+
+[7]: <https://github.com/apache/ignite-extensions/actions/workflows/prepare-rc.yml> "Extension Prepare Release Candidate"
+[8]: <https://github.com/apache/ignite-extensions/actions/workflows/release-checker.yml> "Extension Check Release Candidate"
+
+## Development Instructions
+
+### Running GitHub Actions Locally
+
+Configure the `act` command line utility. When you run `act` it reads projects GitHub Actions 
+from `.github/workflows/` and determines the set of actions that need to be run on Docker image. 
+
+Use the following installation guide to install the `act` command:
+https://github.com/nektos/act/blob/master/README.md#installation
+
+#### Run
+
+```shell
+act --job check --eventpath event.json -s GITHUB_TOKEN=[your_fork_github_token]
+```
+
+The `event.json`:
+
+```json
+{
+  "action": "workflow_dispatch",
+  "inputs": {
+    "extension-name": "ignite-zookeeper-ip-finder-ext",
+    "release-version": "1.0.0"
+  }
+}
+```
+
+#### Troubleshooting
+
+The `act` command executes the workflow in a docker container. Some docker images may not have 
+the `mvn` command pre-installed. Thus, you have to install it in the docker container manually
+as an action step. Use the step below to install Maven into container:
+
+```yaml
+- name: Download Maven
+  run: |
+    curl -sL https://www-eu.apache.org/dist/maven/maven-3/3.6.3/binaries/apache-maven-3.6.3-bin.zip -o maven.zip
+    apt-get update
+    apt-get -y install unzip
+    unzip -d /usr/share maven.zip
+    rm maven.zip
+    ln -s /usr/share/apache-maven-3.6.3/bin/mvn /usr/bin/mvn
+    echo "M2_HOME=/usr/share/apache-maven-3.6.3" | tee -a /etc/environment
+```
diff --git a/DEVNOTES.txt b/DEVNOTES.txt
deleted file mode 100644
index 59bdff9..0000000
--- a/DEVNOTES.txt
+++ /dev/null
@@ -1,23 +0,0 @@
-Apache Ignite Extensions Maven Build Instructions
-================================================
-
-1) Compile and install:
-	
-	mvn clean install
-
-
-Maven Build Instructions For Released Apache Ignite Extension
-=============================================================
-
-NOTE: The release sources package of an Apache Ignite extension provides not only released module sources. The sources
-of other modules from the package are development copy and should not be built.
-
-1) Compile and install:
-
-    mvn -pl modules/%MODULE_NAME% clean install
-
-    where the %MODULE_NAME% is a released extension module name.
-
-    Example:
-
-    mvn -pl modules/spring-data-ext clean install
diff --git a/assembly/bin-component-shared.xml b/assembly/bin-component-shared.xml
new file mode 100644
index 0000000..9712c64
--- /dev/null
+++ b/assembly/bin-component-shared.xml
@@ -0,0 +1,50 @@
+<?xml version='1.0' encoding='UTF-8'?>
+
+<!--
+  Licensed to the Apache Software Foundation (ASF) under one
+  or more contributor license agreements.  See the NOTICE file
+  distributed with this work for additional information
+  regarding copyright ownership.  The ASF licenses this file
+  to you under the Apache License, Version 2.0 (the
+  "License"); you may not use this file except in compliance
+  with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing,
+  software distributed under the License is distributed on an
+  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+  KIND, either express or implied.  See the License for the
+  specific language governing permissions and limitations
+  under the License.
+-->
+
+<component>
+    <fileSets>
+        <fileSet>
+            <directory>${project.build.directory}</directory>
+            <outputDirectory>${project.artifactId}/libs/${project.artifactId}</outputDirectory>
+            <includes>
+                <include>${project.build.finalName}.${project.packaging}</include>
+            </includes>
+        </fileSet>
+        <fileSet>
+            <directory>${project.build.directory}/libs</directory>
+            <outputDirectory>${project.artifactId}/libs/${project.artifactId}</outputDirectory>
+        </fileSet>
+        <!-- license, dependencies, notice, etc. calculated at build time -->
+        <fileSet>
+            <directory>${project.build.directory}/maven-shared-archive-resources/META-INF</directory>
+            <outputDirectory>${project.artifactId}</outputDirectory>
+        </fileSet>
+        <!-- readme, release_notes etc. -->
+        <fileSet>
+            <directory>${project.basedir}</directory>
+            <outputDirectory>${project.artifactId}</outputDirectory>
+            <includes>
+                <include>RELEASE_NOTES*</include>
+                <include>README*</include>
+            </includes>
+        </fileSet>
+    </fileSets>
+</component>
diff --git a/assembly/source-release.xml b/assembly/source-release.xml
new file mode 100644
index 0000000..21cf9d8
--- /dev/null
+++ b/assembly/source-release.xml
@@ -0,0 +1,74 @@
+<?xml version='1.0' encoding='UTF-8'?>
+
+<!--
+  Licensed to the Apache Software Foundation (ASF) under one
+  or more contributor license agreements.  See the NOTICE file
+  distributed with this work for additional information
+  regarding copyright ownership.  The ASF licenses this file
+  to you under the Apache License, Version 2.0 (the
+  "License"); you may not use this file except in compliance
+  with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing,
+  software distributed under the License is distributed on an
+  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+  KIND, either express or implied.  See the License for the
+  specific language governing permissions and limitations
+  under the License.
+-->
+
+<assembly xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.3"
+          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+          xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.3
+          http://maven.apache.org/xsd/assembly-1.1.3.xsd">
+    <id>src</id>
+
+    <formats>
+        <format>zip</format>
+    </formats>
+
+    <fileSets>
+        <!-- main project directory structure -->
+        <fileSet>
+            <directory>.</directory>
+            <outputDirectory>modules/${project.artifactId}</outputDirectory>
+            <useDefaultExcludes>true</useDefaultExcludes>
+            <excludes>
+                <!-- build output -->
+                <exclude>%regex[(?!((?!${project.build.directory}/)[^/]+/)*src/).*${project.build.directory}.*]</exclude>
+
+                <!-- IDEs -->
+                <exclude>%regex[(?!((?!${project.build.directory}/)[^/]+/)*src/)(.*/)?[^/]*\.iml]</exclude>
+
+                <!-- misc -->
+                <exclude>%regex[(?!((?!${project.build.directory}/)[^/]+/)*src/)(.*/)?pom\.xml\.releaseBackup]</exclude>
+                <exclude>%regex[(?!((?!${project.build.directory}/)[^/]+/)*src/)(.*/)?release\.properties]</exclude>
+                <exclude>%regex[(?!((?!${project.build.directory}/)[^/]+/)*src/)(.*/)?pom\-installed\.xml]</exclude>
+            </excludes>
+        </fileSet>
+        <!-- license, dependencies, notice, etc. calculated at build time -->
+        <fileSet>
+            <directory>${project.build.directory}/maven-shared-archive-resources/META-INF</directory>
+            <outputDirectory/>
+        </fileSet>
+        <!-- parent pom-->
+        <fileSet>
+            <directory>${project.basedir}/../../parent-internal</directory>
+            <outputDirectory>parent-internal</outputDirectory>
+            <includes>
+                <include>pom.xml</include>
+            </includes>
+        </fileSet>
+        <!-- readme, release_notes etc. -->
+        <fileSet>
+            <directory>${project.basedir}/../../</directory>
+            <outputDirectory/>
+            <includes>
+                <include>*.txt</include>
+                <include>*.md</include>
+            </includes>
+        </fileSet>
+    </fileSets>
+</assembly>
diff --git a/modules/aws-ext/assembly/aws-ext.xml b/modules/aws-ext/assembly/aws-ext.xml
index 953bd36..0c28f4c 100644
--- a/modules/aws-ext/assembly/aws-ext.xml
+++ b/modules/aws-ext/assembly/aws-ext.xml
@@ -21,25 +21,14 @@
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2
           http://maven.apache.org/xsd/assembly-1.1.2.xsd">
-    <id>cdc-ext</id>
-
+    <id>bin</id>
     <includeBaseDirectory>false</includeBaseDirectory>
 
     <formats>
         <format>zip</format>
     </formats>
 
-    <fileSets>
-        <fileSet>
-            <directory>${project.build.directory}</directory>
-            <outputDirectory>/libs/optional/ignite-aws-ext</outputDirectory>
-            <includes>
-                <include>${project.build.finalName}.${project.packaging}</include>
-            </includes>
-        </fileSet>
-        <fileSet>
-            <directory>${project.build.directory}/libs</directory>
-            <outputDirectory>/libs/optional/ignite-aws-ext</outputDirectory>
-        </fileSet>
-    </fileSets>
+    <componentDescriptors>
+        <componentDescriptor>../../assembly/bin-component-shared.xml</componentDescriptor>
+    </componentDescriptors>
 </assembly>
diff --git a/modules/aws-ext/pom.xml b/modules/aws-ext/pom.xml
index 4e3d114..07c31d7 100644
--- a/modules/aws-ext/pom.xml
+++ b/modules/aws-ext/pom.xml
@@ -231,27 +231,6 @@
                     </execution>
                 </executions>
             </plugin>
-
-            <plugin>
-                <artifactId>maven-assembly-plugin</artifactId>
-                <executions>
-                    <execution>
-                        <id>aws-ext</id>
-                        <goals>
-                            <goal>single</goal>
-                        </goals>
-                        <phase>package</phase>
-                        <configuration>
-                            <appendAssemblyId>false</appendAssemblyId>
-                            <descriptors>
-                                <descriptor>assembly/aws-ext.xml</descriptor>
-                            </descriptors>
-                            <finalName>ignite-aws-ext</finalName>
-                            <attach>false</attach>
-                        </configuration>
-                    </execution>
-                </executions>
-            </plugin>
         </plugins>
     </build>
 </project>
diff --git a/modules/azure-ext/assembly/azure-ext.xml b/modules/azure-ext/assembly/azure-ext.xml
index b3635fc..0c28f4c 100644
--- a/modules/azure-ext/assembly/azure-ext.xml
+++ b/modules/azure-ext/assembly/azure-ext.xml
@@ -21,25 +21,14 @@
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2
           http://maven.apache.org/xsd/assembly-1.1.2.xsd">
-    <id>cdc-ext</id>
-
+    <id>bin</id>
     <includeBaseDirectory>false</includeBaseDirectory>
 
     <formats>
         <format>zip</format>
     </formats>
 
-    <fileSets>
-        <fileSet>
-            <directory>${project.build.directory}</directory>
-            <outputDirectory>/libs/optional/ignite-azure-ext</outputDirectory>
-            <includes>
-                <include>${project.build.finalName}.${project.packaging}</include>
-            </includes>
-        </fileSet>
-        <fileSet>
-            <directory>${project.build.directory}/libs</directory>
-            <outputDirectory>/libs/optional/ignite-azure-ext</outputDirectory>
-        </fileSet>
-    </fileSets>
+    <componentDescriptors>
+        <componentDescriptor>../../assembly/bin-component-shared.xml</componentDescriptor>
+    </componentDescriptors>
 </assembly>
diff --git a/modules/azure-ext/pom.xml b/modules/azure-ext/pom.xml
index e42d4be..25455d6 100644
--- a/modules/azure-ext/pom.xml
+++ b/modules/azure-ext/pom.xml
@@ -392,27 +392,6 @@
                     </execution>
                 </executions>
             </plugin>
-
-            <plugin>
-                <artifactId>maven-assembly-plugin</artifactId>
-                <executions>
-                    <execution>
-                        <id>azure-ext</id>
-                        <goals>
-                            <goal>single</goal>
-                        </goals>
-                        <phase>package</phase>
-                        <configuration>
-                            <appendAssemblyId>false</appendAssemblyId>
-                            <descriptors>
-                                <descriptor>assembly/azure-ext.xml</descriptor>
-                            </descriptors>
-                            <finalName>ignite-azure-ext</finalName>
-                            <attach>false</attach>
-                        </configuration>
-                    </execution>
-                </executions>
-            </plugin>
         </plugins>
     </build>
 </project>
diff --git a/modules/cdc-ext/assembly/cdc-ext.xml b/modules/cdc-ext/assembly/cdc-ext.xml
index baaee78..a911d24 100644
--- a/modules/cdc-ext/assembly/cdc-ext.xml
+++ b/modules/cdc-ext/assembly/cdc-ext.xml
@@ -21,29 +21,21 @@
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2
           http://maven.apache.org/xsd/assembly-1.1.2.xsd">
-    <id>cdc-ext</id>
-
+    <id>bin</id>
     <includeBaseDirectory>false</includeBaseDirectory>
 
     <formats>
         <format>zip</format>
     </formats>
 
+    <componentDescriptors>
+        <componentDescriptor>../../assembly/bin-component-shared.xml</componentDescriptor>
+    </componentDescriptors>
+
     <fileSets>
         <fileSet>
-            <directory>${project.build.directory}</directory>
-            <outputDirectory>/libs/optional/ignite-cdc-ext</outputDirectory>
-            <includes>
-                <include>${project.build.finalName}.${project.packaging}</include>
-            </includes>
-        </fileSet>
-        <fileSet>
-            <directory>${project.build.directory}/libs</directory>
-            <outputDirectory>/libs/optional/ignite-cdc-ext</outputDirectory>
-        </fileSet>
-        <fileSet>
             <directory>${basedir}/bin</directory>
-            <outputDirectory>/bin</outputDirectory>
+            <outputDirectory>${project.artifactId}/bin</outputDirectory>
         </fileSet>
     </fileSets>
 </assembly>
diff --git a/modules/cdc-ext/pom.xml b/modules/cdc-ext/pom.xml
index dc880af..45fc4fb 100644
--- a/modules/cdc-ext/pom.xml
+++ b/modules/cdc-ext/pom.xml
@@ -139,26 +139,6 @@
                     </execution>
                 </executions>
             </plugin>
-            <plugin>
-                <artifactId>maven-assembly-plugin</artifactId>
-                <executions>
-                    <execution>
-                        <id>cdc-ext</id>
-                        <goals>
-                            <goal>single</goal>
-                        </goals>
-                        <phase>package</phase>
-                        <configuration>
-                            <appendAssemblyId>false</appendAssemblyId>
-                            <descriptors>
-                                <descriptor>assembly/cdc-ext.xml</descriptor>
-                            </descriptors>
-                            <finalName>ignite-cdc-ext</finalName>
-                            <attach>false</attach>
-                        </configuration>
-                    </execution>
-                </executions>
-            </plugin>
         </plugins>
     </build>
 </project>
diff --git a/modules/gce-ext/assembly/gce-ext.xml b/modules/gce-ext/assembly/gce-ext.xml
index 4642b60..0c28f4c 100644
--- a/modules/gce-ext/assembly/gce-ext.xml
+++ b/modules/gce-ext/assembly/gce-ext.xml
@@ -21,25 +21,14 @@
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2
           http://maven.apache.org/xsd/assembly-1.1.2.xsd">
-    <id>cdc-ext</id>
-
+    <id>bin</id>
     <includeBaseDirectory>false</includeBaseDirectory>
 
     <formats>
         <format>zip</format>
     </formats>
 
-    <fileSets>
-        <fileSet>
-            <directory>${project.build.directory}</directory>
-            <outputDirectory>/libs/optional/ignite-gce-ext</outputDirectory>
-            <includes>
-                <include>${project.build.finalName}.${project.packaging}</include>
-            </includes>
-        </fileSet>
-        <fileSet>
-            <directory>${project.build.directory}/libs</directory>
-            <outputDirectory>/libs/optional/ignite-gce-ext</outputDirectory>
-        </fileSet>
-    </fileSets>
+    <componentDescriptors>
+        <componentDescriptor>../../assembly/bin-component-shared.xml</componentDescriptor>
+    </componentDescriptors>
 </assembly>
diff --git a/modules/gce-ext/pom.xml b/modules/gce-ext/pom.xml
index 628e359..6b63a65 100644
--- a/modules/gce-ext/pom.xml
+++ b/modules/gce-ext/pom.xml
@@ -127,28 +127,6 @@
                     </execution>
                 </executions>
             </plugin>
-
-            <plugin>
-                <artifactId>maven-assembly-plugin</artifactId>
-                <executions>
-                    <execution>
-                        <id>gce-ext</id>
-                        <goals>
-                            <goal>single</goal>
-                        </goals>
-                        <phase>package</phase>
-                        <configuration>
-                            <appendAssemblyId>false</appendAssemblyId>
-                            <descriptors>
-                                <descriptor>assembly/gce-ext.xml</descriptor>
-                            </descriptors>
-                            <finalName>ignite-gce-ext</finalName>
-                            <attach>false</attach>
-                        </configuration>
-                    </execution>
-                </executions>
-            </plugin>
-
             <plugin>
                 <groupId>org.apache.maven.plugins</groupId>
                 <artifactId>maven-deploy-plugin</artifactId>
diff --git a/modules/performance-statistics-ext/assembly/dependencies-performance-statistics.xml b/modules/performance-statistics-ext/assembly/performance-statistics-binary.xml
similarity index 73%
rename from modules/performance-statistics-ext/assembly/dependencies-performance-statistics.xml
rename to modules/performance-statistics-ext/assembly/performance-statistics-binary.xml
index 54c967f..1fc3360 100644
--- a/modules/performance-statistics-ext/assembly/dependencies-performance-statistics.xml
+++ b/modules/performance-statistics-ext/assembly/performance-statistics-binary.xml
@@ -17,22 +17,26 @@
   limitations under the License.
 -->
 
-<assembly xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2"
+<assembly xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.3"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-          xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2
-          http://maven.apache.org/xsd/assembly-1.1.2.xsd">
-    <id>performance-statistics-report-sources</id>
-
+          xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.3
+          http://maven.apache.org/xsd/assembly-1.1.3.xsd">
+    <id>bin</id>
     <includeBaseDirectory>false</includeBaseDirectory>
 
     <formats>
         <format>zip</format>
     </formats>
 
+    <componentDescriptors>
+        <componentDescriptor>../../assembly/bin-component-shared.xml</componentDescriptor>
+    </componentDescriptors>
+
     <fileSets>
         <fileSet>
-            <directory>report</directory>
-            <outputDirectory>/</outputDirectory>
+            <directory>${basedir}/bin</directory>
+            <outputDirectory>${project.artifactId}/bin</outputDirectory>
+            <fileMode>755</fileMode>
         </fileSet>
     </fileSets>
 </assembly>
diff --git a/modules/performance-statistics-ext/pom.xml b/modules/performance-statistics-ext/pom.xml
index c557ba3..987886d 100644
--- a/modules/performance-statistics-ext/pom.xml
+++ b/modules/performance-statistics-ext/pom.xml
@@ -100,27 +100,6 @@
     <build>
         <plugins>
             <plugin>
-                <artifactId>maven-assembly-plugin</artifactId>
-                <executions>
-                    <execution>
-                        <!-- Create zip archive with UI resources. -->
-                        <id>performance-statistics-report-sources</id>
-                        <goals>
-                            <goal>single</goal>
-                        </goals>
-                        <phase>compile</phase>
-                        <configuration>
-                            <appendAssemblyId>false</appendAssemblyId>
-                            <descriptors>
-                                <descriptor>assembly/dependencies-performance-statistics.xml</descriptor>
-                            </descriptors>
-                            <finalName>report</finalName>
-                            <attach>false</attach>
-                        </configuration>
-                    </execution>
-                </executions>
-            </plugin>
-            <plugin>
                 <artifactId>maven-resources-plugin</artifactId>
                 <version>3.1.0</version>
                 <executions>
@@ -161,53 +140,6 @@
                     </execution>
                 </executions>
             </plugin>
-            <plugin>
-                <groupId>org.apache.maven.plugins</groupId>
-                <artifactId>maven-antrun-plugin</artifactId>
-                <version>1.7</version>
-                <inherited>false</inherited>
-                <executions>
-                    <execution>
-                        <!-- Create release archive. -->
-                        <id>release-postprocessing</id>
-                        <goals>
-                            <goal>run</goal>
-                        </goals>
-                        <phase>install</phase>
-                        <configuration>
-                            <target>
-                                <copy todir="${project.build.directory}/${release.package}/${tool.directory}">
-                                    <fileset dir="${basedir}/bin"/>
-                                </copy>
-                                <copy todir="${project.build.directory}/${release.package}/${tool.directory}/libs">
-                                    <fileset dir="${project.build.directory}/libs"/>
-                                    <fileset dir="${project.build.directory}">
-                                        <include name="${build.finalName}.jar"/>
-                                    </fileset>
-                                </copy>
-                                <copy todir="${project.build.directory}/${release.package}">
-                                    <fileset file="${basedir}/README.txt"/>
-                                    <filelist dir="${basedir}/../../" files="LICENSE,NOTICE"/>
-                                </copy>
-
-                                <chmod dir="${project.build.directory}/${release.package}"
-                                       perm="755" includes="**/*.sh" />
-
-                                <zip destfile="${project.build.directory}/${release.package}.zip"
-                                     encoding="UTF-8">
-                                    <zipfileset dir="${project.build.directory}/${release.package}"
-                                                filemode="755">
-                                        <include name="**/*.sh" />
-                                    </zipfileset>
-                                    <zipfileset dir="${project.build.directory}/${release.package}" >
-                                        <exclude name="**/*.sh" />
-                                    </zipfileset>
-                                </zip>
-                            </target>
-                        </configuration>
-                    </execution>
-                </executions>
-            </plugin>
         </plugins>
     </build>
 </project>
diff --git a/modules/zookeeper-ip-finder-ext/zookeeper-ip-finder/assembly/zookeeper-ip-finder-ext.xml b/modules/zookeeper-ip-finder-ext/zookeeper-ip-finder/assembly/zookeeper-ip-finder-ext.xml
index 80a55c9..a63d3f3 100644
--- a/modules/zookeeper-ip-finder-ext/zookeeper-ip-finder/assembly/zookeeper-ip-finder-ext.xml
+++ b/modules/zookeeper-ip-finder-ext/zookeeper-ip-finder/assembly/zookeeper-ip-finder-ext.xml
@@ -17,11 +17,11 @@
   limitations under the License.
 -->
 
-<assembly xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2"
+<assembly xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.3"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-          xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2
-          http://maven.apache.org/xsd/assembly-1.1.2.xsd">
-    <id>zookeeper-ip-finder-ext</id>
+          xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.3
+          http://maven.apache.org/xsd/assembly-1.1.3.xsd">
+    <id>bin</id>
 
     <includeBaseDirectory>false</includeBaseDirectory>
 
@@ -29,17 +29,7 @@
         <format>zip</format>
     </formats>
 
-    <fileSets>
-        <fileSet>
-            <directory>${project.build.directory}</directory>
-            <outputDirectory>/libs/optional/ignite-zookeeper-ip-finder-ext</outputDirectory>
-            <includes>
-                <include>${project.build.finalName}.${project.packaging}</include>
-            </includes>
-        </fileSet>
-        <fileSet>
-            <directory>${project.build.directory}/libs</directory>
-            <outputDirectory>/libs/optional/ignite-zookeeper-ip-finder-ext</outputDirectory>
-        </fileSet>
-    </fileSets>
+    <componentDescriptors>
+        <componentDescriptor>../../../assembly/bin-component-shared.xml</componentDescriptor>
+    </componentDescriptors>
 </assembly>
diff --git a/modules/zookeeper-ip-finder-ext/zookeeper-ip-finder/pom.xml b/modules/zookeeper-ip-finder-ext/zookeeper-ip-finder/pom.xml
index b6f67f7..2214e91 100644
--- a/modules/zookeeper-ip-finder-ext/zookeeper-ip-finder/pom.xml
+++ b/modules/zookeeper-ip-finder-ext/zookeeper-ip-finder/pom.xml
@@ -167,28 +167,6 @@
                     </execution>
                 </executions>
             </plugin>
-
-            <plugin>
-                <artifactId>maven-assembly-plugin</artifactId>
-                <executions>
-                    <execution>
-                        <id>zookeeper-ip-finder-ext</id>
-                        <goals>
-                            <goal>single</goal>
-                        </goals>
-                        <phase>package</phase>
-                        <configuration>
-                            <appendAssemblyId>false</appendAssemblyId>
-                            <descriptors>
-                                <descriptor>assembly/zookeeper-ip-finder-ext.xml</descriptor>
-                            </descriptors>
-                            <finalName>ignite-zookeeper-ip-finder-ext</finalName>
-                            <attach>false</attach>
-                        </configuration>
-                    </execution>
-                </executions>
-            </plugin>
-
             <!-- Generate the OSGi MANIFEST.MF for this bundle. -->
             <plugin>
                 <groupId>org.apache.felix</groupId>
diff --git a/parent-internal/pom.xml b/parent-internal/pom.xml
index accbf8c..217dc1b 100644
--- a/parent-internal/pom.xml
+++ b/parent-internal/pom.xml
@@ -125,4 +125,78 @@
             </plugin>
         </plugins>
     </build>
+
+    <profiles>
+        <profile>
+            <id>extension-release</id>
+            <build>
+                <plugins>
+                    <plugin>
+                        <groupId>org.apache.maven.plugins</groupId>
+                        <artifactId>maven-assembly-plugin</artifactId>
+                        <executions>
+                            <execution>
+                                <id>source-assembly</id>
+                                <phase>package</phase>
+                                <goals>
+                                    <goal>single</goal>
+                                </goals>
+                                <configuration>
+                                    <runOnlyAtExecutionRoot>true</runOnlyAtExecutionRoot>
+                                    <descriptors>
+                                        <descriptor>../../assembly/source-release.xml</descriptor>
+                                    </descriptors>
+                                    <finalName>ignite-${project.projectDirectory.name}-src</finalName>
+                                    <appendAssemblyId>false</appendAssemblyId>
+                                </configuration>
+                            </execution>
+                            <execution>
+                                <id>binary-assembly</id>
+                                <phase>package</phase>
+                                <goals>
+                                    <goal>single</goal>
+                                </goals>
+                                <configuration>
+                                    <descriptorSourceDirectory>${project.basedir}/assembly</descriptorSourceDirectory>
+                                    <!-- Assembly id will be attached to the final name in favor the release name. -->
+                                    <finalName>${project.artifactId}</finalName>
+                                    <ignoreMissingDescriptor>true</ignoreMissingDescriptor>
+                                </configuration>
+                            </execution>
+                        </executions>
+                    </plugin>
+                    <plugin>
+                        <inherited>true</inherited>
+                        <groupId>org.apache.maven.plugins</groupId>
+                        <artifactId>maven-deploy-plugin</artifactId>
+                        <configuration>
+                            <!-- We want to deploy the artifact to a staging location. -->
+                            <updateReleaseInfo>true</updateReleaseInfo>
+                        </configuration>
+                    </plugin>
+                    <plugin>
+                        <groupId>net.nicoulaj.maven.plugins</groupId>
+                        <artifactId>checksum-maven-plugin</artifactId>
+                        <version>1.10</version>
+                        <executions>
+                            <execution>
+                                <id>checksum</id>
+                                <goals>
+                                    <goal>artifacts</goal>
+                                </goals>
+                            </execution>
+                        </executions>
+                        <configuration>
+                            <algorithms>
+                                <algorithm>SHA-512</algorithm>
+                            </algorithms>
+                            <appendFilename>true</appendFilename>
+                            <excludeMainArtifact>true</excludeMainArtifact>
+                            <failIfNoFiles>false</failIfNoFiles>
+                        </configuration>
+                    </plugin>
+                </plugins>
+            </build>
+        </profile>
+    </profiles>
 </project>
diff --git a/scripts/extension_build_deploy.sh b/scripts/extension_build_deploy.sh
new file mode 100755
index 0000000..ed272b3
--- /dev/null
+++ b/scripts/extension_build_deploy.sh
@@ -0,0 +1,153 @@
+#!/usr/bin/env bash
+set -o nounset
+set -o errexit
+set -o pipefail
+set -o errtrace
+set -o functrace
+
+#################################################################################
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License.  You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+#
+#################################################################################
+#                                  README                                       #
+#################################################################################
+#
+# This script is used to build an extension locally on developers environment and
+# upload everything to the Maven Central Staging repository and distribution archive.
+#
+# Run script from the Apache Ignite Extensions root directory.
+# Usage: ./scripts/extension-deploy.sh modules/zookeeper-ip-finder-ext/
+#
+# PREREQUISITES:
+# - copy `settings.xml` template from scripts directory
+# - `apache.releases.https` username/password pair exists
+# - pgp signature configured
+# - export GPG_TTY=$(tty)
+#
+# SCRIPT EXECUTION:
+#
+# The following conditions must be met in order to complete the deploy successfully:
+# - git branch `release/ignite-zookeeper-ip-finder-ext-1.0.0` created;
+# - there is no SNAPSHOT versions in the release branch (dependencies and extension version);
+# - the RC tag `ignite-zookeeper-ip-finder-ext-1.0.0-rc1` is added to the last commit;
+# - there is no uncommitted changes in the release branch;
+#
+#################################################################################
+
+function _logger () {
+  echo -e "$@\r" | tee -a $log
+}
+
+if [ $# -eq 0 ]
+  then
+    echo "Ignite Extension directory is not specified."
+    exit 1
+fi
+
+GIT_HOME="$(dirname "$(cd "$(dirname "$0")"; "pwd")")";
+SCRIPTS_HOME="${GIT_HOME}/scripts/"
+
+### Import patch functions. ###
+. ${SCRIPTS_HOME}/git-patch-functions.sh
+
+server_id="apache.releases.https"
+dist_url="https://dist.apache.org/repos/dist/dev/ignite/ignite-extensions/"
+now=$(date +'%H%M%S')
+dir=$1
+module_name="ignite-$(sed 's/\/$//' <<< $1 |  cut -d '/' -f2)"
+
+log=$(pwd)"/log_${module_name}_${now}.tmp"
+touch ${log}
+
+_logger "============================================================================="
+_logger "Extension Module Name:    ${module_name}"
+
+cd ${dir}
+
+### Get version from pom.xml with respect to the Maven. ###
+ext_ver=$(mvn help:evaluate -D expression=project.version -q -DforceStdout)
+ignite_ver=$(mvn help:evaluate -D expression=ignite.version -q -DforceStdout)
+
+_logger "Extension Version:        ${ext_ver}"
+_logger "Extension Ignite Version: ${ignite_ver}"
+
+### Get the RC tag associated with the last commit in the current branch. ###
+#rc_tag="${module_name}-${ext_ver}-rc1"
+rc_tag=$(git describe --tags --exact-match --abbrev=0)
+
+if [[ rc_tag =~ "${module_name}-${ext_ver}-rc"* ]]; then
+  _logger "ERROR: The RC tag must have the following format: ignite-zookeeper-if-finder-ext-1.0.0-rc1"
+  _logger "ERROR: Given tag: ${rc_tag}"
+
+  exit 1;
+fi
+
+_logger "Extension RC tag:         ${rc_tag}"
+
+requireCleanWorkTree ${GIT_HOME}
+
+### Build the Extension ###
+_logger "============================================================================="
+_logger "Start Maven Build ..."
+
+cd ${dir}
+
+### The mvn must be started from the module root directory to collect assembly sources.
+mvn clean deploy -DskipTests -Pextension-release -amd | tee -a ${log}
+
+while IFS='' read -r line || [[ -n "$line" ]]; do
+    if [[ $line == *ERROR* ]]; then
+        _logger "ERROR: building. Please check log file: ${log}."
+
+        exit 1;
+    fi
+done < ${log}
+
+cd ${dir}
+
+### Prepare sources and binary packages. ###
+list=$(find $(pwd) -regex '.*\.zip' -o -regex '.*\.zip\.asc' -o -regex '.*\.zip\.sha512')
+svn_dir=$(pwd)"/target/svn"
+mkdir ${svn_dir}
+
+_logger
+_logger "============================================================================="
+_logger "Copy assemblies (zip, asc, sha512) to the temporary svn directory: ${svn_dir}"
+
+for file in $list
+do
+    _logger "Copying ${file}"
+
+    cp ${file} ${svn_dir}
+done
+
+_logger
+_logger "============================================================================="
+_logger "Uploading RC to Apache dist: ${rc_tag}"
+
+# Uncomment subsequent line in case you want to remove incorrectly prepared RC.
+#svn rm -m "Removing redundant Release" https://dist.apache.org/repos/dist/dev/ignite/ignite-extensions/${rc_tag} || true
+svn import ${svn_dir} ${dist_url}${rc_tag} -m "New RC ${rc_tag}: Sources and Binaries"
+
+
+### Output result and notes ###
+_logger
+_logger "============================================================================="
+_logger "Artifacts should be moved to RC repository"
+_logger "Please check results at: "
+_logger " - binaries: https://dist.apache.org/repos/dist/dev/ignite/ignite-extensions/${rc_tag}"
diff --git a/scripts/settings.xml b/scripts/settings.xml
index 45deb60..74bf621 100644
--- a/scripts/settings.xml
+++ b/scripts/settings.xml
@@ -20,11 +20,51 @@
 <settings xmlns="http://maven.apache.org/SETTINGS/1.0.0"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0 http://maven.apache.org/xsd/settings-1.0.0.xsd">
+
     <servers>
         <server>
+            <!--
+                NOTE: This is the name of the Maven Central _staging_ repository to upload prepared artifacts to.
+                The repository is inherited from the Apache Ignite main project (see the 'ignite-parent' module)
+                through the maven parent-child relationship. Use your ASF credentials.
+
+                (!) DO NOT use you password directly, see Maven Password Encryption guide:
+                https://maven.apache.org/guides/mini/guide-encryption.html
+             -->
             <id>apache.releases.https</id>
             <username>release_manager_login</username>
             <password>release_manager_password</password>
         </server>
     </servers>
+
+    <profiles>
+        <profile>
+            <!--
+                NOTE: This profile is optional. If you have a single [ultimate] pgp key installed it
+                will be used to sign the prepared maven artifacts, sources and binary archives.
+
+                In case you have no pgp key, please follow instructions from the following link:
+                https://www.apache.org/dev/openpgp.html#generate-key
+
+                You should add your newly created public pgp key to the Apache Ignite KEYS file
+                (see https://dist.apache.org/repos/dist/release/ignite/KEYS) located in the svn
+                repository. You can update the file using your ASF credentials.
+
+                Append you key using the commands below.
+                (see Exporting a Public Key https://www.gnupg.org/gph/en/manual/x56.html)
+
+                `gpg -k E38286D5 >> KEYS`
+                `gpg -armor -export E38286D5 >> KEYS`
+            -->
+            <id>gpg</id>
+
+            <properties>
+                <!-- You can find your gpg key using the gpg list-keys command: `gpg -k` -->
+                <gpg.keyname>E38286D5</gpg.keyname>
+                <!-- Don't use the passphrase to your gpg key in any settings file. It will be prompted at the command run. -->
+                <gpg.passphrase>*</gpg.passphrase>
+                <gpg.useagent>false</gpg.useagent>
+            </properties>
+        </profile>
+    </profiles>
 </settings>
diff --git a/scripts/update-versions.sh b/scripts/update-versions.sh
deleted file mode 100755
index a9535c3..0000000
--- a/scripts/update-versions.sh
+++ /dev/null
@@ -1,35 +0,0 @@
-#!/bin/bash
-#
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You under the Apache License, Version 2.0
-# (the "License"); you may not use this file except in compliance with
-# the License.  You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-#
-# Updates Ignite version in Java pom files, .NET AssemblyInfo files, C++ configure files.
-# Run in Ignite sources root directory.
-# Usage: ./update-versions 2.6.0
-#
-
-if [ $# -eq 0 ]
-  then
-    echo "Version not specified"
-    exit 1
-fi
-
-echo Updating Java versions to $1 with Maven...
-mvn versions:set -DnewVersion=$1 -Pall-java,all-scala,all-other -DgenerateBackupPoms=false -DgroupId=* -DartifactId=* -DoldVersion=* -DprocessDependencies=false
-
-echo Updating .NET & C++ versions to $1 with Maven...
-mvn validate -P update-versions -D new.ignite.version=$1
diff --git a/scripts/upload_module_to_staging.sh b/scripts/upload_module_to_staging.sh
deleted file mode 100755
index f481aa4..0000000
--- a/scripts/upload_module_to_staging.sh
+++ /dev/null
@@ -1,84 +0,0 @@
-#!/usr/bin/env bash
-#
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You under the Apache License, Version 2.0
-# (the "License"); you may not use this file except in compliance with
-# the License.  You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-module_version="1.0.0"
-dir_name="release-module-name" #enter module name to release.
-module_name="ignite-${dir_name}"
-dir="../modules/${dir_name}"
-
-server_url="https://repository.apache.org/service/local/staging/deploy/maven2"
-server_id="apache.releases.https"
-
-echo "Uploading $module_name to staging"
-
-now=$(date +'%H%M%S')
-
-main_file=$(find $dir/target -name "${module_name}-${module_version}.jar")
-pom=$(find $dir -name "pom-installed.xml")
-javadoc=$(find $dir/target -name "${module_name}-${module_version}-javadoc.jar")
-sources=$(find $dir/target -name "${module_name}-${module_version}-sources.jar")
-tests=$(find $dir -name "${module_name}-${module_version}-tests.jar")
-
-adds=""
-
-echo "Uploading ${dir}."
-
-if [[ $javadoc == *javadoc* ]]
-then
-	adds="${adds} -Djavadoc=${javadoc}"
-fi
-
-if [[ $sources == *sources* ]]
-then
-	adds="${adds} -Dsources=${sources}"
-fi
-
-if [[ $tests == *tests* ]]
-then
-	adds="${adds} -Dfiles=${tests} -Dtypes=jar -Dclassifiers=tests"
-fi
-
-if [[ ! -n $main_file && ! -n $features ]]
-then
-	main_file=$pom
-	adds="-Dpackaging=pom"
-fi
-
-echo "Directory: $dir"
-echo "File: $main_file"
-echo "Adds: $adds"
-
-mvn gpg:sign-and-deploy-file -Papache_staging -Dfile=$main_file -Durl=$server_url -DrepositoryId=$server_id -DretryFailedDeploymentCount=10 -DpomFile=$pom ${adds} --settings ./settings.xml
-
-result="Uploaded"
-
-while IFS='' read -r line || [[ -n "$line" ]]; do
-    if [[ $line == *ERROR* ]]
-    then
-        result="Uploading failed. Please check log file: ${logname}."
-    fi
-done < ./$logname
-
-echo $result
-
-echo " "
-echo "======================================================"
-echo "Maven staging should be created"
-echo "Please check results at"
-echo "https://repository.apache.org/#stagingRepositories"
-echo "Don't forget to close staging with proper comment"
diff --git "a/scripts/vote_\133git\135_update_versions.sh" "b/scripts/vote_\133git\135_update_versions.sh"
new file mode 100755
index 0000000..defdad8
--- /dev/null
+++ "b/scripts/vote_\133git\135_update_versions.sh"
@@ -0,0 +1,44 @@
+#!/bin/bash
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License.  You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+#
+# Run from the Apache Ignite sources root directory.
+# Usage: ./scripts/update-versions [2.13.0] modules/zookeeper-ip-finder-ext/ 1.0.0
+#
+
+if [ $# -eq 0 ]
+  then
+    echo "Version not specified"
+    exit 1
+fi
+
+git_root=$(pwd)
+module_name="ignite-$(sed 's/\/$//' <<< $2 |  cut -d '/' -f2)"
+
+cd parent-internal
+
+echo "============================================================================="
+echo "Updating Apache Ignite parent version to $1 with Maven..."
+mvn versions:update-parent -DparentVersion=$1 -DgenerateBackupPoms=false
+
+### Use changing version command from the extension directory.  ###
+cd ${git_root}/$2
+
+echo "============================================================================="
+echo "Updating Extension ${module_name} version to $3 with Maven..."
+mvn versions:set -DnewVersion=$3 -DgenerateBackupPoms=false -DgroupId=* -DartifactId=* -DoldVersion=* -DprocessDependencies=false
diff --git "a/scripts/vote_\133mvn\135\133pgp\135_jar_deploy.sh" "b/scripts/vote_\133mvn\135\133pgp\135_jar_deploy.sh"
new file mode 100644
index 0000000..ac238a6
--- /dev/null
+++ "b/scripts/vote_\133mvn\135\133pgp\135_jar_deploy.sh"
@@ -0,0 +1,87 @@
+#!/usr/bin/env bash
+
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License.  You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+chmod +x release.properties
+. ./release.properties
+
+function _logger () {
+  echo -e "$@\r" | tee -a $log
+}
+
+server_url="https://repository.apache.org/service/local/staging/deploy/maven2"
+server_id="apache.releases.https"
+
+now=$(date +'%H%M%S')
+log="vote_[mvn][pgp]_deploy_${now}.log"
+
+_logger "============================================================================="
+_logger "Preparing Maven Upload ${EXTENSION_RC_TAG}"
+
+dir="./maven/org/apache/ignite"
+
+main_file=$(find $dir -name "${EXTENSION_NAME}-${EXTENSION_VERSION}.jar")
+pom=$(find $dir -name "${EXTENSION_NAME}-${EXTENSION_VERSION}.pom")
+javadoc=$(find $dir -name "${EXTENSION_NAME}-${EXTENSION_VERSION}-javadoc.jar")
+sources=$(find $dir -name "${EXTENSION_NAME}-${EXTENSION_VERSION}-sources.jar")
+tests=$(find $dir -name "${EXTENSION_NAME}-${EXTENSION_VERSION}-tests.jar")
+
+adds=""
+
+if [[ $javadoc == *javadoc* ]]
+then
+	adds="${adds} -Djavadoc=${javadoc}"
+fi
+
+if [[ $sources == *sources* ]]
+then
+	adds="${adds} -Dsources=${sources}"
+fi
+
+if [[ $tests == *tests* ]]
+then
+	adds="${adds} -Dfiles=${tests} -Dtypes=jar -Dclassifiers=tests"
+fi
+
+if [[ ! -n $main_file && ! -n $features ]]
+then
+	main_file=$pom
+	adds="-Dpackaging=pom"
+fi
+
+_logger "Directory: $dir"
+_logger "File: $main_file"
+_logger "Adds: $adds"
+
+mvn gpg:sign-and-deploy-file -Pgpg -Dfile=$main_file -Durl=$server_url -DrepositoryId=$server_id \
+  -DretryFailedDeploymentCount=10 -DpomFile=$pom ${adds} --settings ./settings.xml | tee -a ${log}
+
+while IFS='' read -r line || [[ -n "$line" ]]; do
+    if [[ $line == *ERROR* ]]
+    then
+        result="Uploading failed. Please check log file: ${log}."
+    fi
+done < ${log}
+
+_logger "$(result:-"Uploaded")"
+
+_logger " "
+_logger "============================================================================="
+_logger "Maven staging should be created"
+_logger "Please check results at"
+_logger "https://repository.apache.org/#stagingRepositories"
diff --git "a/scripts/vote_\133pgp\135_sign_dist.sh" "b/scripts/vote_\133pgp\135_sign_dist.sh"
new file mode 100644
index 0000000..95a9623
--- /dev/null
+++ "b/scripts/vote_\133pgp\135_sign_dist.sh"
@@ -0,0 +1,64 @@
+#!/usr/bin/env bash
+set -o nounset
+set -o errexit
+set -o pipefail
+set -o errtrace
+set -o functrace
+
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License.  You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+now=$(date +'%H%M%S')
+log="vote_[pgp]_sign_binary_${now}.log"
+
+### Sign artifacts ###
+echo "============================================================================="
+echo "Starting GPG Agent"
+gpg-connect-agent /bye
+
+list=$(find ./svn/vote -type f -name "*.zip")
+
+for file in $list
+do
+    echo "Signing ${file}"
+	  echo ${file} | tee -a ${log}
+    GPG_AGENT_INFO=~/.gnupg/S.gpg-agent:0:1 gpg -ab ${file} | tee -a ${log}
+done
+
+result="Signed OK."
+
+while IFS='' read -r line || [[ -n "${line}" ]]; do
+    if [[ $line == *ERROR* ]]
+    then
+        result="Signing failed. Please check log file: ${log}."
+    fi
+done < ${log}
+
+echo ${result}
+
+
+#
+# Output result and notes
+#
+echo " "
+echo "==============================================="
+echo "Artifacts should be signed"
+echo "Please check results at ./svn/vote"
+echo "Each file should have corresponding *.asc file"
+echo
+echo "NOTE: Package files are not signed because they"
+echo "are meant to be stored in Bintray"
\ No newline at end of file
diff --git "a/scripts/vote_\133svn\135_upload_dist.sh" "b/scripts/vote_\133svn\135_upload_dist.sh"
new file mode 100644
index 0000000..c469e27
--- /dev/null
+++ "b/scripts/vote_\133svn\135_upload_dist.sh"
@@ -0,0 +1,43 @@
+#!/usr/bin/env bash
+set -o nounset
+set -o errexit
+set -o pipefail
+set -o errtrace
+set -o functrace
+
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License.  You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+SERVER_URL="https://dist.apache.org/repos/dist/dev/ignite/ignite-extensions"
+
+chmod +x release.properties
+. ./release.properties
+
+echo "============================================================================="
+echo "The RC: ${EXTENSION_RC_TAG}"
+
+# Uncomment subsequent line in case you want to remove incorrectly prepared RC
+#svn rm -m "Removing redundant Release" ${SERVER_URL}/${EXTENSION_RC_TAG} || true
+
+svn import svn/vote ${SERVER_URL}/${EXTENSION_RC_TAG} -m "A new RC ${EXTENSION_RC_TAG} added: Binaries and Sources"
+
+### Output result and notes ###
+echo
+echo "============================================================================="
+echo "Artifacts should be moved to RC repository"
+echo "Please check results at:"
+echo "${SERVER_URL}/${EXTENSION_RC_TAG}"
\ No newline at end of file