diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index fab4261bead5e44b8d1cfa63a795ee45c072700a..b4dbd477c554457234da032db3dac1ecf848d189 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -26,11 +26,10 @@ variables:
 stages:
   - lint
   - build
-  # - release
+  - release
 
 default:
-  tags: 
-    - qt
+  image: registry.skywarder.eu/avn/swd/docker/miosix:latest
 
 # Stage lint
 
@@ -53,11 +52,14 @@ find:
 
 build_linux:
   stage: build
+  image: registry.skywarder.eu/avn/swd/docker/qt/linux
+  before_script:
+    - QMAKE=/opt/qt/$QT_VERSION/gcc_64/bin/qmake
   script:
-    - ./sbs --clean
-    - Qt5_DIR=/opt/qt/$QT_VERSION/gcc_64/lib/cmake/Qt5/ ./sbs
+    - cmake -Bbuild -DCMAKE_CXX_COMPILER_LAUNCHER=ccache .
+    - cmake --build build -j 16
     - cd build
-    - QMAKE=/opt/qt/$QT_VERSION/gcc_64/bin/qmake linuxdeploy --plugin qt -e groundstation -d ../linuxdeploy/groundstation.desktop -i ../linuxdeploy/SkywardLogo.png --appdir AppDir
+    - linuxdeploy --plugin qt -e groundstation -d ../linuxdeploy/groundstation.desktop -i ../linuxdeploy/SkywardLogo.png --appdir AppDir
     - appimagetool AppDir
     - mv Ground_Station-x86_64.AppImage ../Ground_Station-$CI_COMMIT_SHORT_SHA-x86_64.AppImage
   artifacts:
@@ -68,20 +70,30 @@ build_linux:
 
 build_windows:
   stage: build
+  image: registry.skywarder.eu/avn/swd/docker/qt/windows
   before_script:
     - export PATH=/home/gitlab-runner/mxe/usr/bin:$PATH
   script:
-    - ./sbs --clean
-    - x86_64-w64-mingw32.static-qmake-qt5 CONFIG+=release CONFIG+=force_debug_info
-    - make
-    - mv release/SkywardHub.exe Ground_Station-$CI_COMMIT_SHORT_SHA.exe
+    - x86_64-w64-mingw32.static-cmake -Bbuild -DCMAKE_CXX_COMPILER_LAUNCHER=ccache .
+    - x86_64-w64-mingw32.static-cmake --build build -j 16
+    - mv build/groundstation.exe Ground_Station-$CI_COMMIT_SHORT_SHA.exe
   artifacts:
     name: Windows executable
     paths:
       - Ground_Station-$CI_COMMIT_SHORT_SHA.exe
     expire_in: 7 days
 
-  # release:
-  #   tag_name: latest-$CI_COMMIT_SHORT_SHA
-  #   name: Continuous build
-  #   description: Latest build
+post_on_slack:
+  stage: release
+  image: curlimages/curl
+  script:
+    - |
+      curl -XPOST -H "Content-type: application/json" -d "{
+        \"project_id\": $CI_PROJECT_ID,
+        \"pipeline_id\": $CI_PIPELINE_ID,
+        \"message\": \"Bruh, SkywardHub just dropped a new build!\",
+        \"commit_message\": \"${CI_COMMIT_MESSAGE//[$'\n']}\",
+        \"channel_id\": \"$SLACK_CHANNEL_ID\"
+      }" https://api.skywarder.eu/post_job_artifacts
+  rules:
+    - if: $CI_COMMIT_BRANCH == "main"
diff --git a/CMakeLists.txt b/CMakeLists.txt
index c5847472d2f17a6458b387ae135a5563fe0b20f4..6f386e77a9829d61c0858b644572dee64de39eff 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,8 +1,8 @@
-# Copyright (c) 2022 Skyward Experimental Rocketry
+# Copyright (c) 2024 Skyward Experimental Rocketry
 # Author: Damiano Amatruda, Alberto Nidasio
 #
 # Permission is hereby granted, free of charge, to any person obtaining a copy
