diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 89aec5bdb4db0080f7c9a04fda28c7c31dd4c2ef..04e2d7ef80daca9f3cb976aaacba9e3228f430d5 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -93,6 +93,50 @@ bundle-raspberrypi4-64:
     CI_ONIRO_BUILD_FLAVOUR: linux
     CI_ONIRO_RECIPE_NAME: oniro-bundle-base
 
+publish-raspberrypi4-64:
+  # TODO: switch to zygoon/hawkbitctl
+  # blocked by https://gitlab.com/zygoon/go-hawkbit/-/issues/26
+  image: golang:latest
+  stage: update
+  dependencies: [bundle-raspberrypi4-64]
+  needs: [bundle-raspberrypi4-64]
+  variables:
+    CI_HAWKBIT_SWMOD_NAME: oniro-bundle-base-raspberrypi4-64
+    CI_HAWKBIT_DS_NAME: oniro-image-base-raspberrypi4-64
+  script: |
+    # TODO: remove this when switching to the dedicated docker container.
+    - go install gitlab.com/zygoon/go-hawkbit/cmd/hawkbitctl@latest
+    - test -L "$CI_PROJECT_DIR"/artifacts/images/raspberrypi4-64/oniro-bundle-base-raspberrypi4-64.raucb)" || (
+        echo "precondition failed - bundle file missing or not a symbolic link"
+        && ls -l "$CI_PROJECT_DIR"
+        && exit 1 )
+    - CI_BUNDLE_FILE="$(readlink "$CI_PROJECT_DIR"/artifacts/images/raspberrypi4-64/oniro-bundle-base-raspberrypi4-64.raucb)"
+    - CI_BUNDLE_VERSION="$(echo "$CI_BUNDLE_FILE" | awk -e 'BEGIN { RS = "-" } /.*\.raucb/ { sub(".raucb", "", $NF); print $NF }')"
+    # TODO: create or find sw mod type for SysOTA + RAUC bundle
+    - hawkbitctl create software-module \
+        -name "$CI_HAWKBIT_SWMOD_NAME" \
+        -version "$CI_BUNDLE_VERSION" \
+        -type os \
+        -vendor Onrio \
+        -description "Automatic build from Oniro CI"
+    # TODO: create or find ds type for Raspberry Pi 4 + Oniro
+    - hawkbitctl create distribution-set \
+        -name "$CI_HAWKBIT_DS_NAME" \
+        -version "$CI_BUNDLE_VERSION" \
+        -type os_only \
+        -modules "$CI_HAWKBIT_SWMOD_NAME:$CI_BUNDLE_VERSION" \
+        -description "Automatic build from Oniro CI"
+    - hawkbitctl upload \
+        -m "$CI_HAWKBIT_SWMOD_NAME:$CI_HAWKBIT_SWMOD_VERSION" \
+        -a "$CI_BUNDLE_FILE"
+  rules:
+    # For merge requests, the publishing is optional and can be triggered manually.
+    - if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
+      when: manual
+      allow_failure: true
+    # Publishing is done only for scheduled builds
+    - if: '$CI_PIPELINE_SOURCE == "schedule"'
+
 .build-wic-image-daily:
   extends: .build-wic-image
   variables: