diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 966703505e707d7faad8e1bc125f370626f901f7..9ccf88d0be1327da755eb6ab5a6ea6dcb3b3e51e 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -40,20 +40,20 @@ build wheel for publication: # Executed on a tag
     - docker-executor
   script:
     - python3 setup.py egg_info -b+$CI_COMMIT_SHORT_SHA sdist bdist_wheel
-  only:
-    - tags
+  rules:
+    - if: '$CI_COMMIT_TAG'
   artifacts:
     paths:
       - ./dist/
 
-build wheel for development: # Executed on a commit
+build wheel for development: # Executed on non-tagged commit
   stage: build
   tags:
     - docker-executor
   script:
     - python3 setup.py egg_info -b+dev.$CI_COMMIT_SHORT_SHA sdist bdist_wheel
-  except:
-    - tags
+  rules:
+    - if: '$CI_COMMIT_TAG == null || $CI_COMMIT_TAG == ""'
   artifacts:
     paths:
       - ./dist/
@@ -67,7 +67,7 @@ unit tests:
     - docker-executor
   script:
     - echo $(ls -d ./dist/*.whl | grep $CI_COMMIT_SHORT_SHA)
-    - python3 -m pip install -U $(ls -d ./dist/*.whl | grep $CI_COMMIT_SHORT_SHA) --extra-index-url https://nexus.engageska-portugal.pt/repository/pypi/simple
+    - python3 -m pip install -U $(ls -d ./dist/*.whl | grep $CI_COMMIT_SHORT_SHA)
     - make test
     - scripts/validate-metadata.sh
   artifacts:
@@ -83,7 +83,7 @@ linting:
     - docker-executor
   script:
     - echo $(ls -d ./dist/*.whl | grep $CI_COMMIT_SHORT_SHA)
-    - python3 -m pip install -U $(ls -d ./dist/*.whl | grep $CI_COMMIT_SHORT_SHA) --extra-index-url https://nexus.engageska-portugal.pt/repository/pypi/simple
+    - python3 -m pip install -U $(ls -d ./dist/*.whl | grep $CI_COMMIT_SHORT_SHA)
     - make lint
   artifacts:
     paths:
@@ -101,12 +101,9 @@ publish to nexus:
     - scripts/validate-metadata.sh
     - python3 -m pip install twine
     - twine upload --repository-url $PYPI_REPOSITORY_URL dist/*
-  only:
-    variables:
-      # Confirm tag message exists
-      - $CI_COMMIT_MESSAGE =~ /^.+$/
-      # Confirm semantic versioning of tag
-      - $CI_COMMIT_TAG =~ /^((([0-9]+)\.([0-9]+)\.([0-9]+)(?:-([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?)(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?)$/
+  rules:
+    # PyPI package release only on tags, and confirm semantic versioning of tag
+    - if: '$CI_COMMIT_TAG && $CI_COMMIT_TAG =~ /^((([0-9]+)\.([0-9]+)\.([0-9]+)(?:-([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?)(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?)$/'
 
 release docker image:
   stage: release
@@ -118,11 +115,11 @@ release docker image:
   script:
     - make build
     - make push
-  when: manual
-  only:
-    refs:
-      - master
-
+  rules:
+    # Images only allow manual run on tags, and confirm semantic versioning of tag
+    - if: '$CI_COMMIT_TAG && $CI_COMMIT_TAG =~ /^((([0-9]+)\.([0-9]+)\.([0-9]+)(?:-([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?)(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?)$/'
+      when: manual
+      allow_failure: true
 
 pages:
   stage: pages