From 4b48311d829d4b7437574f4b022028ba55a8c3fe Mon Sep 17 00:00:00 2001 From: Vladimir Dubrovin <3proxy@3proxy.ru> Date: Sat, 22 Aug 2026 13:53:29 +0300 Subject: [PATCH] Derive all build timestamps from BUILDDATE The build date stored in version.h is now the single time source for a release. Each package workflow converts it to SOURCE_DATE_EPOCH and passes that into the build containers, the debian changelog entry is stamped from it rather than from the build clock, and rpmbuild is told to use it as the build time and to clamp file mtimes to it. rpm also records the build host, which is a container id and therefore differs on every run, so pin it as well - otherwise the timestamps alone do not make the package reproducible. Rebuilding the same commit now produces byte identical packages, verified for both formats by building twice and comparing checksums. In the version workflow the clock is read exactly once, when a new build date is minted. YEAR3PROXY is derived from the build date instead of being read separately, so the two cannot straddle a year boundary and a re-run in a later year no longer rewrites version.h. --- .github/workflows/build-rpm-arm64.yml | 14 +++++++++++--- .github/workflows/build-rpm-armhf.yml | 7 +++++-- .github/workflows/build-rpm-x86-64.yml | 14 +++++++++++--- .github/workflows/update-version.yml | 7 ++++--- 4 files changed, 31 insertions(+), 11 deletions(-) diff --git a/.github/workflows/build-rpm-arm64.yml b/.github/workflows/build-rpm-arm64.yml index 6a87ae3..7a1d352 100644 --- a/.github/workflows/build-rpm-arm64.yml +++ b/.github/workflows/build-rpm-arm64.yml @@ -27,8 +27,10 @@ jobs: pwd echo "RELEASE=$(cat RELEASE)" >> $GITHUB_ENV BUILDDATE=$(sed -n 's/^#define BUILDDATE "\(.*\)"$/\1/p' src/version.h) - [ -n "$BUILDDATE" ] || BUILDDATE=$(date +%y%m%d%H%M%S) + [ -n "$BUILDDATE" ] || BUILDDATE=$(date -u +%y%m%d%H%M%S) echo "VERSION=$BUILDDATE" >> $GITHUB_ENV + SOURCE_DATE_EPOCH=$(date -u -d "20${BUILDDATE:0:2}-${BUILDDATE:2:2}-${BUILDDATE:4:2} ${BUILDDATE:6:2}:${BUILDDATE:8:2}:${BUILDDATE:10:2}" +%s) + echo "SOURCE_DATE_EPOCH=$SOURCE_DATE_EPOCH" >> $GITHUB_ENV - name: echo env run: echo "release $RELEASE version $VERSION" - name: Linux libraries @@ -52,6 +54,7 @@ jobs: -v "$PWD/scripts/rh/3proxy.spec:/3proxy.spec:ro" \ -v "$PWD/rpmout:/out" \ -e RELEASE="$RELEASE" -e HOSTUID="$(id -u)" -e HOSTGID="$(id -g)" \ + -e SOURCE_DATE_EPOCH="$SOURCE_DATE_EPOCH" \ "almalinux:$EL" bash -c ' set -e dnf -y install rpm-build gcc make openssl-devel pcre2-devel pam-devel tar gzip @@ -60,7 +63,11 @@ jobs: ln -sf ~/rpmbuild/SOURCES/3proxy-$RELEASE.tar.gz ~/rpmbuild/SOURCES/$RELEASE.tar.gz cp /3proxy.spec ~/rpmbuild/SPECS/3proxy-$RELEASE.spec cd ~/rpmbuild/SPECS - rpmbuild -ba 3proxy-$RELEASE.spec + rpmbuild -ba \ + --define "use_source_date_epoch_as_buildtime 1" \ + --define "clamp_mtime_to_source_date_epoch 1" \ + --define "_buildhost 3proxy.org" \ + 3proxy-$RELEASE.spec cp ~/rpmbuild/RPMS/*/*.rpm /out/ chown "$HOSTUID:$HOSTGID" /out/*.rpm || chmod 0666 /out/*.rpm' done @@ -81,6 +88,7 @@ jobs: docker run --rm \ -v "$HOME/debian:/debian" \ -e RELEASE="$RELEASE" -e VERSION="$VERSION" \ + -e SOURCE_DATE_EPOCH="$SOURCE_DATE_EPOCH" \ ubuntu:22.04 bash -c ' set -e export DEBIAN_FRONTEND=noninteractive @@ -93,7 +101,7 @@ jobs: echo " " echo " *3proxy $RELEASE build" echo " " - echo " -- z3APA3A <3apa3a@3proxy.org> $(date "+%a, %d %b %Y %H:%M:%S %z")" + echo " -- z3APA3A <3apa3a@3proxy.org> $(date -R -u -d @$SOURCE_DATE_EPOCH)" echo "" } > debian/changelog dpkg-buildpackage' diff --git a/.github/workflows/build-rpm-armhf.yml b/.github/workflows/build-rpm-armhf.yml index fbac061..6407584 100644 --- a/.github/workflows/build-rpm-armhf.yml +++ b/.github/workflows/build-rpm-armhf.yml @@ -27,8 +27,10 @@ jobs: pwd echo "RELEASE=$(cat RELEASE)" >> $GITHUB_ENV BUILDDATE=$(sed -n 's/^#define BUILDDATE "\(.*\)"$/\1/p' src/version.h) - [ -n "$BUILDDATE" ] || BUILDDATE=$(date +%y%m%d%H%M%S) + [ -n "$BUILDDATE" ] || BUILDDATE=$(date -u +%y%m%d%H%M%S) echo "VERSION=$BUILDDATE" >> $GITHUB_ENV + SOURCE_DATE_EPOCH=$(date -u -d "20${BUILDDATE:0:2}-${BUILDDATE:2:2}-${BUILDDATE:4:2} ${BUILDDATE:6:2}:${BUILDDATE:8:2}:${BUILDDATE:10:2}" +%s) + echo "SOURCE_DATE_EPOCH=$SOURCE_DATE_EPOCH" >> $GITHUB_ENV - name: configure deb env run: | mkdir ~/debian @@ -42,6 +44,7 @@ jobs: docker run --rm \ -v "$HOME/debian:/debian" \ -e RELEASE="$RELEASE" -e VERSION="$VERSION" \ + -e SOURCE_DATE_EPOCH="$SOURCE_DATE_EPOCH" \ ubuntu:22.04 bash -c ' set -e export DEBIAN_FRONTEND=noninteractive @@ -60,7 +63,7 @@ jobs: echo " " echo " *3proxy $RELEASE build" echo " " - echo " -- z3APA3A <3apa3a@3proxy.org> $(date "+%a, %d %b %Y %H:%M:%S %z")" + echo " -- z3APA3A <3apa3a@3proxy.org> $(date -R -u -d @$SOURCE_DATE_EPOCH)" echo "" } > debian/changelog export PATH=/usr/arm-linux-gnueabihf/bin:$PATH diff --git a/.github/workflows/build-rpm-x86-64.yml b/.github/workflows/build-rpm-x86-64.yml index a8336bd..16903d1 100644 --- a/.github/workflows/build-rpm-x86-64.yml +++ b/.github/workflows/build-rpm-x86-64.yml @@ -27,8 +27,10 @@ jobs: pwd echo "RELEASE=$(cat RELEASE)" >> $GITHUB_ENV BUILDDATE=$(sed -n 's/^#define BUILDDATE "\(.*\)"$/\1/p' src/version.h) - [ -n "$BUILDDATE" ] || BUILDDATE=$(date +%y%m%d%H%M%S) + [ -n "$BUILDDATE" ] || BUILDDATE=$(date -u +%y%m%d%H%M%S) echo "VERSION=$BUILDDATE" >> $GITHUB_ENV + SOURCE_DATE_EPOCH=$(date -u -d "20${BUILDDATE:0:2}-${BUILDDATE:2:2}-${BUILDDATE:4:2} ${BUILDDATE:6:2}:${BUILDDATE:8:2}:${BUILDDATE:10:2}" +%s) + echo "SOURCE_DATE_EPOCH=$SOURCE_DATE_EPOCH" >> $GITHUB_ENV - name: echo env run: echo "release $RELEASE version $VERSION" - name: Linux libraries @@ -52,6 +54,7 @@ jobs: -v "$PWD/scripts/rh/3proxy.spec:/3proxy.spec:ro" \ -v "$PWD/rpmout:/out" \ -e RELEASE="$RELEASE" -e HOSTUID="$(id -u)" -e HOSTGID="$(id -g)" \ + -e SOURCE_DATE_EPOCH="$SOURCE_DATE_EPOCH" \ "almalinux:$EL" bash -c ' set -e dnf -y install rpm-build gcc make openssl-devel pcre2-devel pam-devel tar gzip @@ -60,7 +63,11 @@ jobs: ln -sf ~/rpmbuild/SOURCES/3proxy-$RELEASE.tar.gz ~/rpmbuild/SOURCES/$RELEASE.tar.gz cp /3proxy.spec ~/rpmbuild/SPECS/3proxy-$RELEASE.spec cd ~/rpmbuild/SPECS - rpmbuild -ba 3proxy-$RELEASE.spec + rpmbuild -ba \ + --define "use_source_date_epoch_as_buildtime 1" \ + --define "clamp_mtime_to_source_date_epoch 1" \ + --define "_buildhost 3proxy.org" \ + 3proxy-$RELEASE.spec cp ~/rpmbuild/RPMS/*/*.rpm /out/ chown "$HOSTUID:$HOSTGID" /out/*.rpm || chmod 0666 /out/*.rpm' done @@ -81,6 +88,7 @@ jobs: docker run --rm \ -v "$HOME/debian:/debian" \ -e RELEASE="$RELEASE" -e VERSION="$VERSION" \ + -e SOURCE_DATE_EPOCH="$SOURCE_DATE_EPOCH" \ ubuntu:22.04 bash -c ' set -e export DEBIAN_FRONTEND=noninteractive @@ -93,7 +101,7 @@ jobs: echo " " echo " *3proxy $RELEASE build" echo " " - echo " -- z3APA3A <3apa3a@3proxy.org> $(date "+%a, %d %b %Y %H:%M:%S %z")" + echo " -- z3APA3A <3apa3a@3proxy.org> $(date -R -u -d @$SOURCE_DATE_EPOCH)" echo "" } > debian/changelog dpkg-buildpackage' diff --git a/.github/workflows/update-version.yml b/.github/workflows/update-version.yml index 8d1939f..c2f4967 100644 --- a/.github/workflows/update-version.yml +++ b/.github/workflows/update-version.yml @@ -21,7 +21,6 @@ jobs: run: | RELEASE=$(tr -d ' \t\r\n' < RELEASE) if [ -z "$RELEASE" ]; then echo "RELEASE is empty"; exit 1; fi - YEAR=$(date +%Y) MAJOR=$(echo "$RELEASE" | cut -d . -f 1) SUBMAJOR=$(echo "$RELEASE" | cut -d . -f 2) MINOR=$(echo "$RELEASE" | cut -d . -f 3) @@ -38,9 +37,11 @@ jobs: if [ "$OLDRELEASE" = "$RELEASE" ] && [ -n "$OLDBUILDDATE" ]; then BUILDDATE="$OLDBUILDDATE" else - BUILDDATE=$(date +%y%m%d%H%M%S) + BUILDDATE=$(date -u +%y%m%d%H%M%S) fi echo "release $RELEASE -> $MAJOR $SUBMAJOR $MINOR $SUBMINOR, build date $BUILDDATE" + SOURCE_DATE_EPOCH=$(date -u -d "20${BUILDDATE:0:2}-${BUILDDATE:2:2}-${BUILDDATE:4:2} ${BUILDDATE:6:2}:${BUILDDATE:8:2}:${BUILDDATE:10:2}" +%s) + YEAR=$(date -u -d @$SOURCE_DATE_EPOCH +%Y) DEBVERSION=$(head -1 debian/changelog | cut -d "(" -f 2 | cut -d ")" -f 1) if [ "$DEBVERSION" != "$RELEASE-1" ]; then @@ -49,7 +50,7 @@ jobs: echo "" echo " *3proxy $RELEASE initial build" echo "" - echo " -- z3APA3A <3apa3a@3proxy.org> $(date -R)" + echo " -- z3APA3A <3apa3a@3proxy.org> $(date -R -u -d @$SOURCE_DATE_EPOCH)" echo "" cat debian/changelog.old } > debian/changelog