Skip to content

Make release tarballs reproducible

Since testing .gitlab-ci.yml changes is kinda hard I did the following to test the change:

  • used the CI/CD Editor to lint the changed file
  • tested the pipeline job locally with the following Dockerfile and test-deploy.sh
FROM edbizarro/gitlab-ci-pipeline-php:7.2 AS build

ARG CI_COMMIT_TAG=3.2.5

RUN git clone https://git.ispconfig.org/ispconfig/ispconfig3.git -b ${CI_COMMIT_TAG} build

WORKDIR /var/www/html/build
COPY ./test-deploy.sh /var/www/html
RUN /var/www/html/test-deploy.sh

FROM scratch
COPY --from=build /var/www/html/build/ISPConfig-*.tar.gz /
#!/bin/bash

echo "Building release."
die() {
    echo "failed to" "$@"
    exit 1
}
if [[ "$VER" == "" ]] ; then
    VER="$CI_COMMIT_TAG"
fi
if [[ "$VER" == "" ]] ; then
    VER="3.2dev$(date +%s)"
fi
if [[ "$VER" != "" ]] ; then
    echo "Replacing 3.2dev by $VER"
    sed -i -r 's/3\.2dev/'"${VER}"'/g' install/tpl/config.inc.php.master install/sql/ispconfig3.sql || die "replace version in files"
fi
# if this is a git tag (probably a stable release) then make the tar reproducible by setting the creation time of the archive to the time of the git tag
if [[ "$VER" == "$CI_COMMIT_TAG" ]]; then
    LIBFAKETIME_DEB=libfaketime_0.9.7-3_amd64.deb
    curl -o /tmp/$LIBFAKETIME_DEB http://ftp.de.debian.org/debian/pool/main/f/faketime/$LIBFAKETIME_DEB || die "download libfaketime"
    ( cd /tmp && echo "8bd396800da4e5ae05ef6ba9f4bacb4094c69d7299ba046422991bf0807c744e  $LIBFAKETIME_DEB" > check.sum && shasum -a 256 -c check.sum ) || die "checking consistency of libfaketime"
    ( cd /tmp && dpkg-deb -x $LIBFAKETIME_DEB /tmp/libfaketime )
    # get git tag timestamp (e.g. 2021-08-23T14:40:42+00:00)
    RELEASE_TIMESTAMP="$(git log -1 --format=%aI "$CI_COMMIT_TAG")" || die "setting RELEASE_TIMESTAMP"
    # set the modification time of the files we changed earlier
    touch --no-create -d "$RELEASE_TIMESTAMP" install/tpl/config.inc.php.master install/sql/ispconfig3.sql || die "set modification time of install/tpl/config.inc.php.master install/sql/ispconfig3.sql"
    # freeze system time for the next tar+gz call (timestamp needs to be in format 2021-08-23 14:40:42)
    # see https://github.com/wolfcw/libfaketime for details
    export LD_PRELOAD=/tmp/libfaketime/usr/lib/x86_64-linux-gnu/faketime/libfaketime.so.1
    FAKETIME="$(date -d "$RELEASE_TIMESTAMP" '+%F %T')" || die "setting FAKETIME"
    export FAKETIME
fi
# see https://reproducible-builds.org/docs/archives/ for the tar arguments used
tar --sort=name --owner=0 --group=0 --numeric-owner --format=gnu -cpzf "ISPConfig-${VER}.tar.gz" --exclude "ISPConfig-${VER}.tar.gz" --exclude ".git*" --exclude ".phplint.yml" --transform 's,^\./,ispconfig3_install/,' . || die "create release archive"
unset LD_PRELOAD # unfreeze the system time
echo "Listing tar contents for verification"
#tar -tvf "ISPConfig-${VER}.tar.gz" || die "list release archive contents"
echo "Uploading file to download server"
echo curl -u "${DEPLOY_FTP_USER}:${DEPLOY_FTP_PASSWORD}" -T "ISPConfig-${VER}.tar.gz" "ftp://${DEPLOY_FTP_SERVER}/web/" || die "upload release to FTP server"
if [[ "$VER" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]] ; then
    echo "Stable release ${VER}"
    echo curl -u "${DEPLOY_FTP_USER}:${DEPLOY_FTP_PASSWORD}" -T "ISPConfig-${VER}.tar.gz" "ftp://${DEPLOY_FTP_SERVER}/web/ISPConfig-3-stable.tar.gz" || die "upload stable release to FTP server"
    echo -n "${VER}" > ispconfig3_version.txt || die "create ispconfig3_version.txt"
    echo curl -u "${DEPLOY_FTP_USER}:${DEPLOY_FTP_PASSWORD}" -T ispconfig3_version.txt "ftp://${DEPLOY_FTP_SERVER}/web/" || die "upload ispconfig3_version.txt to FTP server"
else
    echo "Dev release ${VER}"
fi
echo "Download url is https://download.ispconfig.org/ISPConfig-${VER}.tar.gz"
echo "SHA 256 sum for release"
shasum -a 256 "ISPConfig-${VER}.tar.gz"
echo "SHA 512 sum for release"
shasum -a 512 "ISPConfig-${VER}.tar.gz"
#rm "ISPConfig-${VER}.tar.gz"

Building this Dockerfile with

docker buildx build -t currentbuild -o "$(date +%FT%T)" --no-cache --progress plain .

I consistently get

SHA 256 sum for release
a3862f14f2579c256c26dec47f0a9992ccee248be56bbbbe483b377af9bad4b8  ISPConfig-3.2.5.tar.gz
SHA 512 sum for release
7f066c28e41ed9f3c0c61738a660914f5dba51dc83a1e0257e323378c0538835e7afbb6cf62e4e865746a5d95c19321b4a1365d91d6f3d08a69206104068b955  ISPConfig-3.2.5.tar.gz

Closes #6222

Edited by Daniel Jagszent

Merge request reports