-# of this software and associated documentation files (the "Software"), to deal
+# of this software and associated documentation files(the "Software"), to deal
 # in the Software without restriction, including without limitation the rights
 # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 # copies of the Software, and to permit persons to whom the Software is
@@ -20,8 +20,8 @@
 # THE SOFTWARE.
 
 cmake_minimum_required(VERSION 3.16)
-add_subdirectory(libs/mavlink-skyward-lib EXCLUDE_FROM_ALL)
-add_subdirectory(libs/backward-cpp)
+# For now we keep debug information on
+set(CMAKE_BUILD_TYPE RelWithDebInfo)
 
 project(SkywardHub)
 
@@ -32,12 +32,15 @@ set(CMAKE_AUTOMOC ON)
 set(CMAKE_AUTORCC ON)
 set(CMAKE_AUTOUIC ON)
 
-find_package(Qt5 REQUIRED COMPONENTS
-    Widgets
-    SerialPort
-    PrintSupport
-    3DCore 3DExtras 3DRender 3DInput
-)
+# MAvLink Skyward library
+add_subdirectory(libs/mavlink-skyward-lib EXCLUDE_FROM_ALL)
+
+# Backward-cpp
+set(MINGW_MSVCR_LIBRARY msvcrt CACHE STRING "Mingw MSVC runtime import library") # Fix dependency on msvcr90
+add_subdirectory(libs/backward-cpp)
+
+# Qt5 and its modules
+find_package(Qt5 REQUIRED COMPONENTS Widgets SerialPort PrintSupport 3DCore 3DExtras 3DRender 3DInput)
 
 add_executable(groundstation
     src/shared/Components/ModulesPicker/ModulesPicker.cpp
@@ -102,30 +105,27 @@ target_link_libraries(groundstation PUBLIC
     Qt5::3DInput
     Mavlink::Mavlink
 )
-if (APPLE)
-    set_target_properties(groundstation PROPERTIES MACOSX_BUNDLE TRUE)
-endif ()
 
-add_backward(groundstation)
+# Prevent the creation of a console window on Windows
+set_target_properties(groundstation PROPERTIES WIN32_EXECUTABLE TRUE)
 
-if (UNIX)
+# Create an applkication build on MacOS
+set_target_properties(groundstation PROPERTIES MACOSX_BUNDLE TRUE)
+
+add_backward(groundstation)
+if(UNIX)
     set(BACKWARD_HAS_DW 1)
     set(BACKWARD_HAS_LIBUNWIND 1)
-endif (UNIX)
+endif(UNIX)
 
-
-if (DEFINED ENV{WIN_DEPLOY_QT})
+# If WIN_DEPLOY_QT is defined, execute windeployqt.exe after every build.
+# https://doc.qt.io/qt-5/windows-deployment.html#the-windows-deployment-tool
+if(DEFINED ENV{WIN_DEPLOY_QT})
     message("-- Using windeployqt.exe from $ENV{WIN_DEPLOY_QT}")
-    # Execute windeployqt.exe in the binary directory after every build.
-    # It adds all the necessary data in the directory to run the executable without external dependencies.
-    # Reference: https://doc.qt.io/qt-5/windows-deployment.html#the-windows-deployment-tool
     add_custom_command(
-            TARGET groundstation POST_BUILD
-            COMMAND $ENV{WIN_DEPLOY_QT} groundstation.exe
-            WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
-            COMMENT "Running windeployqt.exe..."
+        TARGET groundstation POST_BUILD
+        COMMAND $ENV{WIN_DEPLOY_QT} groundstation.exe
+        WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
+        COMMENT "Running windeployqt.exe..."
     )
-endif ()
-
-# For now we keep debug information on
-set(CMAKE_BUILD_TYPE RelWithDebInfo)
+endif()