aboutsummaryrefslogtreecommitdiff
path: root/contrib
diff options
context:
space:
mode:
authorNullptrderef <nullptrderef@proton.me>2024-06-16 13:56:11 +0200
committerNullptrderef <nullptrderef@proton.me>2024-06-16 13:56:11 +0200
commit3cbfa7ab59d37b53724c15fed55a4880745db6a6 (patch)
treecf0e9b5ad27b04be38bf63f9d8092bec1d122ad5 /contrib
parentea28f2d34f308f812076e0128b1799acf8c686dd (diff)
generate ci targets
Diffstat (limited to 'contrib')
-rw-r--r--contrib/ci/Containerfile1
-rwxr-xr-xcontrib/ci/ci.sh5
-rwxr-xr-xcontrib/ci/generate-jobs75
l---------contrib/ci/jobs/1-build-amd64/build.sh1
l---------contrib/ci/jobs/1-build-amd64/job.sh1
l---------contrib/ci/jobs/1-build/build.sh1
l---------contrib/ci/jobs/1-build/job.sh1
l---------contrib/ci/jobs/10-deb-package-riscv64/install-fix.patch1
l---------contrib/ci/jobs/10-deb-package-riscv64/job.sh1
l---------contrib/ci/jobs/10-deb-package-riscv64/version.sh1
-rw-r--r--contrib/ci/jobs/100-build-debian-bookworm-amd64-generated/Containerfile (renamed from contrib/ci/riscv64.Containerfile)3
-rwxr-xr-xcontrib/ci/jobs/100-build-debian-bookworm-amd64-generated/build.sh (renamed from contrib/ci/common/debian/build/build.sh)0
-rwxr-xr-xcontrib/ci/jobs/100-build-debian-bookworm-amd64-generated/job.sh (renamed from contrib/ci/common/debian/build/job.sh)0
-rw-r--r--contrib/ci/jobs/101-deb-package-debian-bookworm-amd64-generated/Containerfile68
-rw-r--r--contrib/ci/jobs/101-deb-package-debian-bookworm-amd64-generated/install-fix.patch (renamed from contrib/ci/common/debian/deb-package/install-fix.patch)0
-rwxr-xr-xcontrib/ci/jobs/101-deb-package-debian-bookworm-amd64-generated/job.sh (renamed from contrib/ci/common/debian/deb-package/job.sh)0
-rwxr-xr-xcontrib/ci/jobs/101-deb-package-debian-bookworm-amd64-generated/version.sh (renamed from contrib/ci/common/debian/deb-package/version.sh)0
-rw-r--r--contrib/ci/jobs/102-deploy-package-debian-bookworm-amd64-generated/config.ini5
-rwxr-xr-xcontrib/ci/jobs/102-deploy-package-debian-bookworm-amd64-generated/job.sh14
-rw-r--r--contrib/ci/jobs/105-build-debian-bookworm-arm64-generated/Containerfile68
-rwxr-xr-xcontrib/ci/jobs/105-build-debian-bookworm-arm64-generated/build.sh14
-rw-r--r--contrib/ci/jobs/105-build-debian-bookworm-arm64-generated/config.ini (renamed from contrib/ci/jobs/7-deb-package-arm64/config.ini)3
-rwxr-xr-xcontrib/ci/jobs/105-build-debian-bookworm-arm64-generated/job.sh6
-rw-r--r--contrib/ci/jobs/106-deb-package-debian-bookworm-arm64-generated/Containerfile68
-rw-r--r--contrib/ci/jobs/106-deb-package-debian-bookworm-arm64-generated/config.ini7
-rw-r--r--contrib/ci/jobs/106-deb-package-debian-bookworm-arm64-generated/install-fix.patch13
-rwxr-xr-xcontrib/ci/jobs/106-deb-package-debian-bookworm-arm64-generated/job.sh23
-rwxr-xr-xcontrib/ci/jobs/106-deb-package-debian-bookworm-arm64-generated/version.sh17
-rw-r--r--contrib/ci/jobs/107-deploy-package-debian-bookworm-arm64-generated/config.ini5
-rwxr-xr-xcontrib/ci/jobs/107-deploy-package-debian-bookworm-arm64-generated/job.sh14
l---------contrib/ci/jobs/11-deploy-package-riscv641
-rw-r--r--contrib/ci/jobs/110-build-debian-trixie-amd64-generated/Containerfile68
-rwxr-xr-xcontrib/ci/jobs/110-build-debian-trixie-amd64-generated/build.sh14
-rwxr-xr-xcontrib/ci/jobs/110-build-debian-trixie-amd64-generated/job.sh6
-rw-r--r--contrib/ci/jobs/111-deb-package-debian-trixie-amd64-generated/Containerfile68
-rw-r--r--contrib/ci/jobs/111-deb-package-debian-trixie-amd64-generated/install-fix.patch13
-rwxr-xr-xcontrib/ci/jobs/111-deb-package-debian-trixie-amd64-generated/job.sh23
-rwxr-xr-xcontrib/ci/jobs/111-deb-package-debian-trixie-amd64-generated/version.sh17
-rw-r--r--contrib/ci/jobs/112-deploy-package-debian-trixie-amd64-generated/config.ini5
-rwxr-xr-xcontrib/ci/jobs/112-deploy-package-debian-trixie-amd64-generated/job.sh14
-rw-r--r--contrib/ci/jobs/115-build-debian-trixie-arm64-generated/Containerfile68
-rwxr-xr-xcontrib/ci/jobs/115-build-debian-trixie-arm64-generated/build.sh14
-rw-r--r--contrib/ci/jobs/115-build-debian-trixie-arm64-generated/config.ini7
-rwxr-xr-xcontrib/ci/jobs/115-build-debian-trixie-arm64-generated/job.sh6
-rw-r--r--contrib/ci/jobs/116-deb-package-debian-trixie-arm64-generated/Containerfile68
-rw-r--r--contrib/ci/jobs/116-deb-package-debian-trixie-arm64-generated/config.ini7
-rw-r--r--contrib/ci/jobs/116-deb-package-debian-trixie-arm64-generated/install-fix.patch13
-rwxr-xr-xcontrib/ci/jobs/116-deb-package-debian-trixie-arm64-generated/job.sh23
-rwxr-xr-xcontrib/ci/jobs/116-deb-package-debian-trixie-arm64-generated/version.sh17
-rw-r--r--contrib/ci/jobs/117-deploy-package-debian-trixie-arm64-generated/config.ini5
-rwxr-xr-xcontrib/ci/jobs/117-deploy-package-debian-trixie-arm64-generated/job.sh14
-rw-r--r--contrib/ci/jobs/120-build-debian-unstable-amd64-generated/Containerfile68
-rwxr-xr-xcontrib/ci/jobs/120-build-debian-unstable-amd64-generated/build.sh14
-rwxr-xr-xcontrib/ci/jobs/120-build-debian-unstable-amd64-generated/job.sh6
-rw-r--r--contrib/ci/jobs/121-deb-package-debian-unstable-amd64-generated/Containerfile68
-rw-r--r--contrib/ci/jobs/121-deb-package-debian-unstable-amd64-generated/install-fix.patch13
-rwxr-xr-xcontrib/ci/jobs/121-deb-package-debian-unstable-amd64-generated/job.sh23
-rwxr-xr-xcontrib/ci/jobs/121-deb-package-debian-unstable-amd64-generated/version.sh17
-rw-r--r--contrib/ci/jobs/122-deploy-package-debian-unstable-amd64-generated/config.ini5
-rwxr-xr-xcontrib/ci/jobs/122-deploy-package-debian-unstable-amd64-generated/job.sh14
-rw-r--r--contrib/ci/jobs/125-build-debian-unstable-arm64-generated/Containerfile68
-rwxr-xr-xcontrib/ci/jobs/125-build-debian-unstable-arm64-generated/build.sh14
-rw-r--r--contrib/ci/jobs/125-build-debian-unstable-arm64-generated/config.ini7
-rwxr-xr-xcontrib/ci/jobs/125-build-debian-unstable-arm64-generated/job.sh6
-rw-r--r--contrib/ci/jobs/126-deb-package-debian-unstable-arm64-generated/Containerfile68
-rw-r--r--contrib/ci/jobs/126-deb-package-debian-unstable-arm64-generated/config.ini7
-rw-r--r--contrib/ci/jobs/126-deb-package-debian-unstable-arm64-generated/install-fix.patch13
-rwxr-xr-xcontrib/ci/jobs/126-deb-package-debian-unstable-arm64-generated/job.sh23
-rwxr-xr-xcontrib/ci/jobs/126-deb-package-debian-unstable-arm64-generated/version.sh17
-rw-r--r--contrib/ci/jobs/127-deploy-package-debian-unstable-arm64-generated/config.ini5
-rwxr-xr-xcontrib/ci/jobs/127-deploy-package-debian-unstable-arm64-generated/job.sh14
-rw-r--r--contrib/ci/jobs/130-build-debian-unstable-riscv64-generated/Containerfile68
-rwxr-xr-xcontrib/ci/jobs/130-build-debian-unstable-riscv64-generated/build.sh14
-rw-r--r--contrib/ci/jobs/130-build-debian-unstable-riscv64-generated/config.ini (renamed from contrib/ci/jobs/9-build-riscv64/config.ini)3
-rwxr-xr-xcontrib/ci/jobs/130-build-debian-unstable-riscv64-generated/job.sh6
-rw-r--r--contrib/ci/jobs/131-deb-package-debian-unstable-riscv64-generated/Containerfile68
-rw-r--r--contrib/ci/jobs/131-deb-package-debian-unstable-riscv64-generated/config.ini (renamed from contrib/ci/jobs/10-deb-package-riscv64/config.ini)3
-rw-r--r--contrib/ci/jobs/131-deb-package-debian-unstable-riscv64-generated/install-fix.patch13
-rwxr-xr-xcontrib/ci/jobs/131-deb-package-debian-unstable-riscv64-generated/job.sh23
-rwxr-xr-xcontrib/ci/jobs/131-deb-package-debian-unstable-riscv64-generated/version.sh17
-rw-r--r--contrib/ci/jobs/132-deploy-package-debian-unstable-riscv64-generated/config.ini5
-rwxr-xr-xcontrib/ci/jobs/132-deploy-package-debian-unstable-riscv64-generated/job.sh14
l---------contrib/ci/jobs/4-deb-package-amd64/install-fix.patch2
l---------contrib/ci/jobs/4-deb-package-amd64/job.sh2
l---------contrib/ci/jobs/4-deb-package-amd64/version.sh2
l---------contrib/ci/jobs/6-build-arm64/build.sh2
-rw-r--r--contrib/ci/jobs/6-build-arm64/config.ini2
l---------contrib/ci/jobs/6-build-arm64/job.sh2
l---------contrib/ci/jobs/7-deb-package-arm64/install-fix.patch1
l---------contrib/ci/jobs/7-deb-package-arm64/job.sh1
l---------contrib/ci/jobs/7-deb-package-arm64/version.sh1
l---------contrib/ci/jobs/8-deploy-package-arm641
l---------contrib/ci/jobs/9-build-riscv64/build.sh1
l---------contrib/ci/jobs/9-build-riscv64/job.sh1
-rwxr-xr-xcontrib/ci/run-all-jobs5
-rw-r--r--contrib/ci/targets/debian/Containerfile68
-rwxr-xr-xcontrib/ci/targets/debian/build/build.sh14
-rwxr-xr-xcontrib/ci/targets/debian/build/job.sh6
-rw-r--r--contrib/ci/targets/debian/deb-package/install-fix.patch13
-rwxr-xr-xcontrib/ci/targets/debian/deb-package/job.sh23
-rwxr-xr-xcontrib/ci/targets/debian/deb-package/version.sh17
-rw-r--r--contrib/ci/targets/debian/deploy-package/config.ini5
-rwxr-xr-xcontrib/ci/targets/debian/deploy-package/job.sh14
-rwxr-xr-xcontrib/ci/targets/debian/setup-job.sh50
104 files changed, 1800 insertions, 24 deletions
diff --git a/contrib/ci/Containerfile b/contrib/ci/Containerfile
index a7fe8a3ac..16d981f40 100644
--- a/contrib/ci/Containerfile
+++ b/contrib/ci/Containerfile
@@ -1,3 +1,4 @@
+# This containerfile is used when no job-specific one exists.
FROM docker.io/library/debian:bookworm
ENV DEBIAN_FRONTEND=noninteractive
diff --git a/contrib/ci/ci.sh b/contrib/ci/ci.sh
index f454a6e3b..611977bd3 100755
--- a/contrib/ci/ci.sh
+++ b/contrib/ci/ci.sh
@@ -9,9 +9,12 @@ JOB_NAME="${1}"
JOB_ARCH=$((grep CONTAINER_ARCH contrib/ci/jobs/${JOB_NAME}/config.ini | cut -d' ' -f 3) || echo "${2:-amd64}")
JOB_CONTAINER=$((grep CONTAINER_NAME contrib/ci/jobs/${JOB_NAME}/config.ini | cut -d' ' -f 3) || echo "localhost/${REPO_NAME}:${JOB_ARCH}")
CONTAINER_BUILD=$((grep CONTAINER_BUILD contrib/ci/jobs/${JOB_NAME}/config.ini | cut -d' ' -f 3) || echo "True")
-CONTAINERFILE="contrib/ci/$JOB_ARCH.Containerfile"
+CONTAINERFILE="contrib/ci/jobs/${JOB_NAME}/Containerfile"
if ! [[ -f "$CONTAINERFILE" ]]; then
+ CONTAINERFILE="contrib/ci/$JOB_ARCH.Containerfile"
+fi;
+if ! [[ -f "$CONTAINERFILE" ]]; then
CONTAINERFILE="$(dirname "$CONTAINERFILE")/Containerfile"
fi;
diff --git a/contrib/ci/generate-jobs b/contrib/ci/generate-jobs
new file mode 100755
index 000000000..ee40d46c0
--- /dev/null
+++ b/contrib/ci/generate-jobs
@@ -0,0 +1,75 @@
+#!/bin/bash
+set -e
+
+export CI_DIR="$(pwd)/$(dirname $0)";
+
+# the number to use as a base for generated ci job indexes
+BASE_IDX=100;
+# the amount of indexes to increment - the room a script has to put scripts in.
+INCREMENT=5;
+
+# our build targets
+BUILD_FOR=(
+ # Format:
+ # distro codename arch
+ # The codename must also be a tag on the distro
+ "debian bookworm amd64"
+ "debian bookworm arm64"
+ "debian trixie amd64"
+ "debian trixie arm64"
+ "debian unstable amd64"
+ "debian unstable arm64"
+ "debian unstable riscv64"
+)
+
+declare -A DISTRO_IMAGES;
+DISTRO_IMAGES['debian']='docker.io/debian';
+DISTRO_IMAGES['archlinux']='docker.io/archlinux';
+
+chmod +w -R $CI_DIR/jobs;
+rm -rf $CI_DIR/jobs/*-generated;
+
+TMPBINDIR="/tmp/ci-temp-bin-$RANDOM/"
+mkdir -p "$TMPBINDIR"
+export PATH="$PATH:$TMPBINDIR"
+
+mkfn() {
+ echo "$2" > "$TMPBINDIR/$1";
+ chmod +x "$TMPBINDIR/$1";
+}
+
+mkfn mktarget '#!/bin/bash
+RELATIVEIDX=$1
+JOBNAME="$2"
+OURIDX=$(($IDX + $RELATIVEIDX))
+JOB="${OURIDX}-${JOBNAME}-${DISTRO}-${CODENAME}-${ARCH}-generated"
+cd "$CI_DIR/jobs"
+mkdir -p "${JOB}"
+echo -n "${JOB}"
+'
+
+for TARGET in "${BUILD_FOR[@]}"; do
+ export DISTRO=$(awk '{print $1}' <<< "$TARGET");
+ export CODENAME=$(awk '{print $2}' <<< "$TARGET");
+ export ARCH=$(awk '{print $3}' <<< "$TARGET");
+ export OCI_IMAGE="${DISTRO_IMAGES[$DISTRO]}";
+ export DISTRO_TARGET="$CI_DIR/targets/$DISTRO";
+ if [[ -d "$DISTRO_TARGET/$CODENAME" ]]; then
+ DISTRO_TARGET="$DISTRO_TARGET/$CODENAME";
+ fi;
+ if [[ -d "$DISTRO_TARGET/$ARCH" ]]; then
+ DISTRO_TARGET="$DISTRO_TARGET/$ARCH";
+ fi;
+ export CONTAINERFILE="$DISTRO_TARGET/Containerfile";
+ export IDX=$BASE_IDX;
+ echo "";
+ echo "> Generating scripts for $DISTRO ($CODENAME) on architecture $ARCH";
+ echo "| > Base Image: $OCI_IMAGE";
+ echo "| > Base Containerfile: $CONTAINERFILE";
+ echo "| > Index: $BASE_IDX";
+ "$DISTRO_TARGET/setup-job.sh";
+ BASE_IDX=$(($BASE_IDX + $INCREMENT));
+done;
+
+rm -rf "$TMPBINDIR"
+chmod -w -R $CI_DIR/jobs/*-generated
diff --git a/contrib/ci/jobs/1-build-amd64/build.sh b/contrib/ci/jobs/1-build-amd64/build.sh
deleted file mode 120000
index e8d2a7f97..000000000
--- a/contrib/ci/jobs/1-build-amd64/build.sh
+++ /dev/null
@@ -1 +0,0 @@
-../../common/debian/build/build.sh \ No newline at end of file
diff --git a/contrib/ci/jobs/1-build-amd64/job.sh b/contrib/ci/jobs/1-build-amd64/job.sh
deleted file mode 120000
index a97450993..000000000
--- a/contrib/ci/jobs/1-build-amd64/job.sh
+++ /dev/null
@@ -1 +0,0 @@
-../../common/debian/build/job.sh \ No newline at end of file
diff --git a/contrib/ci/jobs/1-build/build.sh b/contrib/ci/jobs/1-build/build.sh
new file mode 120000
index 000000000..3babff0b8
--- /dev/null
+++ b/contrib/ci/jobs/1-build/build.sh
@@ -0,0 +1 @@
+../../targets/debian/build/build.sh \ No newline at end of file
diff --git a/contrib/ci/jobs/1-build/job.sh b/contrib/ci/jobs/1-build/job.sh
new file mode 120000
index 000000000..8a185151e
--- /dev/null
+++ b/contrib/ci/jobs/1-build/job.sh
@@ -0,0 +1 @@
+../../targets/debian/build/job.sh \ No newline at end of file
diff --git a/contrib/ci/jobs/10-deb-package-riscv64/install-fix.patch b/contrib/ci/jobs/10-deb-package-riscv64/install-fix.patch
deleted file mode 120000
index 8abc5e3be..000000000
--- a/contrib/ci/jobs/10-deb-package-riscv64/install-fix.patch
+++ /dev/null
@@ -1 +0,0 @@
-../../common/debian/deb-package/install-fix.patch \ No newline at end of file
diff --git a/contrib/ci/jobs/10-deb-package-riscv64/job.sh b/contrib/ci/jobs/10-deb-package-riscv64/job.sh
deleted file mode 120000
index 905d8a638..000000000
--- a/contrib/ci/jobs/10-deb-package-riscv64/job.sh
+++ /dev/null
@@ -1 +0,0 @@
-../../common/debian/deb-package/job.sh \ No newline at end of file
diff --git a/contrib/ci/jobs/10-deb-package-riscv64/version.sh b/contrib/ci/jobs/10-deb-package-riscv64/version.sh
deleted file mode 120000
index 7c51b7217..000000000
--- a/contrib/ci/jobs/10-deb-package-riscv64/version.sh
+++ /dev/null
@@ -1 +0,0 @@
-../../common/debian/deb-package/version.sh \ No newline at end of file
diff --git a/contrib/ci/riscv64.Containerfile b/contrib/ci/jobs/100-build-debian-bookworm-amd64-generated/Containerfile
index 48b93a835..6e2c93980 100644
--- a/contrib/ci/riscv64.Containerfile
+++ b/contrib/ci/jobs/100-build-debian-bookworm-amd64-generated/Containerfile
@@ -1,5 +1,4 @@
-# This file is separate as trixie does not offer a stable riscv on docker yet.
-FROM docker.io/library/debian:unstable
+FROM docker.io/debian
ENV DEBIAN_FRONTEND=noninteractive
diff --git a/contrib/ci/common/debian/build/build.sh b/contrib/ci/jobs/100-build-debian-bookworm-amd64-generated/build.sh
index d3fcfab85..d3fcfab85 100755
--- a/contrib/ci/common/debian/build/build.sh
+++ b/contrib/ci/jobs/100-build-debian-bookworm-amd64-generated/build.sh
diff --git a/contrib/ci/common/debian/build/job.sh b/contrib/ci/jobs/100-build-debian-bookworm-amd64-generated/job.sh
index 8d79902c5..8d79902c5 100755
--- a/contrib/ci/common/debian/build/job.sh
+++ b/contrib/ci/jobs/100-build-debian-bookworm-amd64-generated/job.sh
diff --git a/contrib/ci/jobs/101-deb-package-debian-bookworm-amd64-generated/Containerfile b/contrib/ci/jobs/101-deb-package-debian-bookworm-amd64-generated/Containerfile
new file mode 100644
index 000000000..6e2c93980
--- /dev/null
+++ b/contrib/ci/jobs/101-deb-package-debian-bookworm-amd64-generated/Containerfile
@@ -0,0 +1,68 @@
+FROM docker.io/debian
+
+ENV DEBIAN_FRONTEND=noninteractive
+
+RUN apt-get update -yqq && \
+ apt-get install -yqq \
+ autoconf \
+ autopoint \
+ curl \
+ bash \
+ coreutils \
+ git \
+ libcurl4-gnutls-dev \
+ libgcrypt-dev \
+ libidn11-dev \
+ libjansson-dev \
+ libmicrohttpd-dev \
+ libpq-dev \
+ libqrencode-dev \
+ libsodium-dev \
+ libtool \
+ libunistring-dev \
+ make \
+ pkg-config \
+ python3-pip \
+ python3-sphinx \
+ python3-sphinx-rtd-theme \
+ recutils \
+ texinfo \
+ zlib1g-dev \
+ # For mustach testing (optional) \
+ libjson-c-dev \
+ # Debian packaging tools \
+ po-debconf \
+ build-essential \
+ debhelper-compat \
+ devscripts \
+ git-buildpackage \
+ # Documentation dependencies \
+ doxygen \
+ graphviz \
+ pandoc \
+ # Test suite dependencies \
+ jq \
+ postgresql \
+ sudo \
+ wget
+
+# Install Taler (and friends) packages
+RUN curl -sS https://deb.taler.net/apt-nightly/taler-bookworm-ci.sources \
+ | tee /etc/apt/sources.list.d/taler-bookworm-ci.sources
+
+RUN echo '\
+Package: * \n\
+Pin: origin "deb.taler.net" \n\
+Pin-Priority: 999' > /etc/apt/preferences.d/taler
+
+RUN cat /etc/apt/preferences.d/taler && \
+ apt-get update -y && \
+ apt-get install -y \
+ libgnunet-dev \
+ libgnunet \
+ gnunet \
+&& rm -rf /var/lib/apt/lists/*
+
+WORKDIR /workdir
+
+CMD ["bash", "/workdir/ci/ci.sh"]
diff --git a/contrib/ci/common/debian/deb-package/install-fix.patch b/contrib/ci/jobs/101-deb-package-debian-bookworm-amd64-generated/install-fix.patch
index 8334c5a7a..8334c5a7a 100644
--- a/contrib/ci/common/debian/deb-package/install-fix.patch
+++ b/contrib/ci/jobs/101-deb-package-debian-bookworm-amd64-generated/install-fix.patch
diff --git a/contrib/ci/common/debian/deb-package/job.sh b/contrib/ci/jobs/101-deb-package-debian-bookworm-amd64-generated/job.sh
index 922f8bf63..922f8bf63 100755
--- a/contrib/ci/common/debian/deb-package/job.sh
+++ b/contrib/ci/jobs/101-deb-package-debian-bookworm-amd64-generated/job.sh
diff --git a/contrib/ci/common/debian/deb-package/version.sh b/contrib/ci/jobs/101-deb-package-debian-bookworm-amd64-generated/version.sh
index 52031b23a..52031b23a 100755
--- a/contrib/ci/common/debian/deb-package/version.sh
+++ b/contrib/ci/jobs/101-deb-package-debian-bookworm-amd64-generated/version.sh
diff --git a/contrib/ci/jobs/102-deploy-package-debian-bookworm-amd64-generated/config.ini b/contrib/ci/jobs/102-deploy-package-debian-bookworm-amd64-generated/config.ini
new file mode 100644
index 000000000..8d6409a6e
--- /dev/null
+++ b/contrib/ci/jobs/102-deploy-package-debian-bookworm-amd64-generated/config.ini
@@ -0,0 +1,5 @@
+[build]
+HALT_ON_FAILURE = True
+WARN_ON_FAILURE = True
+CONTAINER_BUILD = False
+CONTAINER_NAME = nixery.dev/shell/rsync
diff --git a/contrib/ci/jobs/102-deploy-package-debian-bookworm-amd64-generated/job.sh b/contrib/ci/jobs/102-deploy-package-debian-bookworm-amd64-generated/job.sh
new file mode 100755
index 000000000..d39cf9987
--- /dev/null
+++ b/contrib/ci/jobs/102-deploy-package-debian-bookworm-amd64-generated/job.sh
@@ -0,0 +1,14 @@
+#!/bin/bash
+set -exuo pipefail
+
+ARTIFACT_PATH="/artifacts/exchange/${CI_COMMIT_REF}/*.deb"
+
+RSYNC_HOST="taler.host.internal"
+RSYNC_PORT=424242
+RSYNC_PATH="incoming_packages/bookworm-taler-ci/"
+RSYNC_DEST="rsync://${RSYNC_HOST}/${RSYNC_PATH}"
+
+
+rsync -vP \
+ --port ${RSYNC_PORT} \
+ ${ARTIFACT_PATH} ${RSYNC_DEST}
diff --git a/contrib/ci/jobs/105-build-debian-bookworm-arm64-generated/Containerfile b/contrib/ci/jobs/105-build-debian-bookworm-arm64-generated/Containerfile
new file mode 100644
index 000000000..6e2c93980
--- /dev/null
+++ b/contrib/ci/jobs/105-build-debian-bookworm-arm64-generated/Containerfile
@@ -0,0 +1,68 @@
+FROM docker.io/debian
+
+ENV DEBIAN_FRONTEND=noninteractive
+
+RUN apt-get update -yqq && \
+ apt-get install -yqq \
+ autoconf \
+ autopoint \
+ curl \
+ bash \
+ coreutils \
+ git \
+ libcurl4-gnutls-dev \
+ libgcrypt-dev \
+ libidn11-dev \
+ libjansson-dev \
+ libmicrohttpd-dev \
+ libpq-dev \
+ libqrencode-dev \
+ libsodium-dev \
+ libtool \
+ libunistring-dev \
+ make \
+ pkg-config \
+ python3-pip \
+ python3-sphinx \
+ python3-sphinx-rtd-theme \
+ recutils \
+ texinfo \
+ zlib1g-dev \
+ # For mustach testing (optional) \
+ libjson-c-dev \
+ # Debian packaging tools \
+ po-debconf \
+ build-essential \
+ debhelper-compat \
+ devscripts \
+ git-buildpackage \
+ # Documentation dependencies \
+ doxygen \
+ graphviz \
+ pandoc \
+ # Test suite dependencies \
+ jq \
+ postgresql \
+ sudo \
+ wget
+
+# Install Taler (and friends) packages
+RUN curl -sS https://deb.taler.net/apt-nightly/taler-bookworm-ci.sources \
+ | tee /etc/apt/sources.list.d/taler-bookworm-ci.sources
+
+RUN echo '\
+Package: * \n\
+Pin: origin "deb.taler.net" \n\
+Pin-Priority: 999' > /etc/apt/preferences.d/taler
+
+RUN cat /etc/apt/preferences.d/taler && \
+ apt-get update -y && \
+ apt-get install -y \
+ libgnunet-dev \
+ libgnunet \
+ gnunet \
+&& rm -rf /var/lib/apt/lists/*
+
+WORKDIR /workdir
+
+CMD ["bash", "/workdir/ci/ci.sh"]
diff --git a/contrib/ci/jobs/105-build-debian-bookworm-arm64-generated/build.sh b/contrib/ci/jobs/105-build-debian-bookworm-arm64-generated/build.sh
new file mode 100755
index 000000000..d3fcfab85
--- /dev/null
+++ b/contrib/ci/jobs/105-build-debian-bookworm-arm64-generated/build.sh
@@ -0,0 +1,14 @@
+#!/bin/bash
+set -exuo pipefail
+
+apt-get update
+apt-get upgrade -yqq
+
+./bootstrap
+./configure CFLAGS="-ggdb -O0" \
+ --enable-logging=verbose \
+ --disable-doc
+
+nump=$(grep processor /proc/cpuinfo | wc -l)
+make -j$(( $nump / 2 ))
+make
diff --git a/contrib/ci/jobs/7-deb-package-arm64/config.ini b/contrib/ci/jobs/105-build-debian-bookworm-arm64-generated/config.ini
index b5b4b5fe7..2a99a970e 100644
--- a/contrib/ci/jobs/7-deb-package-arm64/config.ini
+++ b/contrib/ci/jobs/105-build-debian-bookworm-arm64-generated/config.ini
@@ -2,5 +2,6 @@
HALT_ON_FAILURE = True
WARN_ON_FAILURE = True
CONTAINER_BUILD = True
-CONTAINER_NAME = gnunet:arm64
+CONTAINER_NAME = exchange:arm64
CONTAINER_ARCH = arm64
+
diff --git a/contrib/ci/jobs/105-build-debian-bookworm-arm64-generated/job.sh b/contrib/ci/jobs/105-build-debian-bookworm-arm64-generated/job.sh
new file mode 100755
index 000000000..8d79902c5
--- /dev/null
+++ b/contrib/ci/jobs/105-build-debian-bookworm-arm64-generated/job.sh
@@ -0,0 +1,6 @@
+#!/bin/bash
+set -exuo pipefail
+
+job_dir=$(dirname "${BASH_SOURCE[0]}")
+
+"${job_dir}"/build.sh
diff --git a/contrib/ci/jobs/106-deb-package-debian-bookworm-arm64-generated/Containerfile b/contrib/ci/jobs/106-deb-package-debian-bookworm-arm64-generated/Containerfile
new file mode 100644
index 000000000..6e2c93980
--- /dev/null
+++ b/contrib/ci/jobs/106-deb-package-debian-bookworm-arm64-generated/Containerfile
@@ -0,0 +1,68 @@
+FROM docker.io/debian
+
+ENV DEBIAN_FRONTEND=noninteractive
+
+RUN apt-get update -yqq && \
+ apt-get install -yqq \
+ autoconf \
+ autopoint \
+ curl \
+ bash \
+ coreutils \
+ git \
+ libcurl4-gnutls-dev \
+ libgcrypt-dev \
+ libidn11-dev \
+ libjansson-dev \
+ libmicrohttpd-dev \
+ libpq-dev \
+ libqrencode-dev \
+ libsodium-dev \
+ libtool \
+ libunistring-dev \
+ make \
+ pkg-config \
+ python3-pip \
+ python3-sphinx \
+ python3-sphinx-rtd-theme \
+ recutils \
+ texinfo \
+ zlib1g-dev \
+ # For mustach testing (optional) \
+ libjson-c-dev \
+ # Debian packaging tools \
+ po-debconf \
+ build-essential \
+ debhelper-compat \
+ devscripts \
+ git-buildpackage \
+ # Documentation dependencies \
+ doxygen \
+ graphviz \
+ pandoc \
+ # Test suite dependencies \
+ jq \
+ postgresql \
+ sudo \
+ wget
+
+# Install Taler (and friends) packages
+RUN curl -sS https://deb.taler.net/apt-nightly/taler-bookworm-ci.sources \
+ | tee /etc/apt/sources.list.d/taler-bookworm-ci.sources
+
+RUN echo '\
+Package: * \n\
+Pin: origin "deb.taler.net" \n\
+Pin-Priority: 999' > /etc/apt/preferences.d/taler
+
+RUN cat /etc/apt/preferences.d/taler && \
+ apt-get update -y && \
+ apt-get install -y \
+ libgnunet-dev \
+ libgnunet \
+ gnunet \
+&& rm -rf /var/lib/apt/lists/*
+
+WORKDIR /workdir
+
+CMD ["bash", "/workdir/ci/ci.sh"]
diff --git a/contrib/ci/jobs/106-deb-package-debian-bookworm-arm64-generated/config.ini b/contrib/ci/jobs/106-deb-package-debian-bookworm-arm64-generated/config.ini
new file mode 100644
index 000000000..2a99a970e
--- /dev/null
+++ b/contrib/ci/jobs/106-deb-package-debian-bookworm-arm64-generated/config.ini
@@ -0,0 +1,7 @@
+[build]
+HALT_ON_FAILURE = True
+WARN_ON_FAILURE = True
+CONTAINER_BUILD = True
+CONTAINER_NAME = exchange:arm64
+CONTAINER_ARCH = arm64
+
diff --git a/contrib/ci/jobs/106-deb-package-debian-bookworm-arm64-generated/install-fix.patch b/contrib/ci/jobs/106-deb-package-debian-bookworm-arm64-generated/install-fix.patch
new file mode 100644
index 000000000..8334c5a7a
--- /dev/null
+++ b/contrib/ci/jobs/106-deb-package-debian-bookworm-arm64-generated/install-fix.patch
@@ -0,0 +1,13 @@
+diff --git a/debian/taler-exchange.install b/debian/taler-exchange.install
+index 631c270b..072c6231 100644
+--- a/debian/taler-exchange.install
++++ b/debian/taler-exchange.install
+@@ -36,6 +36,6 @@ usr/share/taler/exchange/templates/*.must
+ debian/etc-taler-exchange/* etc/
+
+ # Terms of service / privacy policy templates
+-usr/share/taler/exchange/*.rst
++#usr/share/taler/exchange/terms/*.rst
+ # Translations of ToS/PP
+-usr/share/taler/exchange/locale/*/LC_MESSAGES/*.po
++#usr/share/taler/exchange/terms/locale/*/LC_MESSAGES/*.po
diff --git a/contrib/ci/jobs/106-deb-package-debian-bookworm-arm64-generated/job.sh b/contrib/ci/jobs/106-deb-package-debian-bookworm-arm64-generated/job.sh
new file mode 100755
index 000000000..922f8bf63
--- /dev/null
+++ b/contrib/ci/jobs/106-deb-package-debian-bookworm-arm64-generated/job.sh
@@ -0,0 +1,23 @@
+#!/bin/bash
+set -exuo pipefail
+# This file is in the public domain.
+# Helper script to build the latest DEB packages in the container.
+
+
+unset LD_LIBRARY_PATH
+
+# Install build-time dependencies.
+# Update apt cache first
+apt-get update
+apt-get upgrade -y
+mk-build-deps --install --tool='apt-get -o Debug::pkgProblemResolver=yes --no-install-recommends --yes' debian/control
+
+export VERSION="$(./contrib/ci/jobs/4-deb-package/version.sh)"
+echo "Building package version ${VERSION}"
+EMAIL=none gbp dch --dch-opt=-b --ignore-branch --debian-tag="%(version)s" --git-author --new-version="${VERSION}"
+./bootstrap
+dpkg-buildpackage -rfakeroot -b -uc -us
+
+ls -alh ../*.deb
+mkdir -p /artifacts/exchange/${CI_COMMIT_REF} # Variable comes from CI environment
+mv ../*.deb /artifacts/exchange/${CI_COMMIT_REF}/
diff --git a/contrib/ci/jobs/106-deb-package-debian-bookworm-arm64-generated/version.sh b/contrib/ci/jobs/106-deb-package-debian-bookworm-arm64-generated/version.sh
new file mode 100755
index 000000000..52031b23a
--- /dev/null
+++ b/contrib/ci/jobs/106-deb-package-debian-bookworm-arm64-generated/version.sh
@@ -0,0 +1,17 @@
+#!/bin/sh
+set -ex
+
+BRANCH=$(git name-rev --name-only HEAD)
+if [ -z "${BRANCH}" ]; then
+ exit 1
+else
+ # "Unshallow" our checkout, but only our current branch, and exclude the submodules.
+ git fetch --no-recurse-submodules --tags --depth=1000 origin "${BRANCH}"
+ RECENT_VERSION_TAG=$(git describe --tags --match 'v*.*.*' --exclude '*-dev*' --always --abbrev=0 HEAD || exit 1)
+ commits="$(git rev-list ${RECENT_VERSION_TAG}..HEAD --count)"
+ if [ "${commits}" = "0" ]; then
+ git describe --tag HEAD | sed -r 's/^v//' || exit 1
+ else
+ echo $(echo ${RECENT_VERSION_TAG} | sed -r 's/^v//')-${commits}-$(git rev-parse --short=8 HEAD)
+ fi
+fi
diff --git a/contrib/ci/jobs/107-deploy-package-debian-bookworm-arm64-generated/config.ini b/contrib/ci/jobs/107-deploy-package-debian-bookworm-arm64-generated/config.ini
new file mode 100644
index 000000000..8d6409a6e
--- /dev/null
+++ b/contrib/ci/jobs/107-deploy-package-debian-bookworm-arm64-generated/config.ini
@@ -0,0 +1,5 @@
+[build]
+HALT_ON_FAILURE = True
+WARN_ON_FAILURE = True
+CONTAINER_BUILD = False
+CONTAINER_NAME = nixery.dev/shell/rsync
diff --git a/contrib/ci/jobs/107-deploy-package-debian-bookworm-arm64-generated/job.sh b/contrib/ci/jobs/107-deploy-package-debian-bookworm-arm64-generated/job.sh
new file mode 100755
index 000000000..d39cf9987
--- /dev/null
+++ b/contrib/ci/jobs/107-deploy-package-debian-bookworm-arm64-generated/job.sh
@@ -0,0 +1,14 @@
+#!/bin/bash
+set -exuo pipefail
+
+ARTIFACT_PATH="/artifacts/exchange/${CI_COMMIT_REF}/*.deb"
+
+RSYNC_HOST="taler.host.internal"
+RSYNC_PORT=424242
+RSYNC_PATH="incoming_packages/bookworm-taler-ci/"
+RSYNC_DEST="rsync://${RSYNC_HOST}/${RSYNC_PATH}"
+
+
+rsync -vP \
+ --port ${RSYNC_PORT} \
+ ${ARTIFACT_PATH} ${RSYNC_DEST}
diff --git a/contrib/ci/jobs/11-deploy-package-riscv64 b/contrib/ci/jobs/11-deploy-package-riscv64
deleted file mode 120000
index a58645d78..000000000
--- a/contrib/ci/jobs/11-deploy-package-riscv64
+++ /dev/null
@@ -1 +0,0 @@
-5-deploy-package-amd64 \ No newline at end of file
diff --git a/contrib/ci/jobs/110-build-debian-trixie-amd64-generated/Containerfile b/contrib/ci/jobs/110-build-debian-trixie-amd64-generated/Containerfile
new file mode 100644
index 000000000..6e2c93980
--- /dev/null
+++ b/contrib/ci/jobs/110-build-debian-trixie-amd64-generated/Containerfile
@@ -0,0 +1,68 @@
+FROM docker.io/debian
+
+ENV DEBIAN_FRONTEND=noninteractive
+
+RUN apt-get update -yqq && \
+ apt-get install -yqq \
+ autoconf \
+ autopoint \
+ curl \
+ bash \
+ coreutils \
+ git \
+ libcurl4-gnutls-dev \
+ libgcrypt-dev \
+ libidn11-dev \
+ libjansson-dev \
+ libmicrohttpd-dev \
+ libpq-dev \
+ libqrencode-dev \
+ libsodium-dev \
+ libtool \
+ libunistring-dev \
+ make \
+ pkg-config \
+ python3-pip \
+ python3-sphinx \
+ python3-sphinx-rtd-theme \
+ recutils \
+ texinfo \
+ zlib1g-dev \
+ # For mustach testing (optional) \
+ libjson-c-dev \
+ # Debian packaging tools \
+ po-debconf \
+ build-essential \
+ debhelper-compat \
+ devscripts \
+ git-buildpackage \
+ # Documentation dependencies \
+ doxygen \
+ graphviz \
+ pandoc \
+ # Test suite dependencies \
+ jq \
+ postgresql \
+ sudo \
+ wget
+
+# Install Taler (and friends) packages
+RUN curl -sS https://deb.taler.net/apt-nightly/taler-bookworm-ci.sources \
+ | tee /etc/apt/sources.list.d/taler-bookworm-ci.sources
+
+RUN echo '\
+Package: * \n\
+Pin: origin "deb.taler.net" \n\
+Pin-Priority: 999' > /etc/apt/preferences.d/taler
+
+RUN cat /etc/apt/preferences.d/taler && \
+ apt-get update -y && \
+ apt-get install -y \
+ libgnunet-dev \
+ libgnunet \
+ gnunet \
+&& rm -rf /var/lib/apt/lists/*
+
+WORKDIR /workdir
+
+CMD ["bash", "/workdir/ci/ci.sh"]
diff --git a/contrib/ci/jobs/110-build-debian-trixie-amd64-generated/build.sh b/contrib/ci/jobs/110-build-debian-trixie-amd64-generated/build.sh
new file mode 100755
index 000000000..d3fcfab85
--- /dev/null
+++ b/contrib/ci/jobs/110-build-debian-trixie-amd64-generated/build.sh
@@ -0,0 +1,14 @@
+#!/bin/bash
+set -exuo pipefail
+
+apt-get update
+apt-get upgrade -yqq
+
+./bootstrap
+./configure CFLAGS="-ggdb -O0" \
+ --enable-logging=verbose \
+ --disable-doc
+
+nump=$(grep processor /proc/cpuinfo | wc -l)
+make -j$(( $nump / 2 ))
+make
diff --git a/contrib/ci/jobs/110-build-debian-trixie-amd64-generated/job.sh b/contrib/ci/jobs/110-build-debian-trixie-amd64-generated/job.sh
new file mode 100755
index 000000000..8d79902c5
--- /dev/null
+++ b/contrib/ci/jobs/110-build-debian-trixie-amd64-generated/job.sh
@@ -0,0 +1,6 @@
+#!/bin/bash
+set -exuo pipefail
+
+job_dir=$(dirname "${BASH_SOURCE[0]}")
+
+"${job_dir}"/build.sh
diff --git a/contrib/ci/jobs/111-deb-package-debian-trixie-amd64-generated/Containerfile b/contrib/ci/jobs/111-deb-package-debian-trixie-amd64-generated/Containerfile
new file mode 100644
index 000000000..6e2c93980
--- /dev/null
+++ b/contrib/ci/jobs/111-deb-package-debian-trixie-amd64-generated/Containerfile
@@ -0,0 +1,68 @@
+FROM docker.io/debian
+
+ENV DEBIAN_FRONTEND=noninteractive
+
+RUN apt-get update -yqq && \
+ apt-get install -yqq \
+ autoconf \
+ autopoint \
+ curl \
+ bash \
+ coreutils \
+ git \
+ libcurl4-gnutls-dev \
+ libgcrypt-dev \
+ libidn11-dev \
+ libjansson-dev \
+ libmicrohttpd-dev \
+ libpq-dev \
+ libqrencode-dev \
+ libsodium-dev \
+ libtool \
+ libunistring-dev \
+ make \
+ pkg-config \
+ python3-pip \
+ python3-sphinx \
+ python3-sphinx-rtd-theme \
+ recutils \
+ texinfo \
+ zlib1g-dev \
+ # For mustach testing (optional) \
+ libjson-c-dev \
+ # Debian packaging tools \
+ po-debconf \
+ build-essential \
+ debhelper-compat \
+ devscripts \
+ git-buildpackage \
+ # Documentation dependencies \
+ doxygen \
+ graphviz \
+ pandoc \
+ # Test suite dependencies \
+ jq \
+ postgresql \
+ sudo \
+ wget
+
+# Install Taler (and friends) packages
+RUN curl -sS https://deb.taler.net/apt-nightly/taler-bookworm-ci.sources \
+ | tee /etc/apt/sources.list.d/taler-bookworm-ci.sources
+
+RUN echo '\
+Package: * \n\
+Pin: origin "deb.taler.net" \n\
+Pin-Priority: 999' > /etc/apt/preferences.d/taler
+
+RUN cat /etc/apt/preferences.d/taler && \
+ apt-get update -y && \
+ apt-get install -y \
+ libgnunet-dev \
+ libgnunet \
+ gnunet \
+&& rm -rf /var/lib/apt/lists/*
+
+WORKDIR /workdir
+
+CMD ["bash", "/workdir/ci/ci.sh"]
diff --git a/contrib/ci/jobs/111-deb-package-debian-trixie-amd64-generated/install-fix.patch b/contrib/ci/jobs/111-deb-package-debian-trixie-amd64-generated/install-fix.patch
new file mode 100644
index 000000000..8334c5a7a
--- /dev/null
+++ b/contrib/ci/jobs/111-deb-package-debian-trixie-amd64-generated/install-fix.patch
@@ -0,0 +1,13 @@
+diff --git a/debian/taler-exchange.install b/debian/taler-exchange.install
+index 631c270b..072c6231 100644
+--- a/debian/taler-exchange.install
++++ b/debian/taler-exchange.install
+@@ -36,6 +36,6 @@ usr/share/taler/exchange/templates/*.must
+ debian/etc-taler-exchange/* etc/
+
+ # Terms of service / privacy policy templates
+-usr/share/taler/exchange/*.rst
++#usr/share/taler/exchange/terms/*.rst
+ # Translations of ToS/PP
+-usr/share/taler/exchange/locale/*/LC_MESSAGES/*.po
++#usr/share/taler/exchange/terms/locale/*/LC_MESSAGES/*.po
diff --git a/contrib/ci/jobs/111-deb-package-debian-trixie-amd64-generated/job.sh b/contrib/ci/jobs/111-deb-package-debian-trixie-amd64-generated/job.sh
new file mode 100755
index 000000000..922f8bf63
--- /dev/null
+++ b/contrib/ci/jobs/111-deb-package-debian-trixie-amd64-generated/job.sh
@@ -0,0 +1,23 @@
+#!/bin/bash
+set -exuo pipefail
+# This file is in the public domain.
+# Helper script to build the latest DEB packages in the container.
+
+
+unset LD_LIBRARY_PATH
+
+# Install build-time dependencies.
+# Update apt cache first
+apt-get update
+apt-get upgrade -y
+mk-build-deps --install --tool='apt-get -o Debug::pkgProblemResolver=yes --no-install-recommends --yes' debian/control
+
+export VERSION="$(./contrib/ci/jobs/4-deb-package/version.sh)"
+echo "Building package version ${VERSION}"
+EMAIL=none gbp dch --dch-opt=-b --ignore-branch --debian-tag="%(version)s" --git-author --new-version="${VERSION}"
+./bootstrap
+dpkg-buildpackage -rfakeroot -b -uc -us
+
+ls -alh ../*.deb
+mkdir -p /artifacts/exchange/${CI_COMMIT_REF} # Variable comes from CI environment
+mv ../*.deb /artifacts/exchange/${CI_COMMIT_REF}/
diff --git a/contrib/ci/jobs/111-deb-package-debian-trixie-amd64-generated/version.sh b/contrib/ci/jobs/111-deb-package-debian-trixie-amd64-generated/version.sh
new file mode 100755
index 000000000..52031b23a
--- /dev/null
+++ b/contrib/ci/jobs/111-deb-package-debian-trixie-amd64-generated/version.sh
@@ -0,0 +1,17 @@
+#!/bin/sh
+set -ex
+
+BRANCH=$(git name-rev --name-only HEAD)
+if [ -z "${BRANCH}" ]; then
+ exit 1
+else
+ # "Unshallow" our checkout, but only our current branch, and exclude the submodules.
+ git fetch --no-recurse-submodules --tags --depth=1000 origin "${BRANCH}"
+ RECENT_VERSION_TAG=$(git describe --tags --match 'v*.*.*' --exclude '*-dev*' --always --abbrev=0 HEAD || exit 1)
+ commits="$(git rev-list ${RECENT_VERSION_TAG}..HEAD --count)"
+ if [ "${commits}" = "0" ]; then
+ git describe --tag HEAD | sed -r 's/^v//' || exit 1
+ else
+ echo $(echo ${RECENT_VERSION_TAG} | sed -r 's/^v//')-${commits}-$(git rev-parse --short=8 HEAD)
+ fi
+fi
diff --git a/contrib/ci/jobs/112-deploy-package-debian-trixie-amd64-generated/config.ini b/contrib/ci/jobs/112-deploy-package-debian-trixie-amd64-generated/config.ini
new file mode 100644
index 000000000..8d6409a6e
--- /dev/null
+++ b/contrib/ci/jobs/112-deploy-package-debian-trixie-amd64-generated/config.ini
@@ -0,0 +1,5 @@
+[build]
+HALT_ON_FAILURE = True
+WARN_ON_FAILURE = True
+CONTAINER_BUILD = False
+CONTAINER_NAME = nixery.dev/shell/rsync
diff --git a/contrib/ci/jobs/112-deploy-package-debian-trixie-amd64-generated/job.sh b/contrib/ci/jobs/112-deploy-package-debian-trixie-amd64-generated/job.sh
new file mode 100755
index 000000000..d39cf9987
--- /dev/null
+++ b/contrib/ci/jobs/112-deploy-package-debian-trixie-amd64-generated/job.sh
@@ -0,0 +1,14 @@
+#!/bin/bash
+set -exuo pipefail
+
+ARTIFACT_PATH="/artifacts/exchange/${CI_COMMIT_REF}/*.deb"
+
+RSYNC_HOST="taler.host.internal"
+RSYNC_PORT=424242
+RSYNC_PATH="incoming_packages/bookworm-taler-ci/"
+RSYNC_DEST="rsync://${RSYNC_HOST}/${RSYNC_PATH}"
+
+
+rsync -vP \
+ --port ${RSYNC_PORT} \
+ ${ARTIFACT_PATH} ${RSYNC_DEST}
diff --git a/contrib/ci/jobs/115-build-debian-trixie-arm64-generated/Containerfile b/contrib/ci/jobs/115-build-debian-trixie-arm64-generated/Containerfile
new file mode 100644
index 000000000..6e2c93980
--- /dev/null
+++ b/contrib/ci/jobs/115-build-debian-trixie-arm64-generated/Containerfile
@@ -0,0 +1,68 @@
+FROM docker.io/debian
+
+ENV DEBIAN_FRONTEND=noninteractive
+
+RUN apt-get update -yqq && \
+ apt-get install -yqq \
+ autoconf \
+ autopoint \
+ curl \
+ bash \
+ coreutils \
+ git \
+ libcurl4-gnutls-dev \
+ libgcrypt-dev \
+ libidn11-dev \
+ libjansson-dev \
+ libmicrohttpd-dev \
+ libpq-dev \
+ libqrencode-dev \
+ libsodium-dev \
+ libtool \
+ libunistring-dev \
+ make \
+ pkg-config \
+ python3-pip \
+ python3-sphinx \
+ python3-sphinx-rtd-theme \
+ recutils \
+ texinfo \
+ zlib1g-dev \
+ # For mustach testing (optional) \
+ libjson-c-dev \
+ # Debian packaging tools \
+ po-debconf \
+ build-essential \
+ debhelper-compat \
+ devscripts \
+ git-buildpackage \
+ # Documentation dependencies \
+ doxygen \
+ graphviz \
+ pandoc \
+ # Test suite dependencies \
+ jq \
+ postgresql \
+ sudo \
+ wget
+
+# Install Taler (and friends) packages
+RUN curl -sS https://deb.taler.net/apt-nightly/taler-bookworm-ci.sources \
+ | tee /etc/apt/sources.list.d/taler-bookworm-ci.sources
+
+RUN echo '\
+Package: * \n\
+Pin: origin "deb.taler.net" \n\
+Pin-Priority: 999' > /etc/apt/preferences.d/taler
+
+RUN cat /etc/apt/preferences.d/taler && \
+ apt-get update -y && \
+ apt-get install -y \
+ libgnunet-dev \
+ libgnunet \
+ gnunet \
+&& rm -rf /var/lib/apt/lists/*
+
+WORKDIR /workdir
+
+CMD ["bash", "/workdir/ci/ci.sh"]
diff --git a/contrib/ci/jobs/115-build-debian-trixie-arm64-generated/build.sh b/contrib/ci/jobs/115-build-debian-trixie-arm64-generated/build.sh
new file mode 100755
index 000000000..d3fcfab85
--- /dev/null
+++ b/contrib/ci/jobs/115-build-debian-trixie-arm64-generated/build.sh
@@ -0,0 +1,14 @@
+#!/bin/bash
+set -exuo pipefail
+
+apt-get update
+apt-get upgrade -yqq
+
+./bootstrap
+./configure CFLAGS="-ggdb -O0" \
+ --enable-logging=verbose \
+ --disable-doc
+
+nump=$(grep processor /proc/cpuinfo | wc -l)
+make -j$(( $nump / 2 ))
+make
diff --git a/contrib/ci/jobs/115-build-debian-trixie-arm64-generated/config.ini b/contrib/ci/jobs/115-build-debian-trixie-arm64-generated/config.ini
new file mode 100644
index 000000000..2a99a970e
--- /dev/null
+++ b/contrib/ci/jobs/115-build-debian-trixie-arm64-generated/config.ini
@@ -0,0 +1,7 @@
+[build]
+HALT_ON_FAILURE = True
+WARN_ON_FAILURE = True
+CONTAINER_BUILD = True
+CONTAINER_NAME = exchange:arm64
+CONTAINER_ARCH = arm64
+
diff --git a/contrib/ci/jobs/115-build-debian-trixie-arm64-generated/job.sh b/contrib/ci/jobs/115-build-debian-trixie-arm64-generated/job.sh
new file mode 100755
index 000000000..8d79902c5
--- /dev/null
+++ b/contrib/ci/jobs/115-build-debian-trixie-arm64-generated/job.sh
@@ -0,0 +1,6 @@
+#!/bin/bash
+set -exuo pipefail
+
+job_dir=$(dirname "${BASH_SOURCE[0]}")
+
+"${job_dir}"/build.sh
diff --git a/contrib/ci/jobs/116-deb-package-debian-trixie-arm64-generated/Containerfile b/contrib/ci/jobs/116-deb-package-debian-trixie-arm64-generated/Containerfile
new file mode 100644
index 000000000..6e2c93980
--- /dev/null
+++ b/contrib/ci/jobs/116-deb-package-debian-trixie-arm64-generated/Containerfile
@@ -0,0 +1,68 @@
+FROM docker.io/debian
+
+ENV DEBIAN_FRONTEND=noninteractive
+
+RUN apt-get update -yqq && \
+ apt-get install -yqq \
+ autoconf \
+ autopoint \
+ curl \
+ bash \
+ coreutils \
+ git \
+ libcurl4-gnutls-dev \
+ libgcrypt-dev \
+ libidn11-dev \
+ libjansson-dev \
+ libmicrohttpd-dev \
+ libpq-dev \
+ libqrencode-dev \
+ libsodium-dev \
+ libtool \
+ libunistring-dev \
+ make \
+ pkg-config \
+ python3-pip \
+ python3-sphinx \
+ python3-sphinx-rtd-theme \
+ recutils \
+ texinfo \
+ zlib1g-dev \
+ # For mustach testing (optional) \
+ libjson-c-dev \
+ # Debian packaging tools \
+ po-debconf \
+ build-essential \
+ debhelper-compat \
+ devscripts \
+ git-buildpackage \
+ # Documentation dependencies \
+ doxygen \
+ graphviz \
+ pandoc \
+ # Test suite dependencies \
+ jq \
+ postgresql \
+ sudo \
+ wget
+
+# Install Taler (and friends) packages
+RUN curl -sS https://deb.taler.net/apt-nightly/taler-bookworm-ci.sources \
+ | tee /etc/apt/sources.list.d/taler-bookworm-ci.sources
+
+RUN echo '\
+Package: * \n\
+Pin: origin "deb.taler.net" \n\
+Pin-Priority: 999' > /etc/apt/preferences.d/taler
+
+RUN cat /etc/apt/preferences.d/taler && \
+ apt-get update -y && \
+ apt-get install -y \
+ libgnunet-dev \
+ libgnunet \
+ gnunet \
+&& rm -rf /var/lib/apt/lists/*
+
+WORKDIR /workdir
+
+CMD ["bash", "/workdir/ci/ci.sh"]
diff --git a/contrib/ci/jobs/116-deb-package-debian-trixie-arm64-generated/config.ini b/contrib/ci/jobs/116-deb-package-debian-trixie-arm64-generated/config.ini
new file mode 100644
index 000000000..2a99a970e
--- /dev/null
+++ b/contrib/ci/jobs/116-deb-package-debian-trixie-arm64-generated/config.ini
@@ -0,0 +1,7 @@
+[build]
+HALT_ON_FAILURE = True
+WARN_ON_FAILURE = True
+CONTAINER_BUILD = True
+CONTAINER_NAME = exchange:arm64
+CONTAINER_ARCH = arm64
+
diff --git a/contrib/ci/jobs/116-deb-package-debian-trixie-arm64-generated/install-fix.patch b/contrib/ci/jobs/116-deb-package-debian-trixie-arm64-generated/install-fix.patch
new file mode 100644
index 000000000..8334c5a7a
--- /dev/null
+++ b/contrib/ci/jobs/116-deb-package-debian-trixie-arm64-generated/install-fix.patch
@@ -0,0 +1,13 @@
+diff --git a/debian/taler-exchange.install b/debian/taler-exchange.install
+index 631c270b..072c6231 100644
+--- a/debian/taler-exchange.install
++++ b/debian/taler-exchange.install
+@@ -36,6 +36,6 @@ usr/share/taler/exchange/templates/*.must
+ debian/etc-taler-exchange/* etc/
+
+ # Terms of service / privacy policy templates
+-usr/share/taler/exchange/*.rst
++#usr/share/taler/exchange/terms/*.rst
+ # Translations of ToS/PP
+-usr/share/taler/exchange/locale/*/LC_MESSAGES/*.po
++#usr/share/taler/exchange/terms/locale/*/LC_MESSAGES/*.po
diff --git a/contrib/ci/jobs/116-deb-package-debian-trixie-arm64-generated/job.sh b/contrib/ci/jobs/116-deb-package-debian-trixie-arm64-generated/job.sh
new file mode 100755
index 000000000..922f8bf63
--- /dev/null
+++ b/contrib/ci/jobs/116-deb-package-debian-trixie-arm64-generated/job.sh
@@ -0,0 +1,23 @@
+#!/bin/bash
+set -exuo pipefail
+# This file is in the public domain.
+# Helper script to build the latest DEB packages in the container.
+
+
+unset LD_LIBRARY_PATH
+
+# Install build-time dependencies.
+# Update apt cache first
+apt-get update
+apt-get upgrade -y
+mk-build-deps --install --tool='apt-get -o Debug::pkgProblemResolver=yes --no-install-recommends --yes' debian/control
+
+export VERSION="$(./contrib/ci/jobs/4-deb-package/version.sh)"
+echo "Building package version ${VERSION}"
+EMAIL=none gbp dch --dch-opt=-b --ignore-branch --debian-tag="%(version)s" --git-author --new-version="${VERSION}"
+./bootstrap
+dpkg-buildpackage -rfakeroot -b -uc -us
+
+ls -alh ../*.deb
+mkdir -p /artifacts/exchange/${CI_COMMIT_REF} # Variable comes from CI environment
+mv ../*.deb /artifacts/exchange/${CI_COMMIT_REF}/
diff --git a/contrib/ci/jobs/116-deb-package-debian-trixie-arm64-generated/version.sh b/contrib/ci/jobs/116-deb-package-debian-trixie-arm64-generated/version.sh
new file mode 100755
index 000000000..52031b23a
--- /dev/null
+++ b/contrib/ci/jobs/116-deb-package-debian-trixie-arm64-generated/version.sh
@@ -0,0 +1,17 @@
+#!/bin/sh
+set -ex
+
+BRANCH=$(git name-rev --name-only HEAD)
+if [ -z "${BRANCH}" ]; then
+ exit 1
+else
+ # "Unshallow" our checkout, but only our current branch, and exclude the submodules.
+ git fetch --no-recurse-submodules --tags --depth=1000 origin "${BRANCH}"
+ RECENT_VERSION_TAG=$(git describe --tags --match 'v*.*.*' --exclude '*-dev*' --always --abbrev=0 HEAD || exit 1)
+ commits="$(git rev-list ${RECENT_VERSION_TAG}..HEAD --count)"
+ if [ "${commits}" = "0" ]; then
+ git describe --tag HEAD | sed -r 's/^v//' || exit 1
+ else
+ echo $(echo ${RECENT_VERSION_TAG} | sed -r 's/^v//')-${commits}-$(git rev-parse --short=8 HEAD)
+ fi
+fi
diff --git a/contrib/ci/jobs/117-deploy-package-debian-trixie-arm64-generated/config.ini b/contrib/ci/jobs/117-deploy-package-debian-trixie-arm64-generated/config.ini
new file mode 100644
index 000000000..8d6409a6e
--- /dev/null
+++ b/contrib/ci/jobs/117-deploy-package-debian-trixie-arm64-generated/config.ini
@@ -0,0 +1,5 @@
+[build]
+HALT_ON_FAILURE = True
+WARN_ON_FAILURE = True
+CONTAINER_BUILD = False
+CONTAINER_NAME = nixery.dev/shell/rsync
diff --git a/contrib/ci/jobs/117-deploy-package-debian-trixie-arm64-generated/job.sh b/contrib/ci/jobs/117-deploy-package-debian-trixie-arm64-generated/job.sh
new file mode 100755
index 000000000..d39cf9987
--- /dev/null
+++ b/contrib/ci/jobs/117-deploy-package-debian-trixie-arm64-generated/job.sh
@@ -0,0 +1,14 @@
+#!/bin/bash
+set -exuo pipefail
+
+ARTIFACT_PATH="/artifacts/exchange/${CI_COMMIT_REF}/*.deb"
+
+RSYNC_HOST="taler.host.internal"
+RSYNC_PORT=424242
+RSYNC_PATH="incoming_packages/bookworm-taler-ci/"
+RSYNC_DEST="rsync://${RSYNC_HOST}/${RSYNC_PATH}"
+
+
+rsync -vP \
+ --port ${RSYNC_PORT} \
+ ${ARTIFACT_PATH} ${RSYNC_DEST}
diff --git a/contrib/ci/jobs/120-build-debian-unstable-amd64-generated/Containerfile b/contrib/ci/jobs/120-build-debian-unstable-amd64-generated/Containerfile
new file mode 100644
index 000000000..6e2c93980
--- /dev/null
+++ b/contrib/ci/jobs/120-build-debian-unstable-amd64-generated/Containerfile
@@ -0,0 +1,68 @@
+FROM docker.io/debian
+
+ENV DEBIAN_FRONTEND=noninteractive
+
+RUN apt-get update -yqq && \
+ apt-get install -yqq \
+ autoconf \
+ autopoint \
+ curl \
+ bash \
+ coreutils \
+ git \
+ libcurl4-gnutls-dev \
+ libgcrypt-dev \
+ libidn11-dev \
+ libjansson-dev \
+ libmicrohttpd-dev \
+ libpq-dev \
+ libqrencode-dev \
+ libsodium-dev \
+ libtool \
+ libunistring-dev \
+ make \
+ pkg-config \
+ python3-pip \
+ python3-sphinx \
+ python3-sphinx-rtd-theme \
+ recutils \
+ texinfo \
+ zlib1g-dev \
+ # For mustach testing (optional) \
+ libjson-c-dev \
+ # Debian packaging tools \
+ po-debconf \
+ build-essential \
+ debhelper-compat \
+ devscripts \
+ git-buildpackage \
+ # Documentation dependencies \
+ doxygen \
+ graphviz \
+ pandoc \
+ # Test suite dependencies \
+ jq \
+ postgresql \
+ sudo \
+ wget
+
+# Install Taler (and friends) packages
+RUN curl -sS https://deb.taler.net/apt-nightly/taler-bookworm-ci.sources \
+ | tee /etc/apt/sources.list.d/taler-bookworm-ci.sources
+
+RUN echo '\
+Package: * \n\
+Pin: origin "deb.taler.net" \n\
+Pin-Priority: 999' > /etc/apt/preferences.d/taler
+
+RUN cat /etc/apt/preferences.d/taler && \
+ apt-get update -y && \
+ apt-get install -y \
+ libgnunet-dev \
+ libgnunet \
+ gnunet \
+&& rm -rf /var/lib/apt/lists/*
+
+WORKDIR /workdir
+
+CMD ["bash", "/workdir/ci/ci.sh"]
diff --git a/contrib/ci/jobs/120-build-debian-unstable-amd64-generated/build.sh b/contrib/ci/jobs/120-build-debian-unstable-amd64-generated/build.sh
new file mode 100755
index 000000000..d3fcfab85
--- /dev/null
+++ b/contrib/ci/jobs/120-build-debian-unstable-amd64-generated/build.sh
@@ -0,0 +1,14 @@
+#!/bin/bash
+set -exuo pipefail
+
+apt-get update
+apt-get upgrade -yqq
+
+./bootstrap
+./configure CFLAGS="-ggdb -O0" \
+ --enable-logging=verbose \
+ --disable-doc
+
+nump=$(grep processor /proc/cpuinfo | wc -l)
+make -j$(( $nump / 2 ))
+make
diff --git a/contrib/ci/jobs/120-build-debian-unstable-amd64-generated/job.sh b/contrib/ci/jobs/120-build-debian-unstable-amd64-generated/job.sh
new file mode 100755
index 000000000..8d79902c5
--- /dev/null
+++ b/contrib/ci/jobs/120-build-debian-unstable-amd64-generated/job.sh
@@ -0,0 +1,6 @@
+#!/bin/bash
+set -exuo pipefail
+
+job_dir=$(dirname "${BASH_SOURCE[0]}")
+
+"${job_dir}"/build.sh
diff --git a/contrib/ci/jobs/121-deb-package-debian-unstable-amd64-generated/Containerfile b/contrib/ci/jobs/121-deb-package-debian-unstable-amd64-generated/Containerfile
new file mode 100644
index 000000000..6e2c93980
--- /dev/null
+++ b/contrib/ci/jobs/121-deb-package-debian-unstable-amd64-generated/Containerfile
@@ -0,0 +1,68 @@
+FROM docker.io/debian
+
+ENV DEBIAN_FRONTEND=noninteractive
+
+RUN apt-get update -yqq && \
+ apt-get install -yqq \
+ autoconf \
+ autopoint \
+ curl \
+ bash \
+ coreutils \
+ git \
+ libcurl4-gnutls-dev \
+ libgcrypt-dev \
+ libidn11-dev \
+ libjansson-dev \
+ libmicrohttpd-dev \
+ libpq-dev \
+ libqrencode-dev \
+ libsodium-dev \
+ libtool \
+ libunistring-dev \
+ make \
+ pkg-config \
+ python3-pip \
+ python3-sphinx \
+ python3-sphinx-rtd-theme \
+ recutils \
+ texinfo \
+ zlib1g-dev \
+ # For mustach testing (optional) \
+ libjson-c-dev \
+ # Debian packaging tools \
+ po-debconf \
+ build-essential \
+ debhelper-compat \
+ devscripts \
+ git-buildpackage \
+ # Documentation dependencies \
+ doxygen \
+ graphviz \
+ pandoc \
+ # Test suite dependencies \
+ jq \
+ postgresql \
+ sudo \
+ wget
+
+# Install Taler (and friends) packages
+RUN curl -sS https://deb.taler.net/apt-nightly/taler-bookworm-ci.sources \
+ | tee /etc/apt/sources.list.d/taler-bookworm-ci.sources
+
+RUN echo '\
+Package: * \n\
+Pin: origin "deb.taler.net" \n\
+Pin-Priority: 999' > /etc/apt/preferences.d/taler
+
+RUN cat /etc/apt/preferences.d/taler && \
+ apt-get update -y && \
+ apt-get install -y \
+ libgnunet-dev \
+ libgnunet \
+ gnunet \
+&& rm -rf /var/lib/apt/lists/*
+
+WORKDIR /workdir
+
+CMD ["bash", "/workdir/ci/ci.sh"]
diff --git a/contrib/ci/jobs/121-deb-package-debian-unstable-amd64-generated/install-fix.patch b/contrib/ci/jobs/121-deb-package-debian-unstable-amd64-generated/install-fix.patch
new file mode 100644
index 000000000..8334c5a7a
--- /dev/null
+++ b/contrib/ci/jobs/121-deb-package-debian-unstable-amd64-generated/install-fix.patch
@@ -0,0 +1,13 @@
+diff --git a/debian/taler-exchange.install b/debian/taler-exchange.install
+index 631c270b..072c6231 100644
+--- a/debian/taler-exchange.install
++++ b/debian/taler-exchange.install
+@@ -36,6 +36,6 @@ usr/share/taler/exchange/templates/*.must
+ debian/etc-taler-exchange/* etc/
+
+ # Terms of service / privacy policy templates
+-usr/share/taler/exchange/*.rst
++#usr/share/taler/exchange/terms/*.rst
+ # Translations of ToS/PP
+-usr/share/taler/exchange/locale/*/LC_MESSAGES/*.po
++#usr/share/taler/exchange/terms/locale/*/LC_MESSAGES/*.po
diff --git a/contrib/ci/jobs/121-deb-package-debian-unstable-amd64-generated/job.sh b/contrib/ci/jobs/121-deb-package-debian-unstable-amd64-generated/job.sh
new file mode 100755
index 000000000..922f8bf63
--- /dev/null
+++ b/contrib/ci/jobs/121-deb-package-debian-unstable-amd64-generated/job.sh
@@ -0,0 +1,23 @@
+#!/bin/bash
+set -exuo pipefail
+# This file is in the public domain.
+# Helper script to build the latest DEB packages in the container.
+
+
+unset LD_LIBRARY_PATH
+
+# Install build-time dependencies.
+# Update apt cache first
+apt-get update
+apt-get upgrade -y
+mk-build-deps --install --tool='apt-get -o Debug::pkgProblemResolver=yes --no-install-recommends --yes' debian/control
+
+export VERSION="$(./contrib/ci/jobs/4-deb-package/version.sh)"
+echo "Building package version ${VERSION}"
+EMAIL=none gbp dch --dch-opt=-b --ignore-branch --debian-tag="%(version)s" --git-author --new-version="${VERSION}"
+./bootstrap
+dpkg-buildpackage -rfakeroot -b -uc -us
+
+ls -alh ../*.deb
+mkdir -p /artifacts/exchange/${CI_COMMIT_REF} # Variable comes from CI environment
+mv ../*.deb /artifacts/exchange/${CI_COMMIT_REF}/
diff --git a/contrib/ci/jobs/121-deb-package-debian-unstable-amd64-generated/version.sh b/contrib/ci/jobs/121-deb-package-debian-unstable-amd64-generated/version.sh
new file mode 100755
index 000000000..52031b23a
--- /dev/null
+++ b/contrib/ci/jobs/121-deb-package-debian-unstable-amd64-generated/version.sh
@@ -0,0 +1,17 @@
+#!/bin/sh
+set -ex
+
+BRANCH=$(git name-rev --name-only HEAD)
+if [ -z "${BRANCH}" ]; then
+ exit 1
+else
+ # "Unshallow" our checkout, but only our current branch, and exclude the submodules.
+ git fetch --no-recurse-submodules --tags --depth=1000 origin "${BRANCH}"
+ RECENT_VERSION_TAG=$(git describe --tags --match 'v*.*.*' --exclude '*-dev*' --always --abbrev=0 HEAD || exit 1)
+ commits="$(git rev-list ${RECENT_VERSION_TAG}..HEAD --count)"
+ if [ "${commits}" = "0" ]; then
+ git describe --tag HEAD | sed -r 's/^v//' || exit 1
+ else
+ echo $(echo ${RECENT_VERSION_TAG} | sed -r 's/^v//')-${commits}-$(git rev-parse --short=8 HEAD)
+ fi
+fi
diff --git a/contrib/ci/jobs/122-deploy-package-debian-unstable-amd64-generated/config.ini b/contrib/ci/jobs/122-deploy-package-debian-unstable-amd64-generated/config.ini
new file mode 100644
index 000000000..8d6409a6e
--- /dev/null
+++ b/contrib/ci/jobs/122-deploy-package-debian-unstable-amd64-generated/config.ini
@@ -0,0 +1,5 @@
+[build]
+HALT_ON_FAILURE = True
+WARN_ON_FAILURE = True
+CONTAINER_BUILD = False
+CONTAINER_NAME = nixery.dev/shell/rsync
diff --git a/contrib/ci/jobs/122-deploy-package-debian-unstable-amd64-generated/job.sh b/contrib/ci/jobs/122-deploy-package-debian-unstable-amd64-generated/job.sh
new file mode 100755
index 000000000..d39cf9987
--- /dev/null
+++ b/contrib/ci/jobs/122-deploy-package-debian-unstable-amd64-generated/job.sh
@@ -0,0 +1,14 @@
+#!/bin/bash
+set -exuo pipefail
+
+ARTIFACT_PATH="/artifacts/exchange/${CI_COMMIT_REF}/*.deb"
+
+RSYNC_HOST="taler.host.internal"
+RSYNC_PORT=424242
+RSYNC_PATH="incoming_packages/bookworm-taler-ci/"
+RSYNC_DEST="rsync://${RSYNC_HOST}/${RSYNC_PATH}"
+
+
+rsync -vP \
+ --port ${RSYNC_PORT} \
+ ${ARTIFACT_PATH} ${RSYNC_DEST}
diff --git a/contrib/ci/jobs/125-build-debian-unstable-arm64-generated/Containerfile b/contrib/ci/jobs/125-build-debian-unstable-arm64-generated/Containerfile
new file mode 100644
index 000000000..6e2c93980
--- /dev/null
+++ b/contrib/ci/jobs/125-build-debian-unstable-arm64-generated/Containerfile
@@ -0,0 +1,68 @@
+FROM docker.io/debian
+
+ENV DEBIAN_FRONTEND=noninteractive
+
+RUN apt-get update -yqq && \
+ apt-get install -yqq \
+ autoconf \
+ autopoint \
+ curl \
+ bash \
+ coreutils \
+ git \
+ libcurl4-gnutls-dev \
+ libgcrypt-dev \
+ libidn11-dev \
+ libjansson-dev \
+ libmicrohttpd-dev \
+ libpq-dev \
+ libqrencode-dev \
+ libsodium-dev \
+ libtool \
+ libunistring-dev \
+ make \
+ pkg-config \
+ python3-pip \
+ python3-sphinx \
+ python3-sphinx-rtd-theme \
+ recutils \
+ texinfo \
+ zlib1g-dev \
+ # For mustach testing (optional) \
+ libjson-c-dev \
+ # Debian packaging tools \
+ po-debconf \
+ build-essential \
+ debhelper-compat \
+ devscripts \
+ git-buildpackage \
+ # Documentation dependencies \
+ doxygen \
+ graphviz \
+ pandoc \
+ # Test suite dependencies \
+ jq \
+ postgresql \
+ sudo \
+ wget
+
+# Install Taler (and friends) packages
+RUN curl -sS https://deb.taler.net/apt-nightly/taler-bookworm-ci.sources \
+ | tee /etc/apt/sources.list.d/taler-bookworm-ci.sources
+
+RUN echo '\
+Package: * \n\
+Pin: origin "deb.taler.net" \n\
+Pin-Priority: 999' > /etc/apt/preferences.d/taler
+
+RUN cat /etc/apt/preferences.d/taler && \
+ apt-get update -y && \
+ apt-get install -y \
+ libgnunet-dev \
+ libgnunet \
+ gnunet \
+&& rm -rf /var/lib/apt/lists/*
+
+WORKDIR /workdir
+
+CMD ["bash", "/workdir/ci/ci.sh"]
diff --git a/contrib/ci/jobs/125-build-debian-unstable-arm64-generated/build.sh b/contrib/ci/jobs/125-build-debian-unstable-arm64-generated/build.sh
new file mode 100755
index 000000000..d3fcfab85
--- /dev/null
+++ b/contrib/ci/jobs/125-build-debian-unstable-arm64-generated/build.sh
@@ -0,0 +1,14 @@
+#!/bin/bash
+set -exuo pipefail
+
+apt-get update
+apt-get upgrade -yqq
+
+./bootstrap
+./configure CFLAGS="-ggdb -O0" \
+ --enable-logging=verbose \
+ --disable-doc
+
+nump=$(grep processor /proc/cpuinfo | wc -l)
+make -j$(( $nump / 2 ))
+make
diff --git a/contrib/ci/jobs/125-build-debian-unstable-arm64-generated/config.ini b/contrib/ci/jobs/125-build-debian-unstable-arm64-generated/config.ini
new file mode 100644
index 000000000..2a99a970e
--- /dev/null
+++ b/contrib/ci/jobs/125-build-debian-unstable-arm64-generated/config.ini
@@ -0,0 +1,7 @@
+[build]
+HALT_ON_FAILURE = True
+WARN_ON_FAILURE = True
+CONTAINER_BUILD = True
+CONTAINER_NAME = exchange:arm64
+CONTAINER_ARCH = arm64
+
diff --git a/contrib/ci/jobs/125-build-debian-unstable-arm64-generated/job.sh b/contrib/ci/jobs/125-build-debian-unstable-arm64-generated/job.sh
new file mode 100755
index 000000000..8d79902c5
--- /dev/null
+++ b/contrib/ci/jobs/125-build-debian-unstable-arm64-generated/job.sh
@@ -0,0 +1,6 @@
+#!/bin/bash
+set -exuo pipefail
+
+job_dir=$(dirname "${BASH_SOURCE[0]}")
+
+"${job_dir}"/build.sh
diff --git a/contrib/ci/jobs/126-deb-package-debian-unstable-arm64-generated/Containerfile b/contrib/ci/jobs/126-deb-package-debian-unstable-arm64-generated/Containerfile
new file mode 100644
index 000000000..6e2c93980
--- /dev/null
+++ b/contrib/ci/jobs/126-deb-package-debian-unstable-arm64-generated/Containerfile
@@ -0,0 +1,68 @@
+FROM docker.io/debian
+
+ENV DEBIAN_FRONTEND=noninteractive
+
+RUN apt-get update -yqq && \
+ apt-get install -yqq \
+ autoconf \
+ autopoint \
+ curl \
+ bash \
+ coreutils \
+ git \
+ libcurl4-gnutls-dev \
+ libgcrypt-dev \
+ libidn11-dev \
+ libjansson-dev \
+ libmicrohttpd-dev \
+ libpq-dev \
+ libqrencode-dev \
+ libsodium-dev \
+ libtool \
+ libunistring-dev \
+ make \
+ pkg-config \
+ python3-pip \
+ python3-sphinx \
+ python3-sphinx-rtd-theme \
+ recutils \
+ texinfo \
+ zlib1g-dev \
+ # For mustach testing (optional) \
+ libjson-c-dev \
+ # Debian packaging tools \
+ po-debconf \
+ build-essential \
+ debhelper-compat \
+ devscripts \
+ git-buildpackage \
+ # Documentation dependencies \
+ doxygen \
+ graphviz \
+ pandoc \
+ # Test suite dependencies \
+ jq \
+ postgresql \
+ sudo \
+ wget
+
+# Install Taler (and friends) packages
+RUN curl -sS https://deb.taler.net/apt-nightly/taler-bookworm-ci.sources \
+ | tee /etc/apt/sources.list.d/taler-bookworm-ci.sources
+
+RUN echo '\
+Package: * \n\
+Pin: origin "deb.taler.net" \n\
+Pin-Priority: 999' > /etc/apt/preferences.d/taler
+
+RUN cat /etc/apt/preferences.d/taler && \
+ apt-get update -y && \
+ apt-get install -y \
+ libgnunet-dev \
+ libgnunet \
+ gnunet \
+&& rm -rf /var/lib/apt/lists/*
+
+WORKDIR /workdir
+
+CMD ["bash", "/workdir/ci/ci.sh"]
diff --git a/contrib/ci/jobs/126-deb-package-debian-unstable-arm64-generated/config.ini b/contrib/ci/jobs/126-deb-package-debian-unstable-arm64-generated/config.ini
new file mode 100644
index 000000000..2a99a970e
--- /dev/null
+++ b/contrib/ci/jobs/126-deb-package-debian-unstable-arm64-generated/config.ini
@@ -0,0 +1,7 @@
+[build]
+HALT_ON_FAILURE = True
+WARN_ON_FAILURE = True
+CONTAINER_BUILD = True
+CONTAINER_NAME = exchange:arm64
+CONTAINER_ARCH = arm64
+
diff --git a/contrib/ci/jobs/126-deb-package-debian-unstable-arm64-generated/install-fix.patch b/contrib/ci/jobs/126-deb-package-debian-unstable-arm64-generated/install-fix.patch
new file mode 100644
index 000000000..8334c5a7a
--- /dev/null
+++ b/contrib/ci/jobs/126-deb-package-debian-unstable-arm64-generated/install-fix.patch
@@ -0,0 +1,13 @@
+diff --git a/debian/taler-exchange.install b/debian/taler-exchange.install
+index 631c270b..072c6231 100644
+--- a/debian/taler-exchange.install
++++ b/debian/taler-exchange.install
+@@ -36,6 +36,6 @@ usr/share/taler/exchange/templates/*.must
+ debian/etc-taler-exchange/* etc/
+
+ # Terms of service / privacy policy templates
+-usr/share/taler/exchange/*.rst
++#usr/share/taler/exchange/terms/*.rst
+ # Translations of ToS/PP
+-usr/share/taler/exchange/locale/*/LC_MESSAGES/*.po
++#usr/share/taler/exchange/terms/locale/*/LC_MESSAGES/*.po
diff --git a/contrib/ci/jobs/126-deb-package-debian-unstable-arm64-generated/job.sh b/contrib/ci/jobs/126-deb-package-debian-unstable-arm64-generated/job.sh
new file mode 100755
index 000000000..922f8bf63
--- /dev/null
+++ b/contrib/ci/jobs/126-deb-package-debian-unstable-arm64-generated/job.sh
@@ -0,0 +1,23 @@
+#!/bin/bash
+set -exuo pipefail
+# This file is in the public domain.
+# Helper script to build the latest DEB packages in the container.
+
+
+unset LD_LIBRARY_PATH
+
+# Install build-time dependencies.
+# Update apt cache first
+apt-get update
+apt-get upgrade -y
+mk-build-deps --install --tool='apt-get -o Debug::pkgProblemResolver=yes --no-install-recommends --yes' debian/control
+
+export VERSION="$(./contrib/ci/jobs/4-deb-package/version.sh)"
+echo "Building package version ${VERSION}"
+EMAIL=none gbp dch --dch-opt=-b --ignore-branch --debian-tag="%(version)s" --git-author --new-version="${VERSION}"
+./bootstrap
+dpkg-buildpackage -rfakeroot -b -uc -us
+
+ls -alh ../*.deb
+mkdir -p /artifacts/exchange/${CI_COMMIT_REF} # Variable comes from CI environment
+mv ../*.deb /artifacts/exchange/${CI_COMMIT_REF}/
diff --git a/contrib/ci/jobs/126-deb-package-debian-unstable-arm64-generated/version.sh b/contrib/ci/jobs/126-deb-package-debian-unstable-arm64-generated/version.sh
new file mode 100755
index 000000000..52031b23a
--- /dev/null
+++ b/contrib/ci/jobs/126-deb-package-debian-unstable-arm64-generated/version.sh
@@ -0,0 +1,17 @@
+#!/bin/sh
+set -ex
+
+BRANCH=$(git name-rev --name-only HEAD)
+if [ -z "${BRANCH}" ]; then
+ exit 1
+else
+ # "Unshallow" our checkout, but only our current branch, and exclude the submodules.
+ git fetch --no-recurse-submodules --tags --depth=1000 origin "${BRANCH}"
+ RECENT_VERSION_TAG=$(git describe --tags --match 'v*.*.*' --exclude '*-dev*' --always --abbrev=0 HEAD || exit 1)
+ commits="$(git rev-list ${RECENT_VERSION_TAG}..HEAD --count)"
+ if [ "${commits}" = "0" ]; then
+ git describe --tag HEAD | sed -r 's/^v//' || exit 1
+ else
+ echo $(echo ${RECENT_VERSION_TAG} | sed -r 's/^v//')-${commits}-$(git rev-parse --short=8 HEAD)
+ fi
+fi
diff --git a/contrib/ci/jobs/127-deploy-package-debian-unstable-arm64-generated/config.ini b/contrib/ci/jobs/127-deploy-package-debian-unstable-arm64-generated/config.ini
new file mode 100644
index 000000000..8d6409a6e
--- /dev/null
+++ b/contrib/ci/jobs/127-deploy-package-debian-unstable-arm64-generated/config.ini
@@ -0,0 +1,5 @@
+[build]
+HALT_ON_FAILURE = True
+WARN_ON_FAILURE = True
+CONTAINER_BUILD = False
+CONTAINER_NAME = nixery.dev/shell/rsync
diff --git a/contrib/ci/jobs/127-deploy-package-debian-unstable-arm64-generated/job.sh b/contrib/ci/jobs/127-deploy-package-debian-unstable-arm64-generated/job.sh
new file mode 100755
index 000000000..d39cf9987
--- /dev/null
+++ b/contrib/ci/jobs/127-deploy-package-debian-unstable-arm64-generated/job.sh
@@ -0,0 +1,14 @@
+#!/bin/bash
+set -exuo pipefail
+
+ARTIFACT_PATH="/artifacts/exchange/${CI_COMMIT_REF}/*.deb"
+
+RSYNC_HOST="taler.host.internal"
+RSYNC_PORT=424242
+RSYNC_PATH="incoming_packages/bookworm-taler-ci/"
+RSYNC_DEST="rsync://${RSYNC_HOST}/${RSYNC_PATH}"
+
+
+rsync -vP \
+ --port ${RSYNC_PORT} \
+ ${ARTIFACT_PATH} ${RSYNC_DEST}
diff --git a/contrib/ci/jobs/130-build-debian-unstable-riscv64-generated/Containerfile b/contrib/ci/jobs/130-build-debian-unstable-riscv64-generated/Containerfile
new file mode 100644
index 000000000..6e2c93980
--- /dev/null
+++ b/contrib/ci/jobs/130-build-debian-unstable-riscv64-generated/Containerfile
@@ -0,0 +1,68 @@
+FROM docker.io/debian
+
+ENV DEBIAN_FRONTEND=noninteractive
+
+RUN apt-get update -yqq && \
+ apt-get install -yqq \
+ autoconf \
+ autopoint \
+ curl \
+ bash \
+ coreutils \
+ git \
+ libcurl4-gnutls-dev \
+ libgcrypt-dev \
+ libidn11-dev \
+ libjansson-dev \
+ libmicrohttpd-dev \
+ libpq-dev \
+ libqrencode-dev \
+ libsodium-dev \
+ libtool \
+ libunistring-dev \
+ make \
+ pkg-config \
+ python3-pip \
+ python3-sphinx \
+ python3-sphinx-rtd-theme \
+ recutils \
+ texinfo \
+ zlib1g-dev \
+ # For mustach testing (optional) \
+ libjson-c-dev \
+ # Debian packaging tools \
+ po-debconf \
+ build-essential \
+ debhelper-compat \
+ devscripts \
+ git-buildpackage \
+ # Documentation dependencies \
+ doxygen \
+ graphviz \
+ pandoc \
+ # Test suite dependencies \
+ jq \
+ postgresql \
+ sudo \
+ wget
+
+# Install Taler (and friends) packages
+RUN curl -sS https://deb.taler.net/apt-nightly/taler-bookworm-ci.sources \
+ | tee /etc/apt/sources.list.d/taler-bookworm-ci.sources
+
+RUN echo '\
+Package: * \n\
+Pin: origin "deb.taler.net" \n\
+Pin-Priority: 999' > /etc/apt/preferences.d/taler
+
+RUN cat /etc/apt/preferences.d/taler && \
+ apt-get update -y && \
+ apt-get install -y \
+ libgnunet-dev \
+ libgnunet \
+ gnunet \
+&& rm -rf /var/lib/apt/lists/*
+
+WORKDIR /workdir
+
+CMD ["bash", "/workdir/ci/ci.sh"]
diff --git a/contrib/ci/jobs/130-build-debian-unstable-riscv64-generated/build.sh b/contrib/ci/jobs/130-build-debian-unstable-riscv64-generated/build.sh
new file mode 100755
index 000000000..d3fcfab85
--- /dev/null
+++ b/contrib/ci/jobs/130-build-debian-unstable-riscv64-generated/build.sh
@@ -0,0 +1,14 @@
+#!/bin/bash
+set -exuo pipefail
+
+apt-get update
+apt-get upgrade -yqq
+
+./bootstrap
+./configure CFLAGS="-ggdb -O0" \
+ --enable-logging=verbose \
+ --disable-doc
+
+nump=$(grep processor /proc/cpuinfo | wc -l)
+make -j$(( $nump / 2 ))
+make
diff --git a/contrib/ci/jobs/9-build-riscv64/config.ini b/contrib/ci/jobs/130-build-debian-unstable-riscv64-generated/config.ini
index 73914f224..f3afa2db7 100644
--- a/contrib/ci/jobs/9-build-riscv64/config.ini
+++ b/contrib/ci/jobs/130-build-debian-unstable-riscv64-generated/config.ini
@@ -2,5 +2,6 @@
HALT_ON_FAILURE = True
WARN_ON_FAILURE = True
CONTAINER_BUILD = True
-CONTAINER_NAME = gnunet:riscv64
+CONTAINER_NAME = exchange:riscv64
CONTAINER_ARCH = riscv64
+
diff --git a/contrib/ci/jobs/130-build-debian-unstable-riscv64-generated/job.sh b/contrib/ci/jobs/130-build-debian-unstable-riscv64-generated/job.sh
new file mode 100755
index 000000000..8d79902c5
--- /dev/null
+++ b/contrib/ci/jobs/130-build-debian-unstable-riscv64-generated/job.sh
@@ -0,0 +1,6 @@
+#!/bin/bash
+set -exuo pipefail
+
+job_dir=$(dirname "${BASH_SOURCE[0]}")
+
+"${job_dir}"/build.sh
diff --git a/contrib/ci/jobs/131-deb-package-debian-unstable-riscv64-generated/Containerfile b/contrib/ci/jobs/131-deb-package-debian-unstable-riscv64-generated/Containerfile
new file mode 100644
index 000000000..6e2c93980
--- /dev/null
+++ b/contrib/ci/jobs/131-deb-package-debian-unstable-riscv64-generated/Containerfile
@@ -0,0 +1,68 @@
+FROM docker.io/debian
+
+ENV DEBIAN_FRONTEND=noninteractive
+
+RUN apt-get update -yqq && \
+ apt-get install -yqq \
+ autoconf \
+ autopoint \
+ curl \
+ bash \
+ coreutils \
+ git \
+ libcurl4-gnutls-dev \
+ libgcrypt-dev \
+ libidn11-dev \
+ libjansson-dev \
+ libmicrohttpd-dev \
+ libpq-dev \
+ libqrencode-dev \
+ libsodium-dev \
+ libtool \
+ libunistring-dev \
+ make \
+ pkg-config \
+ python3-pip \
+ python3-sphinx \
+ python3-sphinx-rtd-theme \
+ recutils \
+ texinfo \
+ zlib1g-dev \
+ # For mustach testing (optional) \
+ libjson-c-dev \
+ # Debian packaging tools \
+ po-debconf \
+ build-essential \
+ debhelper-compat \
+ devscripts \
+ git-buildpackage \
+ # Documentation dependencies \
+ doxygen \
+ graphviz \
+ pandoc \
+ # Test suite dependencies \
+ jq \
+ postgresql \
+ sudo \
+ wget
+
+# Install Taler (and friends) packages
+RUN curl -sS https://deb.taler.net/apt-nightly/taler-bookworm-ci.sources \
+ | tee /etc/apt/sources.list.d/taler-bookworm-ci.sources
+
+RUN echo '\
+Package: * \n\
+Pin: origin "deb.taler.net" \n\
+Pin-Priority: 999' > /etc/apt/preferences.d/taler
+
+RUN cat /etc/apt/preferences.d/taler && \
+ apt-get update -y && \
+ apt-get install -y \
+ libgnunet-dev \
+ libgnunet \
+ gnunet \
+&& rm -rf /var/lib/apt/lists/*
+
+WORKDIR /workdir
+
+CMD ["bash", "/workdir/ci/ci.sh"]
diff --git a/contrib/ci/jobs/10-deb-package-riscv64/config.ini b/contrib/ci/jobs/131-deb-package-debian-unstable-riscv64-generated/config.ini
index 73914f224..f3afa2db7 100644
--- a/contrib/ci/jobs/10-deb-package-riscv64/config.ini
+++ b/contrib/ci/jobs/131-deb-package-debian-unstable-riscv64-generated/config.ini
@@ -2,5 +2,6 @@
HALT_ON_FAILURE = True
WARN_ON_FAILURE = True
CONTAINER_BUILD = True
-CONTAINER_NAME = gnunet:riscv64
+CONTAINER_NAME = exchange:riscv64
CONTAINER_ARCH = riscv64
+
diff --git a/contrib/ci/jobs/131-deb-package-debian-unstable-riscv64-generated/install-fix.patch b/contrib/ci/jobs/131-deb-package-debian-unstable-riscv64-generated/install-fix.patch
new file mode 100644
index 000000000..8334c5a7a
--- /dev/null
+++ b/contrib/ci/jobs/131-deb-package-debian-unstable-riscv64-generated/install-fix.patch
@@ -0,0 +1,13 @@
+diff --git a/debian/taler-exchange.install b/debian/taler-exchange.install
+index 631c270b..072c6231 100644
+--- a/debian/taler-exchange.install
++++ b/debian/taler-exchange.install
+@@ -36,6 +36,6 @@ usr/share/taler/exchange/templates/*.must
+ debian/etc-taler-exchange/* etc/
+
+ # Terms of service / privacy policy templates
+-usr/share/taler/exchange/*.rst
++#usr/share/taler/exchange/terms/*.rst
+ # Translations of ToS/PP
+-usr/share/taler/exchange/locale/*/LC_MESSAGES/*.po
++#usr/share/taler/exchange/terms/locale/*/LC_MESSAGES/*.po
diff --git a/contrib/ci/jobs/131-deb-package-debian-unstable-riscv64-generated/job.sh b/contrib/ci/jobs/131-deb-package-debian-unstable-riscv64-generated/job.sh
new file mode 100755
index 000000000..922f8bf63
--- /dev/null
+++ b/contrib/ci/jobs/131-deb-package-debian-unstable-riscv64-generated/job.sh
@@ -0,0 +1,23 @@
+#!/bin/bash
+set -exuo pipefail
+# This file is in the public domain.
+# Helper script to build the latest DEB packages in the container.
+
+
+unset LD_LIBRARY_PATH
+
+# Install build-time dependencies.
+# Update apt cache first
+apt-get update
+apt-get upgrade -y
+mk-build-deps --install --tool='apt-get -o Debug::pkgProblemResolver=yes --no-install-recommends --yes' debian/control
+
+export VERSION="$(./contrib/ci/jobs/4-deb-package/version.sh)"
+echo "Building package version ${VERSION}"
+EMAIL=none gbp dch --dch-opt=-b --ignore-branch --debian-tag="%(version)s" --git-author --new-version="${VERSION}"
+./bootstrap
+dpkg-buildpackage -rfakeroot -b -uc -us
+
+ls -alh ../*.deb
+mkdir -p /artifacts/exchange/${CI_COMMIT_REF} # Variable comes from CI environment
+mv ../*.deb /artifacts/exchange/${CI_COMMIT_REF}/
diff --git a/contrib/ci/jobs/131-deb-package-debian-unstable-riscv64-generated/version.sh b/contrib/ci/jobs/131-deb-package-debian-unstable-riscv64-generated/version.sh
new file mode 100755
index 000000000..52031b23a
--- /dev/null
+++ b/contrib/ci/jobs/131-deb-package-debian-unstable-riscv64-generated/version.sh
@@ -0,0 +1,17 @@
+#!/bin/sh
+set -ex
+
+BRANCH=$(git name-rev --name-only HEAD)
+if [ -z "${BRANCH}" ]; then
+ exit 1
+else
+ # "Unshallow" our checkout, but only our current branch, and exclude the submodules.
+ git fetch --no-recurse-submodules --tags --depth=1000 origin "${BRANCH}"
+ RECENT_VERSION_TAG=$(git describe --tags --match 'v*.*.*' --exclude '*-dev*' --always --abbrev=0 HEAD || exit 1)
+ commits="$(git rev-list ${RECENT_VERSION_TAG}..HEAD --count)"
+ if [ "${commits}" = "0" ]; then
+ git describe --tag HEAD | sed -r 's/^v//' || exit 1
+ else
+ echo $(echo ${RECENT_VERSION_TAG} | sed -r 's/^v//')-${commits}-$(git rev-parse --short=8 HEAD)
+ fi
+fi
diff --git a/contrib/ci/jobs/132-deploy-package-debian-unstable-riscv64-generated/config.ini b/contrib/ci/jobs/132-deploy-package-debian-unstable-riscv64-generated/config.ini
new file mode 100644
index 000000000..8d6409a6e
--- /dev/null
+++ b/contrib/ci/jobs/132-deploy-package-debian-unstable-riscv64-generated/config.ini
@@ -0,0 +1,5 @@
+[build]
+HALT_ON_FAILURE = True
+WARN_ON_FAILURE = True
+CONTAINER_BUILD = False
+CONTAINER_NAME = nixery.dev/shell/rsync
diff --git a/contrib/ci/jobs/132-deploy-package-debian-unstable-riscv64-generated/job.sh b/contrib/ci/jobs/132-deploy-package-debian-unstable-riscv64-generated/job.sh
new file mode 100755
index 000000000..d39cf9987
--- /dev/null
+++ b/contrib/ci/jobs/132-deploy-package-debian-unstable-riscv64-generated/job.sh
@@ -0,0 +1,14 @@
+#!/bin/bash
+set -exuo pipefail
+
+ARTIFACT_PATH="/artifacts/exchange/${CI_COMMIT_REF}/*.deb"
+
+RSYNC_HOST="taler.host.internal"
+RSYNC_PORT=424242
+RSYNC_PATH="incoming_packages/bookworm-taler-ci/"
+RSYNC_DEST="rsync://${RSYNC_HOST}/${RSYNC_PATH}"
+
+
+rsync -vP \
+ --port ${RSYNC_PORT} \
+ ${ARTIFACT_PATH} ${RSYNC_DEST}
diff --git a/contrib/ci/jobs/4-deb-package-amd64/install-fix.patch b/contrib/ci/jobs/4-deb-package-amd64/install-fix.patch
index 8abc5e3be..059182140 120000
--- a/contrib/ci/jobs/4-deb-package-amd64/install-fix.patch
+++ b/contrib/ci/jobs/4-deb-package-amd64/install-fix.patch
@@ -1 +1 @@
-../../common/debian/deb-package/install-fix.patch \ No newline at end of file
+../../targets/debian/deb-package/install-fix.patch \ No newline at end of file
diff --git a/contrib/ci/jobs/4-deb-package-amd64/job.sh b/contrib/ci/jobs/4-deb-package-amd64/job.sh
index 905d8a638..24f481dda 120000
--- a/contrib/ci/jobs/4-deb-package-amd64/job.sh
+++ b/contrib/ci/jobs/4-deb-package-amd64/job.sh
@@ -1 +1 @@
-../../common/debian/deb-package/job.sh \ No newline at end of file
+../../targets/debian/deb-package/job.sh \ No newline at end of file
diff --git a/contrib/ci/jobs/4-deb-package-amd64/version.sh b/contrib/ci/jobs/4-deb-package-amd64/version.sh
index 7c51b7217..16edff5e5 120000
--- a/contrib/ci/jobs/4-deb-package-amd64/version.sh
+++ b/contrib/ci/jobs/4-deb-package-amd64/version.sh
@@ -1 +1 @@
-../../common/debian/deb-package/version.sh \ No newline at end of file
+../../targets/debian/deb-package/version.sh \ No newline at end of file
diff --git a/contrib/ci/jobs/6-build-arm64/build.sh b/contrib/ci/jobs/6-build-arm64/build.sh
index e8d2a7f97..3babff0b8 120000
--- a/contrib/ci/jobs/6-build-arm64/build.sh
+++ b/contrib/ci/jobs/6-build-arm64/build.sh
@@ -1 +1 @@
-../../common/debian/build/build.sh \ No newline at end of file
+../../targets/debian/build/build.sh \ No newline at end of file
diff --git a/contrib/ci/jobs/6-build-arm64/config.ini b/contrib/ci/jobs/6-build-arm64/config.ini
index b5b4b5fe7..0b5c6ba9f 100644
--- a/contrib/ci/jobs/6-build-arm64/config.ini
+++ b/contrib/ci/jobs/6-build-arm64/config.ini
@@ -2,5 +2,5 @@
HALT_ON_FAILURE = True
WARN_ON_FAILURE = True
CONTAINER_BUILD = True
-CONTAINER_NAME = gnunet:arm64
+CONTAINER_NAME = exchange:arm64
CONTAINER_ARCH = arm64
diff --git a/contrib/ci/jobs/6-build-arm64/job.sh b/contrib/ci/jobs/6-build-arm64/job.sh
index a97450993..8a185151e 120000
--- a/contrib/ci/jobs/6-build-arm64/job.sh
+++ b/contrib/ci/jobs/6-build-arm64/job.sh
@@ -1 +1 @@
-../../common/debian/build/job.sh \ No newline at end of file
+../../targets/debian/build/job.sh \ No newline at end of file
diff --git a/contrib/ci/jobs/7-deb-package-arm64/install-fix.patch b/contrib/ci/jobs/7-deb-package-arm64/install-fix.patch
deleted file mode 120000
index 8abc5e3be..000000000
--- a/contrib/ci/jobs/7-deb-package-arm64/install-fix.patch
+++ /dev/null
@@ -1 +0,0 @@
-../../common/debian/deb-package/install-fix.patch \ No newline at end of file
diff --git a/contrib/ci/jobs/7-deb-package-arm64/job.sh b/contrib/ci/jobs/7-deb-package-arm64/job.sh
deleted file mode 120000
index 905d8a638..000000000
--- a/contrib/ci/jobs/7-deb-package-arm64/job.sh
+++ /dev/null
@@ -1 +0,0 @@
-../../common/debian/deb-package/job.sh \ No newline at end of file
diff --git a/contrib/ci/jobs/7-deb-package-arm64/version.sh b/contrib/ci/jobs/7-deb-package-arm64/version.sh
deleted file mode 120000
index 7c51b7217..000000000
--- a/contrib/ci/jobs/7-deb-package-arm64/version.sh
+++ /dev/null
@@ -1 +0,0 @@
-../../common/debian/deb-package/version.sh \ No newline at end of file
diff --git a/contrib/ci/jobs/8-deploy-package-arm64 b/contrib/ci/jobs/8-deploy-package-arm64
deleted file mode 120000
index a58645d78..000000000
--- a/contrib/ci/jobs/8-deploy-package-arm64
+++ /dev/null
@@ -1 +0,0 @@
-5-deploy-package-amd64 \ No newline at end of file
diff --git a/contrib/ci/jobs/9-build-riscv64/build.sh b/contrib/ci/jobs/9-build-riscv64/build.sh
deleted file mode 120000
index e8d2a7f97..000000000
--- a/contrib/ci/jobs/9-build-riscv64/build.sh
+++ /dev/null
@@ -1 +0,0 @@
-../../common/debian/build/build.sh \ No newline at end of file
diff --git a/contrib/ci/jobs/9-build-riscv64/job.sh b/contrib/ci/jobs/9-build-riscv64/job.sh
deleted file mode 120000
index a97450993..000000000
--- a/contrib/ci/jobs/9-build-riscv64/job.sh
+++ /dev/null
@@ -1 +0,0 @@
-../../common/debian/build/job.sh \ No newline at end of file
diff --git a/contrib/ci/run-all-jobs b/contrib/ci/run-all-jobs
new file mode 100755
index 000000000..a4837191c
--- /dev/null
+++ b/contrib/ci/run-all-jobs
@@ -0,0 +1,5 @@
+#!/bin/bash
+set -eax
+for JOB in $(ls $(dirname $0)/jobs | sort -n); do
+ $(dirname $0)/ci.sh $JOB;
+done;
diff --git a/contrib/ci/targets/debian/Containerfile b/contrib/ci/targets/debian/Containerfile
new file mode 100644
index 000000000..a7fe8a3ac
--- /dev/null
+++ b/contrib/ci/targets/debian/Containerfile
@@ -0,0 +1,68 @@
+FROM docker.io/library/debian:bookworm
+
+ENV DEBIAN_FRONTEND=noninteractive
+
+RUN apt-get update -yqq && \
+ apt-get install -yqq \
+ autoconf \
+ autopoint \
+ curl \
+ bash \
+ coreutils \
+ git \
+ libcurl4-gnutls-dev \
+ libgcrypt-dev \
+ libidn11-dev \
+ libjansson-dev \
+ libmicrohttpd-dev \
+ libpq-dev \
+ libqrencode-dev \
+ libsodium-dev \
+ libtool \
+ libunistring-dev \
+ make \
+ pkg-config \
+ python3-pip \
+ python3-sphinx \
+ python3-sphinx-rtd-theme \
+ recutils \
+ texinfo \
+ zlib1g-dev \
+ # For mustach testing (optional) \
+ libjson-c-dev \
+ # Debian packaging tools \
+ po-debconf \
+ build-essential \
+ debhelper-compat \
+ devscripts \
+ git-buildpackage \
+ # Documentation dependencies \
+ doxygen \
+ graphviz \
+ pandoc \
+ # Test suite dependencies \
+ jq \
+ postgresql \
+ sudo \
+ wget
+
+# Install Taler (and friends) packages
+RUN curl -sS https://deb.taler.net/apt-nightly/taler-bookworm-ci.sources \
+ | tee /etc/apt/sources.list.d/taler-bookworm-ci.sources
+
+RUN echo '\
+Package: * \n\
+Pin: origin "deb.taler.net" \n\
+Pin-Priority: 999' > /etc/apt/preferences.d/taler
+
+RUN cat /etc/apt/preferences.d/taler && \
+ apt-get update -y && \
+ apt-get install -y \
+ libgnunet-dev \
+ libgnunet \
+ gnunet \
+&& rm -rf /var/lib/apt/lists/*
+
+WORKDIR /workdir
+
+CMD ["bash", "/workdir/ci/ci.sh"]
diff --git a/contrib/ci/targets/debian/build/build.sh b/contrib/ci/targets/debian/build/build.sh
new file mode 100755
index 000000000..d3fcfab85
--- /dev/null
+++ b/contrib/ci/targets/debian/build/build.sh
@@ -0,0 +1,14 @@
+#!/bin/bash
+set -exuo pipefail
+
+apt-get update
+apt-get upgrade -yqq
+
+./bootstrap
+./configure CFLAGS="-ggdb -O0" \
+ --enable-logging=verbose \
+ --disable-doc
+
+nump=$(grep processor /proc/cpuinfo | wc -l)
+make -j$(( $nump / 2 ))
+make
diff --git a/contrib/ci/targets/debian/build/job.sh b/contrib/ci/targets/debian/build/job.sh
new file mode 100755
index 000000000..8d79902c5
--- /dev/null
+++ b/contrib/ci/targets/debian/build/job.sh
@@ -0,0 +1,6 @@
+#!/bin/bash
+set -exuo pipefail
+
+job_dir=$(dirname "${BASH_SOURCE[0]}")
+
+"${job_dir}"/build.sh
diff --git a/contrib/ci/targets/debian/deb-package/install-fix.patch b/contrib/ci/targets/debian/deb-package/install-fix.patch
new file mode 100644
index 000000000..8334c5a7a
--- /dev/null
+++ b/contrib/ci/targets/debian/deb-package/install-fix.patch
@@ -0,0 +1,13 @@
+diff --git a/debian/taler-exchange.install b/debian/taler-exchange.install
+index 631c270b..072c6231 100644
+--- a/debian/taler-exchange.install
++++ b/debian/taler-exchange.install
+@@ -36,6 +36,6 @@ usr/share/taler/exchange/templates/*.must
+ debian/etc-taler-exchange/* etc/
+
+ # Terms of service / privacy policy templates
+-usr/share/taler/exchange/*.rst
++#usr/share/taler/exchange/terms/*.rst
+ # Translations of ToS/PP
+-usr/share/taler/exchange/locale/*/LC_MESSAGES/*.po
++#usr/share/taler/exchange/terms/locale/*/LC_MESSAGES/*.po
diff --git a/contrib/ci/targets/debian/deb-package/job.sh b/contrib/ci/targets/debian/deb-package/job.sh
new file mode 100755
index 000000000..922f8bf63
--- /dev/null
+++ b/contrib/ci/targets/debian/deb-package/job.sh
@@ -0,0 +1,23 @@
+#!/bin/bash
+set -exuo pipefail
+# This file is in the public domain.
+# Helper script to build the latest DEB packages in the container.
+
+
+unset LD_LIBRARY_PATH
+
+# Install build-time dependencies.
+# Update apt cache first
+apt-get update
+apt-get upgrade -y
+mk-build-deps --install --tool='apt-get -o Debug::pkgProblemResolver=yes --no-install-recommends --yes' debian/control
+
+export VERSION="$(./contrib/ci/jobs/4-deb-package/version.sh)"
+echo "Building package version ${VERSION}"
+EMAIL=none gbp dch --dch-opt=-b --ignore-branch --debian-tag="%(version)s" --git-author --new-version="${VERSION}"
+./bootstrap
+dpkg-buildpackage -rfakeroot -b -uc -us
+
+ls -alh ../*.deb
+mkdir -p /artifacts/exchange/${CI_COMMIT_REF} # Variable comes from CI environment
+mv ../*.deb /artifacts/exchange/${CI_COMMIT_REF}/
diff --git a/contrib/ci/targets/debian/deb-package/version.sh b/contrib/ci/targets/debian/deb-package/version.sh
new file mode 100755
index 000000000..52031b23a
--- /dev/null
+++ b/contrib/ci/targets/debian/deb-package/version.sh
@@ -0,0 +1,17 @@
+#!/bin/sh
+set -ex
+
+BRANCH=$(git name-rev --name-only HEAD)
+if [ -z "${BRANCH}" ]; then
+ exit 1
+else
+ # "Unshallow" our checkout, but only our current branch, and exclude the submodules.
+ git fetch --no-recurse-submodules --tags --depth=1000 origin "${BRANCH}"
+ RECENT_VERSION_TAG=$(git describe --tags --match 'v*.*.*' --exclude '*-dev*' --always --abbrev=0 HEAD || exit 1)
+ commits="$(git rev-list ${RECENT_VERSION_TAG}..HEAD --count)"
+ if [ "${commits}" = "0" ]; then
+ git describe --tag HEAD | sed -r 's/^v//' || exit 1
+ else
+ echo $(echo ${RECENT_VERSION_TAG} | sed -r 's/^v//')-${commits}-$(git rev-parse --short=8 HEAD)
+ fi
+fi
diff --git a/contrib/ci/targets/debian/deploy-package/config.ini b/contrib/ci/targets/debian/deploy-package/config.ini
new file mode 100644
index 000000000..8d6409a6e
--- /dev/null
+++ b/contrib/ci/targets/debian/deploy-package/config.ini
@@ -0,0 +1,5 @@
+[build]
+HALT_ON_FAILURE = True
+WARN_ON_FAILURE = True
+CONTAINER_BUILD = False
+CONTAINER_NAME = nixery.dev/shell/rsync
diff --git a/contrib/ci/targets/debian/deploy-package/job.sh b/contrib/ci/targets/debian/deploy-package/job.sh
new file mode 100755
index 000000000..d39cf9987
--- /dev/null
+++ b/contrib/ci/targets/debian/deploy-package/job.sh
@@ -0,0 +1,14 @@
+#!/bin/bash
+set -exuo pipefail
+
+ARTIFACT_PATH="/artifacts/exchange/${CI_COMMIT_REF}/*.deb"
+
+RSYNC_HOST="taler.host.internal"
+RSYNC_PORT=424242
+RSYNC_PATH="incoming_packages/bookworm-taler-ci/"
+RSYNC_DEST="rsync://${RSYNC_HOST}/${RSYNC_PATH}"
+
+
+rsync -vP \
+ --port ${RSYNC_PORT} \
+ ${ARTIFACT_PATH} ${RSYNC_DEST}
diff --git a/contrib/ci/targets/debian/setup-job.sh b/contrib/ci/targets/debian/setup-job.sh
new file mode 100755
index 000000000..b632eaf06
--- /dev/null
+++ b/contrib/ci/targets/debian/setup-job.sh
@@ -0,0 +1,50 @@
+#!/bin/bash
+set -eax
+# Variables passed in:
+# - CI_DIR: Path to contrib/ci
+# - DISTRO: Distro Name (debian)
+# - CODENAME: Codename to target
+# - ARCH: Architecture to use
+# - OCI_IMAGE: The OCI image we're expected to target
+# - DISTRO_TARGET: The TARGET dir of the current distro (targets/debian)
+# - CONTAINERFILE: Our input Containerfile
+# Helper Scripts:
+# - mktarget: Makes a target for us
+
+# Generate the build target
+cd "${CI_DIR}/jobs/$(mktarget 0 build)"
+sed "1s|FROM .*|FROM ${OCI_IMAGE}|" "$CONTAINERFILE" > Containerfile
+cp "$DISTRO_TARGET/build/build.sh" ./
+cp "$DISTRO_TARGET/build/job.sh" ./
+
+if [[ "$ARCH" != "amd64" ]]; then
+ echo '[build]
+HALT_ON_FAILURE = True
+WARN_ON_FAILURE = True
+CONTAINER_BUILD = True
+CONTAINER_NAME = exchange:'"$ARCH"'
+CONTAINER_ARCH = '"$ARCH"'
+' > config.ini
+fi;
+
+# Generate the deb-package target
+cd "${CI_DIR}/jobs/$(mktarget 1 deb-package)"
+sed "1s|FROM .*|FROM ${OCI_IMAGE}|" "$CONTAINERFILE" > Containerfile
+cp "$DISTRO_TARGET/deb-package/version.sh" ./
+cp "$DISTRO_TARGET/deb-package/job.sh" ./
+cp "$DISTRO_TARGET/deb-package/install-fix.patch" ./
+
+if [[ "$ARCH" != "amd64" ]]; then
+ echo '[build]
+HALT_ON_FAILURE = True
+WARN_ON_FAILURE = True
+CONTAINER_BUILD = True
+CONTAINER_NAME = exchange:'"$ARCH"'
+CONTAINER_ARCH = '"$ARCH"'
+' > config.ini
+fi;
+
+# Generate the deploy-package target
+cd "${CI_DIR}/jobs/$(mktarget 2 deploy-package)"
+cp "$DISTRO_TARGET/deploy-package/config.ini" ./
+cp "$DISTRO_TARGET/deploy-package/job.sh" ./