From 634edd83bb9ba0cc2c661fb8c6a56509c3573355 Mon Sep 17 00:00:00 2001 From: Patrick Spek Date: Sun, 29 Mar 2020 16:33:23 +0200 Subject: Make reproducible tarballs with dist --- lib/actions/dist.bash | 34 ++++++++++++++++++++++++++++++---- lib/util.bash | 16 ++++++++++++++++ 2 files changed, 46 insertions(+), 4 deletions(-) diff --git a/lib/actions/dist.bash b/lib/actions/dist.bash index 727cb53..137576d 100644 --- a/lib/actions/dist.bash +++ b/lib/actions/dist.bash @@ -13,9 +13,25 @@ RSTAR_DEPS_BIN+=( ) action() { - local version="${1:-$(date +%Y.%m)}" + local LC_ALL + local SOURCE_DATE_EPOCH + local basename + local tarball + local version + + # Prepare environment for a reproducible tarball + LC_ALL=C.UTF-8 + SOURCE_DATE_EPOCH="$(git log -1 --pretty=format:%at)" + + # Set a version if none was specified explicitly + version="${1:-$(datetime %Y.%m)}" WORKDIR="$BASEDIR/tmp/rakudo-star-$version" + debug "SOURCE_DATE_EPOCH set to $SOURCE_DATE_EPOCH" + + export LC_ALL + export SOURCE_DATE_EPOCH + info "Creating distribution contents at $WORKDIR" chgdir "$BASEDIR" @@ -31,17 +47,27 @@ action() { # Add a MANIFEST.txt chgdir "$WORKDIR" - find . > MANIFEST.txt + touch MANIFEST.txt + find . -type f | sed 's|^./||' | sort > MANIFEST.txt # Tar it all up into a distribution tarball info "Creating tarball out of $WORKDIR" - local tarball="$BASEDIR/dist/rakudo-star-$version.tar.gz" + basename="rakudo-star-$version" + tarball="$BASEDIR/dist/$basename.tar.gz" mkdir -p -- "$(dirname "$tarball")" chgdir "$BASEDIR/tmp" - tar czf "$tarball" "rakudo-star-$version" + awk '{ print "'"$basename"'/"$0 }' "$WORKDIR/MANIFEST.txt" \ + | tar -c -T - \ + --mtime @"$SOURCE_DATE_EPOCH" \ + --mode=go=rX,u+rw,a-s \ + --format=gnu \ + --numeric-owner --owner=0 --group=0 \ + | gzip -9cn \ + > "$tarball" + touch -d"$(datetime)" "$tarball" chgdir "$(dirname "$tarball")" diff --git a/lib/util.bash b/lib/util.bash index 97131c3..a387d8b 100644 --- a/lib/util.bash +++ b/lib/util.bash @@ -33,6 +33,22 @@ config_etc_kv() { printf "%s" "$value" } +# Create a datetime stamp. This is a wrapper around the date utility, ensuring +# that the date being formatted is always in UTC and respect SOURCE_DATE_EPOCH, +# if it is set. +datetime() { + local date_opts + + # Apply SOURCE_DATE_EPOCH as the date to base off of. + if [[ $SOURCE_DATE_EPOCH ]] + then + date_opts+=("-d@$SOURCE_DATE_EPOCH") + date_opts+=("-u") + fi + + date "${date_opts[@]}" +"${1:-%FT%T}" +} + # Log a message as error, and exit the program. This is intended for serious # issues that prevent the script from running correctly. The exit code can be # specified with -i, or will default to 1. -- cgit v1.1