diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index cf2bf1c4f70871af495a3b04af54bab4b2ae9c10..a418e36914fb897df9b571674974d87569ca2f96 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -19,43 +19,31 @@ stages:
 
 # Jobs templates
 
-.set-executor: &executor
+default:
   tags:
     - docker-executor
-
-.install-deps-template: &install-deps
-  <<: *executor
   before_script:
-    - apt update && apt install make -y
+    - apt update && apt install make git -y
     - pip install poetry
     - poetry --version
     - poetry config virtualenvs.in-project true
     - poetry install -vv
-
-.quality-template: &quality
-  <<: *install-deps
   image: python:3.9-slim-bullseye
-  stage: quality
 
 .test-template: &test
-  <<: *install-deps
   stage: tests
+  image: "python:$PYTHON_VER-slim-bullseye"
   script: make test
 
 # Quality jobs
 
 run-pre-commit:
-  <<: *quality
+  stage: quality
   script: make check
   allow_failure: true
   after_script:
     - mkdir -pv changed
-    - |
-      test $CI_JOB_STATUS -eq "failed" &&
-      apt install git -y &&
-      git status --porcelain 
-        | awk 'match($1,"M"){print $2}' 
-        | xargs -r cp -vt changed
+    - git status --porcelain | awk 'match($1,"M"){print $2}' | xargs -r cp -vt changed
   artifacts:
     name: "$CI_JOB_NAME"
     expire_in: 7 days
@@ -65,20 +53,20 @@ run-pre-commit:
 
 # Tests jobs
 
-python3.9:
-  <<: *test
-  image: python:3.9-slim-bullseye
+"Run tests with Python 3.9":
+  extends: .test
+  variables: 
+    PYTHON_VER: "3.9"
 
-python3.10:
-  <<: *test
-  image: python:3.10-slim-bullseye
+"Run tests with Python 3.10":
+  extends: .test
+  variables: 
+    PYTHON_VER: "3.10"
 
 # Publish jobs
 
 publish:
-  <<: *install-deps
   stage: publish
-  image: python:3.10-slim-bullseye
   only:
     - /^v(\d+\.)(\d+\.)(\d+)$/
   script: