diff --git a/check_blender_release/check_module_enabled.py b/check_blender_release/check_module_enabled.py
new file mode 100644
index 0000000000000000000000000000000000000000..158a5386a9ddb7d9848133a58a7fe85c40dbae18
--- /dev/null
+++ b/check_blender_release/check_module_enabled.py
@@ -0,0 +1,44 @@
+#!/usr/bin/env python3
+
+# ***** BEGIN GPL LICENSE BLOCK *****
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+#
+# Contributor(s): Sergey Sharybin
+#
+# #**** END GPL LICENSE BLOCK #****
+
+# <pep8 compliant>
+
+import unittest
+
+from check_utils import (sliceCommandLineArguments,
+                         SceiptUnitTesting)
+
+
+class UnitTesting(SceiptUnitTesting):
+    def test_modulesEnabled(self):
+        self.checkScript("modules_enabled")
+
+
+def main():
+    # Slice command line arguments by '--'
+    unittest_args, parser_args = sliceCommandLineArguments()
+    # Construct and run unit tests.
+    unittest.main(argv=unittest_args)
+
+
+if __name__ == "__main__":
+    main()
diff --git a/check_blender_release/check_module_numpy.py b/check_blender_release/check_module_numpy.py
new file mode 100644
index 0000000000000000000000000000000000000000..36c90006807531cdb44b0ca5441ed042a6b0511f
--- /dev/null
+++ b/check_blender_release/check_module_numpy.py
@@ -0,0 +1,47 @@
+#!/usr/bin/env python3
+
+# ***** BEGIN GPL LICENSE BLOCK *****
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+#
+# Contributor(s): Sergey Sharybin
+#
+# #**** END GPL LICENSE BLOCK #****
+
+# <pep8 compliant>
+
+import unittest
+
+from check_utils import (sliceCommandLineArguments,
+                         SceiptUnitTesting)
+
+
+class UnitTesting(SceiptUnitTesting):
+    def test_numpyImports(self):
+        self.checkScript("numpy_import")
+
+    def test_numpyBasicOperation(self):
+        self.checkScript("numpy_basic_operation")
+
+
+def main():
+    # Slice command line arguments by '--'
+    unittest_args, parser_args = sliceCommandLineArguments()
+    # Construct and run unit tests.
+    unittest.main(argv=unittest_args)
+
+
+if __name__ == "__main__":
+    main()
diff --git a/check_blender_release/check_module_requests.py b/check_blender_release/check_module_requests.py
new file mode 100644
index 0000000000000000000000000000000000000000..af8f6e3b8e43f03e17fda167d6a3f974a7445e8f
--- /dev/null
+++ b/check_blender_release/check_module_requests.py
@@ -0,0 +1,47 @@
+#!/usr/bin/env python3
+
+# ***** BEGIN GPL LICENSE BLOCK *****
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+#
+# Contributor(s): Sergey Sharybin
+#
+# #**** END GPL LICENSE BLOCK #****
+
+# <pep8 compliant>
+
+import unittest
+
+from check_utils import (sliceCommandLineArguments,
+                         SceiptUnitTesting)
+
+
+class UnitTesting(SceiptUnitTesting):
+    def test_requestsImports(self):
+        self.checkScript("requests_import")
+
+    def test_requestsBasicAccess(self):
+        self.checkScript("requests_basic_access")
+
+
+def main():
+    # Slice command line arguments by '--'
+    unittest_args, parser_args = sliceCommandLineArguments()
+    # Construct and run unit tests.
+    unittest.main(argv=unittest_args)
+
+
+if __name__ == "__main__":
+    main()
diff --git a/check_blender_release/check_release.py b/check_blender_release/check_release.py
new file mode 100755
index 0000000000000000000000000000000000000000..6275f79b0833160135ccc2f7e1b8fad63c2669fb
--- /dev/null
+++ b/check_blender_release/check_release.py
@@ -0,0 +1,59 @@
+#!/usr/bin/env python3
+
+# ***** BEGIN GPL LICENSE BLOCK *****
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+#
+# Contributor(s): Sergey Sharybin
+#
+# #**** END GPL LICENSE BLOCK #****
+
+# <pep8 compliant>
+
+# Usage: ./check_release.py -- ../path/to/release/folder
+
+
+import os
+import sys
+import unittest
+
+import check_module_enabled
+import check_module_numpy
+import check_module_requests
+import check_static_binaries
+from check_utils import sliceCommandLineArguments
+
+
+def load_tests(loader, standard_tests, pattern):
+    standard_tests.addTests(loader.loadTestsFromTestCase(
+            check_module_enabled.UnitTesting))
+    standard_tests.addTests(loader.loadTestsFromTestCase(
+            check_module_numpy.UnitTesting))
+    standard_tests.addTests(loader.loadTestsFromTestCase(
+            check_module_requests.UnitTesting))
+    standard_tests.addTests(loader.loadTestsFromTestCase(
+            check_static_binaries.UnitTesting))
+    return standard_tests
+
+
+def main():
+    # Slice command line arguments by '--'
+    unittest_args, parser_args = sliceCommandLineArguments()
+    # Construct and run unit tests.
+    unittest.main(argv=unittest_args)
+
+
+if __name__ == "__main__":
+    main()
diff --git a/check_blender_release/check_static_binaries.py b/check_blender_release/check_static_binaries.py
new file mode 100644
index 0000000000000000000000000000000000000000..198796bce1863776925bdd2d7aff220f4d4d57c9
--- /dev/null
+++ b/check_blender_release/check_static_binaries.py
@@ -0,0 +1,200 @@
+#!/usr/bin/env python3
+
+# ***** BEGIN GPL LICENSE BLOCK *****
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+#
+# Contributor(s): Sergey Sharybin
+#
+# #**** END GPL LICENSE BLOCK #****
+
+# <pep8 compliant>
+
+import os
+from pathlib import Path
+import re
+import subprocess
+import sys
+import unittest
+
+from check_utils import (sliceCommandLineArguments,
+                         parseArguments)
+
+
+ALLOWED_LIBS = (
+    # Core C/C++ libraries
+    "ld-linux.so",
+    "ld-linux-x86-64.so",
+    "libc.so",
+    "libm.so",
+    "libstdc++.so",
+    "libdl.so",
+    "libpthread.so",
+    "libgcc_s.so",
+    "librt.so",
+    "libutil.so",
+
+    # X11 libraries we don't link statically,
+    "libX11.so",
+    "libXext.so",
+    "libXrender.so",
+    "libXxf86vm.so",
+    "libXi.so",
+
+    # OpenGL libraries.
+    "libGL.so",
+    "libGLU.so",
+
+    # Own dependencies we don't link statically.
+    "libfreetype.so",
+)
+
+IGNORE_FILES = ("blender-softwaregl", )
+IGNORE_EXTENSION = (".sh", ".py", )
+
+
+# Library dependencies.
+
+def getNeededLibrariesLDD(binary_filepath):
+    """
+    This function uses ldd to collect libraries which binary depends on.
+
+    Not totally safe since ldd might actually execute the binary to get it's
+    symbols and will also collect indirect dependnecies which might not be
+    desired.
+
+    Has advantage of telling that some dependnecy library is not found.
+    """
+    ldd_command = ("ldd", str(binary_filepath))
+    ldd_output = subprocess.check_output(ldd_command, stderr=subprocess.STDOUT)
+    lines = ldd_output.decode().split("\n")
+    libraries = []
+    for line in lines:
+        line = line.strip()
+        if not line:
+            continue
+        lib_name = line.split("=>")[0]
+        lib_name = lib_name.split(" (")[0].strip()
+        lib_file_name = os.path.basename(lib_name)
+        libraries.append(lib_file_name)
+    return libraries
+
+
+def getNeededLibrariesOBJDUMP(binary_filepath):
+    """
+    This function uses objdump to get direct dependencies of a given binary.
+
+    Totally safe, but will require manual check over libraries which are not
+    found on the system.
+    """
+    objdump_command = ("objdump", "-p", str(binary_filepath))
+    objdump_output = subprocess.check_output(objdump_command,
+                                             stderr=subprocess.STDOUT)
+    lines = objdump_output.decode().split("\n")
+    libraries = []
+    for line in lines:
+        line = line.strip()
+        if not line:
+            continue
+        if not line.startswith("NEEDED"):
+            continue
+        lib_name = line[6:].strip()
+        libraries.append(lib_name)
+    return libraries
+
+
+def getNeededLibraries(binary_filepath):
+    """
+    Get all libraries given binary depends on.
+    """
+    if False:
+        return getNeededLibrariesLDD(binary_filepath)
+    else:
+        return getNeededLibrariesOBJDUMP(binary_filepath)
+
+
+def stripLibraryABI(lib_name):
+    """
+    Strip ABI suffix from .so file
+
+    Example; libexample.so.1.0 => libexample.so
+    """
+    lib_name_no_abi = lib_name
+    # TOOD(sergey): Optimize this!
+    while True:
+        no_abi = re.sub(r"\.[0-9]+$", "", lib_name_no_abi)
+        if lib_name_no_abi == no_abi:
+            break
+        lib_name_no_abi = no_abi
+    return lib_name_no_abi
+
+
+class UnitTesting(unittest.TestCase):
+    def checkBinary(self, binary_filepath):
+        """
+        Check given binary file to be a proper static self-sufficient.
+        """
+
+        libraries = getNeededLibraries(binary_filepath)
+        for lib_name in libraries:
+            lib_name_no_abi = stripLibraryABI(lib_name)
+            self.assertTrue(lib_name_no_abi in ALLOWED_LIBS,
+                            "Error detected in {}: library used {}" . format(
+                                binary_filepath, lib_name))
+
+    def checkDirectory(self, directory):
+        """
+        Recursively traverse directory and check every binary in in.
+        """
+
+        for path in Path(directory).rglob("*"):
+            # Ignore any checks on directory.
+            if path.is_dir():
+                continue
+            # Ignore script files.
+            if path.name in IGNORE_FILES:
+                continue
+            if path.suffix in IGNORE_EXTENSION:
+                continue
+            # Check any executable binary,
+            if path.stat().st_mode & 0o111 != 0:
+                self.checkBinary(path)
+            # Check all dynamic libraries.
+            elif path.suffix == ".so":
+                self.checkBinary(path)
+
+    def test_directoryIsStatic(self):
+        # Parse arguments which are not handled by unit testing framework.
+        args = parseArguments()
+        # Do some sanity checks first.
+        self.assertTrue(os.path.exists(args.directory),
+                        "Given directory does not exist: {}" .
+                        format(args.directory))
+        self.assertTrue(os.path.isdir(args.directory),
+                        "Given path is not a directory: {}" .
+                        format(args.directory))
+        # Perform actual test,
+        self.checkDirectory(args.directory)
+
+
+def main():
+    # Slice command line arguments by '--'
+    unittest_args, parser_args = sliceCommandLineArguments()
+    # Construct and run unit tests.
+    unittest.main(argv=unittest_args)
+
+
+if __name__ == "__main__":
+    main()
diff --git a/check_blender_release/check_utils.py b/check_blender_release/check_utils.py
new file mode 100644
index 0000000000000000000000000000000000000000..42679cd16ec420b530b6b7f04b9c6f2a2e9e9b7c
--- /dev/null
+++ b/check_blender_release/check_utils.py
@@ -0,0 +1,92 @@
+#!/usr/bin/env python3
+
+# ***** BEGIN GPL LICENSE BLOCK *****
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+#
+# Contributor(s): Sergey Sharybin
+#
+# #**** END GPL LICENSE BLOCK #****
+
+# <pep8 compliant>
+
+
+import unittest
+
+
+def sliceCommandLineArguments():
+    """
+    Slice command line arguments by -- argument.
+    """
+
+    import sys
+
+    try:
+        double_shasl_index = sys.argv.index("--")
+    except ValueError:
+        unittest_args = sys.argv[:]
+        parser_args = []
+    else:
+        unittest_args = sys.argv[:double_shasl_index]
+        parser_args = sys.argv[double_shasl_index + 1:]
+
+    return unittest_args, parser_args
+
+
+def parseArguments():
+    import argparse
+
+    # Construct argument parser.
+    parser = argparse.ArgumentParser(description="Static binary checker")
+    parser.add_argument('directory', help='Directories to check')
+    # Parse arguments which are not handled by unit testing framework.
+    unittest_args, parser_args = sliceCommandLineArguments()
+    args = parser.parse_args(args=parser_args)
+    # TODO(sergey): Run some checks here?
+    return args
+
+
+def runScriptInBlender(blender_directory, script):
+    """
+    Run given script inside Blender and check non-zero exit code
+    """
+
+    import os
+    import subprocess
+
+    blender = os.path.join(blender_directory, "blender")
+    python = os.path.join(os.path.dirname(__file__), "scripts", script) + ".py"
+
+    command = (blender,
+               "-b",
+               "--factory-startup",
+               "--python-exit-code", "1",
+               "--python", python)
+
+    process = subprocess.Popen(command,
+                               shell=False,
+                               stdout=subprocess.PIPE,
+                               stderr=subprocess.STDOUT)
+    output, error = process.communicate()
+    return process.returncode == 0
+
+
+class SceiptUnitTesting(unittest.TestCase):
+    def checkScript(self, script):
+        # Parse arguments which are not handled by unit testing framework.
+        args = parseArguments()
+        # Perform actual test,
+        self.assertTrue(runScriptInBlender(args.directory, script),
+                        "Failed to run script {}" . format(script))
diff --git a/check_blender_release/scripts/modules_enabled.py b/check_blender_release/scripts/modules_enabled.py
new file mode 100644
index 0000000000000000000000000000000000000000..1a83ec6b22643c633d1556fab6ec809794846fa4
--- /dev/null
+++ b/check_blender_release/scripts/modules_enabled.py
@@ -0,0 +1,5 @@
+import _sha1
+import _sha256
+import _md5
+import ssl
+import multiprocessing.synchronize
diff --git a/check_blender_release/scripts/numpy_basic_operation.py b/check_blender_release/scripts/numpy_basic_operation.py
new file mode 100644
index 0000000000000000000000000000000000000000..54c581bbf6551f0404b3b53e9552d9f60ec8eb44
--- /dev/null
+++ b/check_blender_release/scripts/numpy_basic_operation.py
@@ -0,0 +1,6 @@
+# This code tests bug reported in T50703
+
+import numpy
+
+a = numpy.array([[3, 2, 0], [3, 1, 0]], dtype=numpy.int32)
+a[0]
diff --git a/check_blender_release/scripts/numpy_import.py b/check_blender_release/scripts/numpy_import.py
new file mode 100644
index 0000000000000000000000000000000000000000..c2e5936fe3786bc72d6bf8f7278f733571c09e48
--- /dev/null
+++ b/check_blender_release/scripts/numpy_import.py
@@ -0,0 +1 @@
+import numpy
diff --git a/check_blender_release/scripts/requests_basic_access.py b/check_blender_release/scripts/requests_basic_access.py
new file mode 100644
index 0000000000000000000000000000000000000000..09d6f61796cccdaba15a17b39f2dc1923b623bca
--- /dev/null
+++ b/check_blender_release/scripts/requests_basic_access.py
@@ -0,0 +1,8 @@
+import requests
+
+r = requests.get("https://blender.org/", verify=True)
+
+assert(r.status_code == 200)
+assert(r.reason == "OK")
+assert(True if r.ok else False)
+assert(len(r.content) > 256)
diff --git a/check_blender_release/scripts/requests_import.py b/check_blender_release/scripts/requests_import.py
new file mode 100644
index 0000000000000000000000000000000000000000..20b15530dd259d47a077bafde4e99ff35e656c80
--- /dev/null
+++ b/check_blender_release/scripts/requests_import.py
@@ -0,0 +1 @@
+import requests