diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 6eb365268cc6c07f72705cbc2403c9e51a188944..99fe5d5fbd449e8da58edc5e1884cc9003419aad 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -33,3 +33,11 @@ tests (arch):
 tests:
   script:
     - tox -p
+
+publish:
+  rules:
+    - if: $CI_COMMIT_TAG
+  variables:
+    TWINE_REPOSITORY: testpypi
+  script:
+    - tox -e publish
diff --git a/pyproject.toml b/pyproject.toml
index 454cd6c42332de727a16f95f1b637006c38d7b5a..bb47a49998c82616a14233263d48fd6a80356571 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -4,7 +4,7 @@ build-backend = 'setuptools.build_meta'
 
 [project]
 name = "ogstools"
-version = "0.0.1"
+version = "0.0.2"
 description = "A collection of Python tools aimed at evolving into a modeling toolchain around OpenGeoSys."
 authors = [{ name = 'OpenGeoSys Community', email = 'info@opengeosys.org' }]
 license = { text = "BSD-3-Clause" }
@@ -17,8 +17,10 @@ dependencies = ["meshio>=5.3.0"]
 "Bug Tracker" = 'https://gitlab.opengeosys.org/ogs/tools/ogstools/-/issues'
 "Source Code" = 'https://gitlab.opengeosys.org/ogs/tools/ogstools'
 
-[tool.setuptools]
-packages = ["ogstools"]
+[tool.setuptools.packages.find]
+where = ["."]
+include = ["ogstools"]
+namespaces = false
 
 [project.scripts]
 msh2vtu = 'ogstools.msh2vtu._cli:cli'
diff --git a/tox.ini b/tox.ini
index 4b4dc318e767dbcbc03b39c01419abab33cc6b33..6cfbcbc56d60e8deca2df06910f58949b0b5690e 100644
--- a/tox.ini
+++ b/tox.ini
@@ -41,6 +41,20 @@ deps = pre-commit
 skip_install = True
 commands = pre-commit run --all-files
 
+[testenv:publish]
+deps =
+    build
+    twine
+skip_install = True
+passenv =
+    TWINE_REPOSITORY
+    TWINE_USERNAME
+    TWINE_PASSWORD
+commands =
+    pyproject-build
+    twine upload dist/*
+
+# Tool settings
 [pytest]
 testpaths = ogstools
 xfail_strict = true