diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index f8203175e9f6b3dee571b5ad0572c4d1a067362b..75c8bf0a07aeb6878408416367275bf928b4af6e 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -1,6 +1,8 @@
 stages:
     - test
-    - examples
+    - deploy_test
+    - test_install
+    - deploy_prod
 
 test_docker:
     stage: test
@@ -12,3 +14,35 @@ test_docker:
         - export DEBIAN_FRONTEND=noninteractive
         - apt install -yq git python3 python3-pip python3-venv
     script: ./run_tests.sh
+    rules:
+        - if: '$CI_COMMIT_TAG == null'
+
+deploy to testpypi:
+  stage: deploy_test
+  image: python:3.8
+  only:
+    - tags
+  script:
+    - pip install twine
+    - python setup.py sdist bdist_wheel
+    - twine upload -u $PYPI_TEST_USER -p $PYPI_TEST_PASSWORD --repository-url https://test.pypi.org/legacy/ --skip-existing dist/*
+
+install from testpypi:
+  stage: test_install
+  image: python:3.8
+  needs: ["deploy to testpypi"]
+  script:
+    - pip install --index-url https://test.pypi.org/simple/ --extra-index-url https://pypi.org/simple/ enstools-encoding
+  artifacts:
+    when: on_failure
+    paths:
+      - "*.log"
+
+deploy to pypi:
+  stage: deploy_prod
+  image: python:3.8
+  needs: ["install from testpypi"]
+  script:
+    - pip install twine
+    - python setup.py sdist bdist_wheel
+    - twine upload -u $PYPI_USERNAME -p $PYPI_PASSWORD --skip-existing dist/*
\ No newline at end of file