diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 3e009c3cc20993af29a358379f89a85904151caf..9cf3b634f3155e09388dcf7f82307d42af4e420c 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -1,3 +1,5 @@
+# vim: ts=2
+
 sonarqube-check:
   variables:
     SONAR_USER_HOME: "${CI_PROJECT_DIR}/.sonar"  # Defines the location of the analysis task cache
@@ -9,4 +11,15 @@ sonarqube-check:
   script:
     - sonar-scanner
   allow_failure: true
+  only:
+    - master
+    - merge_requests
 
+pypi-release:
+  rules:
+    - if: '$CI_COMMIT_TAG =~ /^v\d+/'
+  script:
+    - pip3 install --upgrade pip build twine
+    - rm -f dist/*
+    - python3 -m build
+    - TWINE_USERNAME=${PYPI_USER} TWINE_PASSWORD=${PYPI_PASSWORD} python3 -m twine upload --skip-existing --non-interactive dist/*