anastasis

Credential backup and recovery protocol and service
Log | Files | Refs | Submodules | README | LICENSE

commit f5320a6e87f3e5f590f643783eb5dd54fbd8ba87
parent ef7c440f21067a185746fcb639902e4531e91280
Author: Christian Grothoff <christian@grothoff.org>
Date:   Tue,  4 Aug 2026 10:55:46 +0200

add CI

Diffstat:
Acontrib/ci/Containerfile | 91+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Acontrib/ci/ci.sh | 34++++++++++++++++++++++++++++++++++
Acontrib/ci/jobs/0-codespell/config.ini | 6++++++
Acontrib/ci/jobs/0-codespell/dictionary.txt | 23+++++++++++++++++++++++
Acontrib/ci/jobs/0-codespell/job.sh | 41+++++++++++++++++++++++++++++++++++++++++
Acontrib/ci/jobs/1-build/build.sh | 25+++++++++++++++++++++++++
Acontrib/ci/jobs/1-build/config.ini | 6++++++
Acontrib/ci/jobs/1-build/job.sh | 9+++++++++
Acontrib/ci/jobs/2-test/1-build.sh | 11+++++++++++
Acontrib/ci/jobs/2-test/2-install.sh | 7+++++++
Acontrib/ci/jobs/2-test/3-startdb.sh | 24++++++++++++++++++++++++
Acontrib/ci/jobs/2-test/4-test.sh | 25+++++++++++++++++++++++++
Acontrib/ci/jobs/2-test/5-coverage.sh | 18++++++++++++++++++
Acontrib/ci/jobs/2-test/config.ini | 6++++++
Acontrib/ci/jobs/2-test/job.sh | 10++++++++++
Acontrib/ci/jobs/3-docs/config.ini | 6++++++
Acontrib/ci/jobs/3-docs/docs.sh | 19+++++++++++++++++++
Acontrib/ci/jobs/3-docs/job.sh | 6++++++
Acontrib/ci/jobs/4-deb-package/config.ini | 6++++++
Acontrib/ci/jobs/4-deb-package/job.sh | 23+++++++++++++++++++++++
Acontrib/ci/jobs/4-deb-package/version.sh | 19+++++++++++++++++++
Acontrib/ci/jobs/5-deploy-package/config.ini | 6++++++
Acontrib/ci/jobs/5-deploy-package/job.sh | 14++++++++++++++
Acontrib/ci/jobs/6-db-naming/config.ini | 6++++++
Acontrib/ci/jobs/6-db-naming/job.sh | 4++++
25 files changed, 445 insertions(+), 0 deletions(-)

