diff --git a/Applications/Python/OpenGeoSys/__init__.py b/Applications/Python/OpenGeoSys/__init__.py
index 7631e8c33692a7ce6118ac016ed66d46bdc9de78..628678b353d0ed28af41e50ddc1028a8d6974dac 100644
--- a/Applications/Python/OpenGeoSys/__init__.py
+++ b/Applications/Python/OpenGeoSys/__init__.py
@@ -11,5 +11,6 @@ def _program(name, args):
     return subprocess.call([os.path.join(OGS_BIN_DIR, name)] + args)
 
 
+# Binary entrypoints
 def ogs():
     raise SystemExit(_program("ogs", sys.argv[1:]))
diff --git a/pyproject.toml b/pyproject.toml
index 754315d212c6989f0a5711974f6de0c7adf0c06a..9c3d7b3b2c7adef8409e3a6cec527e780daf2652 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -22,3 +22,4 @@ build-verbosity = "1"
 [tool.cibuildwheel.linux]
 manylinux-x86_64-image = "manylinux2014"
 manylinux-aarch64-image = "manylinux2014"
+environment-pass = ["OGS_VERSION"]
diff --git a/scripts/ci/jobs/build-wheels.yml b/scripts/ci/jobs/build-wheels.yml
index 0c29c74387ebede371c80df11bba4eebbecf9c0a..6bcab571755f0942b5d8353d703334c6cf437987 100644
--- a/scripts/ci/jobs/build-wheels.yml
+++ b/scripts/ci/jobs/build-wheels.yml
@@ -4,6 +4,12 @@ build wheels linux:
   tags: [envinf3-shell]
   script:
     - pipx run cibuildwheel
+    - >
+      pipx run twine upload
+      --repository-url https://gitlab.opengeosys.org/api/v4/projects/${CI_PROJECT_ID}/packages/pypi
+      --username gitlab-ci-token
+      --password ${CI_JOB_TOKEN}
+      wheelhouse/*
   artifacts:
     paths:
       - wheelhouse/
diff --git a/setup.py b/setup.py
index eaa57d949671b0b30e370f1e8dac8250bd52d633..f95e450d35f20b21bdaf2366d4e88be56ee0b9ad 100644
--- a/setup.py
+++ b/setup.py
@@ -1,9 +1,39 @@
 from skbuild import setup
 from setuptools import find_packages
 
+import os
+import re
+import subprocess
+
+
+def get_version():
+    git_version = ""
+    if "OGS_VERSION" in os.environ:
+        git_version = os.environ["OGS_VERSION"]
+    else:
+        git_version = subprocess.run(
+            ["git describe --tags"],
+            capture_output=True,
+            text=True,
+            shell=True,
+        ).stdout.strip()
+
+    if re.match("\d+\.\d+\.\d+-\d+-g\w+", git_version):
+        # Make it PEP 440 compliant
+        # e.g. 6.4.2-1140-g85bbc8b4e1 -> 6.4.2.dev1140
+        m = re.match(".+?(?=-g[\w]*$)", git_version)  # strip out commit hash
+        if m:
+            return m.group(0).replace("-", ".dev")  # insert dev
+        else:
+            print("WARNING: Could not get ogs version!")
+            exit(1)
+    else:
+        return git_version
+
+
 setup(
     name="OpenGeoSys",
-    version="6.4.2",
+    version=get_version(),
     description="OpenGeoSys",
     author="OpenGeoSys Community",
     license="BSD-3-Clause",