diff --git a/.gitignore b/.gitignore
index 567609b1234a9b8806c5a05da6c866e480aa148d..6f31401f787928dc3bb3e2622578f889336d1d92 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1 +1,2 @@
 build/
+.vscode/
diff --git a/.gitlab-ci.common.yml b/.gitlab-ci.common.yml
index 37762af3eaddbf028efd735f6c452e97f345a41c..82494622e8305a7bedd95cd7a8292b0d20d823c7 100644
--- a/.gitlab-ci.common.yml
+++ b/.gitlab-ci.common.yml
@@ -40,13 +40,11 @@ build-docker-ubuntu-22.04:
   stage: prepare
   needs: ["versioning"]
   image: docker:latest
+  before_script:
+    - echo $CI_REGISTRY_PASSWORD | docker login -u $CI_REGISTRY_USER --password-stdin $CI_REGISTRY
   script:
     - |
       if ! docker manifest inspect $BASE_IMAGE > /dev/null || [ "$BUILD_DOCKER_IMAGE" = "1" ]; then
         docker build --tag $BASE_IMAGE -f ci/ubuntu_22_04-base .
         docker push $BASE_IMAGE
       fi
-  before_script:
-    - echo $CI_REGISTRY_PASSWORD | docker login -u $CI_REGISTRY_USER --password-stdin $CI_REGISTRY
-
-
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 4b85ed69b43fa4d319bbe640f46543265f422c40..ba892832390c101c122cf4515a99df47a602ea65 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -3,7 +3,7 @@
 
 include: .gitlab-ci.common.yml
 
-lint:
+format:
   stage: linting
   needs: ["versioning", "build-docker-ubuntu-22.04"]
   image: $BASE_IMAGE
@@ -13,13 +13,20 @@ lint:
     - git diff > format.patch
     # Fail when the patch is not empy (note ! can't be used directly.)
     - (! grep -q '^--- a'  format.patch)
+  artifacts:
+    when: on_failure
+      paths:
+        - format.patch
+
+tidy:
+  stage: linting
+  needs: ["versioning", "build-docker-ubuntu-22.04"]
+  image: $BASE_IMAGE
+  script:
     - mkdir build
     - cd build
     - cmake -DCMAKE_CXX_CLANG_TIDY=clang-tidy -G Ninja ..
     - ninja
-  artifacts:
-    paths:
-      - format.patch
 
 test:
   stage: test
@@ -28,7 +35,7 @@ test:
   script:
     - mkdir build
     - cd build
-    - cmake -DCMAKE_BUILD_TYPE=Debug -DBUILD_TESTINDBUILD_TESTSG=ON -DCMAKE_CXX_FLAGS="-coverage" -DCMAKE_EXE_LINKER_FLAGS="-coverage" -G Ninja ..
+    - cmake -DCMAKE_BUILD_TYPE=Debug -DBUILD_TESTING=ON -DCMAKE_CXX_FLAGS="-coverage" -DCMAKE_EXE_LINKER_FLAGS="-coverage" -G Ninja ..
     - ninja
     - ctest --output-on-failure |& tee ctest.out
     - mkdir coverage
@@ -57,10 +64,13 @@ build:
 
 pages:
   stage: pages
-  needs: ["versioning", "build-docker-ubuntu-22.04"]
+  needs: ["versioning", "test"]
   image: $BASE_IMAGE
   script:
-    - mkdir build
+    # Generate documentation.
     - cd build
     - cmake -DBUILD_DOCUMENTATION=ON -G Ninja ..
     - ninja sphinx
+    # Extract HTML coverage report.
+    - tar xfz coverage.tar.gz
+    # TODO: Add an index page with links to the documentation and coverage.
diff --git a/CMakeLists.txt b/CMakeLists.txt
index b03a8115f8c1a9f4f0988bf58b89b325541c043a..128da29ab49d278427f76aec16724357d9ed7ccc 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -14,6 +14,7 @@ option(BUILD_TESTING "Build the test suite" OFF)
 option(BUILD_DOCUMENTATION "Build the documentation" OFF)
 
 add_subdirectory(src)
+
 if(BUILD_TESTING)
   include(CTest)
   add_subdirectory(test)
diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt
index 9496c79dd1d77f979b06c662ea2b0caf9a517ed0..727559007f2aafdf71d62ca761641c3541fcd3d3 100644
--- a/test/CMakeLists.txt
+++ b/test/CMakeLists.txt
@@ -6,11 +6,10 @@ find_package(
   COMPONENTS unit_test_framework
   REQUIRED)
 
-add_executable(unittests main.cpp hello.cpp)
+add_executable(unittests main.cpp thello.cpp)
 
 target_link_libraries(unittests PRIVATE hello Boost::unit_test_framework)
 
 add_test(
   NAME unittests
-  COMMAND unittests -f JUNIT -k unittests.xml
-  WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIRECTORY}")
+  COMMAND unittests -f JUNIT -k unittests.xml)
diff --git a/test/hello.cpp b/test/thello.cpp
similarity index 100%
rename from test/hello.cpp
rename to test/thello.cpp