diff --git a/contrib/ci/Containerfile b/contrib/ci/Containerfile @@ -0,0 +1,91 @@ +FROM docker.io/library/debian:trixie + +ENV DEBIAN_FRONTEND=noninteractive + +RUN apt-get update -yqq && \ + apt-get install -yqq \ + git \ + meson \ + ninja-build \ + make \ + pkg-config \ + libtool \ + build-essential \ + autopoint \ + gettext \ + curl \ + wget \ + libcurl4-gnutls-dev \ + libgcrypt-dev \ + libjansson-dev \ + libmicrohttpd-dev \ + libpq-dev \ + libqrencode-dev \ + libsodium-dev \ + libsqlite3-dev \ + libunistring-dev \ + uuid-dev \ + zlib1g-dev \ + # Test suite dependencies \ + jq \ + postgresql \ + sudo + +# Debian packaging tools +RUN apt-get install -yqq \ + po-debconf \ + debhelper-compat \ + devscripts \ + fakeroot \ + git-buildpackage + +# Documentation generation utils. The Texinfo manual is built by +# 'make' itself (texinfo/makeinfo), the handbook by Sphinx; the theme +# and the httpdomain extension are vendored in doc/sphinx/_exts/, but +# recommonmark and graphviz are not. +RUN apt-get update -yqq && \ + apt-get install -yqq \ + texinfo \ + python3-sphinx \ + python3-sphinx-rtd-theme \ + python3-recommonmark \ + graphviz \ + # For coverage reports and their upload \ + lcov \ + rsync \ + && rm -rf /var/lib/apt/lists/* + +# Install Taler (and friends) packages +RUN curl -sS https://deb.taler.net/apt-nightly/taler-trixie-ci.sources \ + | tee /etc/apt/sources.list.d/taler-trixie-ci.sources + +RUN echo '\ +Package: * \n\ +Pin: origin "deb.taler.net" \n\ +Pin-Priority: 999' > /etc/apt/preferences.d/taler + +# libtalerexchange-dev provides taler-unified-setup.sh, which the reducer +# and IBAN CLI tests use to bring up an exchange, a merchant and a bank. +RUN cat /etc/apt/preferences.d/taler && \ + apt-get update -y && \ + apt-get install -y \ + libgnunet-dev \ + libgnunet \ + gnunet \ + libtalerexchange-dev \ + libtalerexchange \ + libtalermerchant-dev \ + libtalermerchant \ + taler-exchange \ + taler-exchange-database \ + taler-exchange-offline \ + taler-auditor \ + taler-merchant \ + taler-harness \ + taler-wallet-cli \ + libeufin-common \ + libeufin-bank \ + libeufin-nexus \ +&& rm -rf /var/lib/apt/lists/* + +WORKDIR /workdir diff --git a/contrib/ci/ci.sh b/contrib/ci/ci.sh @@ -0,0 +1,34 @@ +#!/bin/bash +set -exvuo pipefail + +# Run a single CI job locally, in the same container the buildbot uses. +# Usage: ./contrib/ci/ci.sh <job-name> [arch] +# e.g. ./contrib/ci/ci.sh 2-test + +# Requires podman +# Fails if not found in PATH +OCI_RUNTIME=$(which podman) +REPO_NAME=$(basename "${PWD}") +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") + +echo "Image name: ${JOB_CONTAINER}" + +if [ "${CONTAINER_BUILD}" = "True" ] ; then + "${OCI_RUNTIME}" build \ + --arch "${JOB_ARCH}" \ + -t "${JOB_CONTAINER}" \ + -f contrib/ci/Containerfile . +fi + +"${OCI_RUNTIME}" run \ + --rm \ + -ti \ + --arch "${JOB_ARCH}" \ + --env CI_COMMIT_REF="$(git rev-parse HEAD)" \ + --volume "${PWD}":/workdir \ + --workdir /workdir \ + "${JOB_CONTAINER}" \ + contrib/ci/jobs/"${JOB_NAME}"/job.sh diff --git a/contrib/ci/jobs/0-codespell/config.ini b/contrib/ci/jobs/0-codespell/config.ini @@ -0,0 +1,6 @@ +[build] +HALT_ON_FAILURE = False +WARN_ON_FAILURE = True +CONTAINER_BUILD = False +CONTAINER_NAME = nixery.dev/shell/codespell +CONTAINER_ARCH = amd64 diff --git a/contrib/ci/jobs/0-codespell/dictionary.txt b/contrib/ci/jobs/0-codespell/dictionary.txt @@ -0,0 +1,23 @@ +# List of "words" that codespell should ignore in our sources. +# +# Note: The word sensitivity depends on how the to-be-ignored word is +# spelled in codespell_lib/data/dictionary.txt. F.e. if there is a word +# 'foo' and you add 'Foo' _here_, codespell will continue to complain +# about 'Foo'. +# +# "ect"/"ECT" is the HKDF salt used when encrypting truth, it is part of +# the protocol and must not be "corrected" to "etc". +ect +ECT +# Local variable names. +dum +fo +pres +# German ("Ihr ... Code ist:", "an eine Adresse") in the i18n +# authorization messages. +ist +Adresse +# French ("Nom complet") in the identity attribute labels. +complet +# French/Belgian ("numero de registre national") in the BE validator. +registre diff --git a/contrib/ci/jobs/0-codespell/job.sh b/contrib/ci/jobs/0-codespell/job.sh @@ -0,0 +1,41 @@ +#!/bin/bash +set -exuo pipefail + +job_dir=$(dirname "${BASH_SOURCE[0]}") + +skip=$(cat <<EOF +ABOUT-NLS +configure +config.guess +configure~ +*/debian/upstream/* +*/debian/.debhelper/* +*/build/* +*/contrib/gana/* +*/contrib/locale/* +*/doc/prebuilt/* +*/doc/doxygen/* +*/doc/system-documentation/* +*/doc/sphinx/_exts/* +*/doc/anastasis.texi +*/doc/manual.info +*/doc/texinfo.tex +*/doc/highlight.pack.js +*/po/* +*build-aux* +*.cache/* +*/.git/* +*/contrib/ci/* +depcomp +*libtool* +ltmain.sh +*.log +*/m4/* +*.m4 +*.rpath +EOF +); + +echo Current directory: `pwd` + +codespell -I "${job_dir}"/dictionary.txt -S ${skip//$'\n'/,} diff --git a/contrib/ci/jobs/1-build/build.sh b/contrib/ci/jobs/1-build/build.sh @@ -0,0 +1,25 @@ +#!/bin/bash +set -exuo pipefail + +build_command() +{ + ./bootstrap + ./configure CFLAGS="-ggdb -O0" \ + --prefix=/usr \ + --enable-logging=verbose + + nump=$(grep -c processor /proc/cpuinfo) + make -j$(( nump / 2 + 1 )) +} + +print_logs() +{ + set +e + echo "Printing meson log" + cat build/meson-logs/meson-log.txt +} + +if ! build_command ; then + print_logs + exit 1 +fi diff --git a/contrib/ci/jobs/1-build/config.ini b/contrib/ci/jobs/1-build/config.ini @@ -0,0 +1,6 @@ +[build] +HALT_ON_FAILURE = True +WARN_ON_FAILURE = False +CONTAINER_BUILD = True +CONTAINER_NAME = localhost/anastasis +CONTAINER_ARCH = amd64 diff --git a/contrib/ci/jobs/1-build/job.sh b/contrib/ci/jobs/1-build/job.sh @@ -0,0 +1,9 @@ +#!/bin/bash +set -exuo pipefail + +apt-get update -yq +apt-get upgrade -yq + +job_dir=$(dirname "${BASH_SOURCE[0]}") + +"${job_dir}"/build.sh diff --git a/contrib/ci/jobs/2-test/1-build.sh b/contrib/ci/jobs/2-test/1-build.sh @@ -0,0 +1,11 @@ +#!/bin/bash +set -evux + +apt-get update +apt-get upgrade -yqq + +./bootstrap +./configure CFLAGS="-ggdb -O0" \ + --prefix=/usr \ + --enable-coverage \ + --enable-logging=verbose diff --git a/contrib/ci/jobs/2-test/2-install.sh b/contrib/ci/jobs/2-test/2-install.sh @@ -0,0 +1,7 @@ +#!/bin/bash +set -evux + +# 'make check' resolves anastasis-httpd, anastasis-dbinit and the +# authorization plugins via ANASTASIS_PREFIX, so the tests only work +# against an installed tree. +make install diff --git a/contrib/ci/jobs/2-test/3-startdb.sh b/contrib/ci/jobs/2-test/3-startdb.sh @@ -0,0 +1,24 @@ +#!/bin/bash +set -evux + +PG_BIN=$(pg_config --bindir) +PG_ETC=$(pg_config --sharedir | sed 's|/usr/share/postgresql|/etc/postgresql|') +export PGPORT=5432 + +sudo -u postgres "${PG_BIN}/pg_ctl" \ + start \ + -D ${PG_ETC}/main \ + -o "-h localhost -p $PGPORT" +sleep 10 +sudo -u postgres createuser -p "$PGPORT" root -s -w + +# 'talercheck' is used by the exchange, the merchant and libeufin-bank +# that taler-unified-setup.sh brings up for the reducer and IBAN tests. +sudo -u postgres createdb -p "$PGPORT" -O root talercheck +# The provider database: 'anastasischeck' for the stasis and testing +# suites, 'anastasischeck1' .. 'anastasischeck4' for the four providers +# the reducer/CLI tests run against (see src/cli/test_anastasis_reducer_*.conf). +sudo -u postgres createdb -p "$PGPORT" -O root anastasischeck +for n in 1 2 3 4; do + sudo -u postgres createdb -p "$PGPORT" -O root "anastasischeck${n}" +done diff --git a/contrib/ci/jobs/2-test/4-test.sh b/contrib/ci/jobs/2-test/4-test.sh @@ -0,0 +1,25 @@ +#!/bin/bash +set -evux + +check_command() +{ + # Set LD_LIBRARY_PATH so tests can find the installed libs; + # libanastasis* land in the multiarch libdir, the Taler libraries + # come from the Debian packages. + export LD_LIBRARY_PATH=/usr/lib/x86_64-linux-gnu:/usr/lib/x86_64-linux-gnu/taler:/usr/lib/x86_64-linux-gnu/taler-merchant:/usr/lib + # taler-unified-setup.sh (used by the reducer and IBAN tests) wants this + export USER=root + PGPORT=5432 make check +} + +print_logs() +{ + set +e + echo "Printing meson log" + cat build/meson-logs/testlog.txt +} + +if ! check_command ; then + print_logs + exit 1 +fi diff --git a/contrib/ci/jobs/2-test/5-coverage.sh b/contrib/ci/jobs/2-test/5-coverage.sh @@ -0,0 +1,18 @@ +#!/bin/bash +set -evux + +ARTIFACT_PATH="/artifacts/anastasis/lcov/${CI_COMMIT_REF}/anastasis" +mkdir -p /artifacts/anastasis/lcov/${CI_COMMIT_REF} # Variable comes from CI environment +lcov --ignore-errors version --capture --directory . --output-file coverage.info || exit 1 +genhtml coverage.info --output-directory ${ARTIFACT_PATH} || exit 1 + + +RSYNC_HOST="taler.host.internal" +RSYNC_PORT=424243 +RSYNC_PATH="incoming_taler/" +RSYNC_DEST="rsync://${RSYNC_HOST}/${RSYNC_PATH}" + + +rsync -rvP \ + --port ${RSYNC_PORT} \ + ${ARTIFACT_PATH} ${RSYNC_DEST} || exit 1 diff --git a/contrib/ci/jobs/2-test/config.ini b/contrib/ci/jobs/2-test/config.ini @@ -0,0 +1,6 @@ +[build] +HALT_ON_FAILURE = False +WARN_ON_FAILURE = True +CONTAINER_BUILD = True +CONTAINER_NAME = localhost/anastasis +CONTAINER_ARCH = amd64 diff --git a/contrib/ci/jobs/2-test/job.sh b/contrib/ci/jobs/2-test/job.sh @@ -0,0 +1,10 @@ +#!/bin/bash +set -exuo pipefail + +job_dir=$(dirname "${BASH_SOURCE[0]}") + +"${job_dir}"/1-build.sh +"${job_dir}"/2-install.sh +"${job_dir}"/3-startdb.sh +"${job_dir}"/4-test.sh +"${job_dir}"/5-coverage.sh diff --git a/contrib/ci/jobs/3-docs/config.ini b/contrib/ci/jobs/3-docs/config.ini @@ -0,0 +1,6 @@ +[build] +HALT_ON_FAILURE = False +WARN_ON_FAILURE = True +CONTAINER_BUILD = True +CONTAINER_NAME = localhost/anastasis +CONTAINER_ARCH = amd64 diff --git a/contrib/ci/jobs/3-docs/docs.sh b/contrib/ci/jobs/3-docs/docs.sh @@ -0,0 +1,19 @@ +#!/bin/bash +set -exuo pipefail + +# There is no Doxygen configuration in this repository (doc/doxygen only +# holds the GNUnet/Taler tag files), so the documentation job builds the +# two things that are actually generated here: the Texinfo manual, via +# '--enable-only-doc' (which skips compiling any C), and the Sphinx +# handbook under doc/sphinx. + +./bootstrap +./configure --enable-only-doc + +make + +pushd ./doc/sphinx/ + +make html + +popd diff --git a/contrib/ci/jobs/3-docs/job.sh b/contrib/ci/jobs/3-docs/job.sh @@ -0,0 +1,6 @@ +#!/bin/bash +set -exuo pipefail + +job_dir=$(dirname "${BASH_SOURCE[0]}") + +"${job_dir}"/docs.sh diff --git a/contrib/ci/jobs/4-deb-package/config.ini b/contrib/ci/jobs/4-deb-package/config.ini @@ -0,0 +1,6 @@ +[build] +HALT_ON_FAILURE = True +WARN_ON_FAILURE = False +CONTAINER_BUILD = True +CONTAINER_NAME = localhost/anastasis +CONTAINER_ARCH = amd64 diff --git a/contrib/ci/jobs/4-deb-package/job.sh b/contrib/ci/jobs/4-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 --ignore-branch --debian-tag="%(version)s" --git-author --new-version="${VERSION}" +./bootstrap +dpkg-buildpackage -rfakeroot -b -uc -us + +ls -alh ../*.deb +mkdir -p /artifacts/anastasis/${CI_COMMIT_REF} # Variable comes from CI environment +mv ../*.deb /artifacts/anastasis/${CI_COMMIT_REF}/ diff --git a/contrib/ci/jobs/4-deb-package/version.sh b/contrib/ci/jobs/4-deb-package/version.sh @@ -0,0 +1,19 @@ +#!/bin/sh +set -ex +# This file is in the public domain. +# Determines the current version of our code. + +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/5-deploy-package/config.ini b/contrib/ci/jobs/5-deploy-package/config.ini @@ -0,0 +1,6 @@ +[build] +HALT_ON_FAILURE = True +WARN_ON_FAILURE = True +CONTAINER_BUILD = False +CONTAINER_NAME = nixery.dev/shell/rsync +CONTAINER_ARCH = amd64 diff --git a/contrib/ci/jobs/5-deploy-package/job.sh b/contrib/ci/jobs/5-deploy-package/job.sh @@ -0,0 +1,14 @@ +#!/bin/bash +set -exuo pipefail + +ARTIFACT_PATH="/artifacts/anastasis/${CI_COMMIT_REF}/*.deb" + +RSYNC_HOST="taler.host.internal" +RSYNC_PORT=424242 +RSYNC_PATH="incoming_packages/trixie-taler-ci/" +RSYNC_DEST="rsync://${RSYNC_HOST}/${RSYNC_PATH}" + + +rsync -vP \ + --port ${RSYNC_PORT} \ + ${ARTIFACT_PATH} ${RSYNC_DEST} diff --git a/contrib/ci/jobs/6-db-naming/config.ini b/contrib/ci/jobs/6-db-naming/config.ini @@ -0,0 +1,6 @@ +[build] +HALT_ON_FAILURE = True +WARN_ON_FAILURE = False +CONTAINER_BUILD = True +CONTAINER_NAME = localhost/anastasis +CONTAINER_ARCH = amd64 diff --git a/contrib/ci/jobs/6-db-naming/job.sh b/contrib/ci/jobs/6-db-naming/job.sh @@ -0,0 +1,4 @@ +#!/usr/bin/env bash +set -exuo pipefail + +exec ./contrib/check-db-naming.py