diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index afdd2f8be01ba25fe452a38809d560603daa3d0e..bbd0fba9f2223680c5ad6ccf46d4cc67cd6f60a7 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -1,12 +1,48 @@
-include: "https://git.autistici.org/pipelines/debian/raw/master/common.yml"
+# mailman has stopped working after 'buster' (python2) thus keep CI pinned on
+# buster (from https://git.autistici.org/pipelines/debian/-/blob/master/common.yml)
+
+stages:
+  - test
+  - build
+  - release
 
-# debian/patches patches are kept applied in the tree, no need to
-# double-apply them when building the source package.
-# Thus remove the patches altogether and build an original tarball out of HEAD.
 pkg_src:
+  stage: build
+  image: "registry.git.autistici.org/pipelines/debian:buster-amd64"
+  # debian/patches patches are kept applied in the tree, no need to
+  # double-apply them when building the source package.
+  # Thus remove the patches altogether and build an original tarball out of HEAD.
   script:
     - rm -rf debian/patches
     - git archive --prefix orig/ --output ../$(dpkg-parsechangelog -SSource)_$(dpkg-parsechangelog -SVersion | sed -e  's/-[^-]*$//' -e 's/^[0-9]*://').orig.tar.gz HEAD
     # nicer version with git-buildpackage >= 0.9.8
     #- gbp export-orig  --upstream-tag=HEAD
     - build-dsc
+  artifacts:
+    paths:
+      - build-deb/
+    expire_in: 1 day
+
+build_pkg:buster:amd64:
+  image: "registry.git.autistici.org/pipelines/debian:buster-amd64"
+  tags:
+    - amd64
+  stage: build
+  needs: ["pkg_src"]
+  script:
+    - build-deb
+  artifacts:
+    paths:
+      - output-deb/
+    expire_in: 1 day
+
+# Changes to the 'master' branch are uploaded to the main repositories.
+upload_pkg:buster:
+  stage: release
+  # Use 'bookworm' image since the distro doesn't matter for upload
+  image: "registry.git.autistici.org/pipelines/debian:bookworm-amd64"
+  needs: ["build_pkg:buster:amd64"]
+  script:
+    - upload-packages --repository ${REPOSITORY:-float}/buster
+  only:
+    - master