mirror of
https://github.com/3proxy/3proxy.git
synced 2026-08-26 09:55:48 +08:00
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.
189 lines
7.6 KiB
YAML
189 lines
7.6 KiB
YAML
name: RPM/DEB build aarch64
|
|
|
|
on:
|
|
release:
|
|
types: [published]
|
|
workflow_dispatch:
|
|
|
|
permissions:
|
|
contents: read
|
|
|
|
jobs:
|
|
ci:
|
|
permissions:
|
|
contents: write
|
|
id-token: write
|
|
attestations: write
|
|
name: "${{ matrix.target }}"
|
|
strategy:
|
|
matrix:
|
|
target:
|
|
- ubuntu-24.04-arm
|
|
runs-on: ${{ matrix.target }}
|
|
steps:
|
|
- uses: actions/checkout@v7
|
|
- name: env
|
|
run: |
|
|
pwd
|
|
echo "RELEASE=$(cat RELEASE)" >> $GITHUB_ENV
|
|
BUILDDATE=$(sed -n 's/^#define BUILDDATE "\(.*\)"$/\1/p' src/version.h)
|
|
[ -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
|
|
run: |
|
|
sudo apt update
|
|
sudo apt install libssl-dev libpam-dev libpcre2-dev rpm build-essential debhelper
|
|
- name: configure rpm env
|
|
run: |
|
|
mkdir ~/debian
|
|
mkdir -p ~/rpmbuild/{BUILD,RPMS,SOURCES,SPECS,SRPMS}
|
|
tar -czf ~/rpmbuild/SOURCES/3proxy-$RELEASE.tar.gz --transform "s,^,3proxy-$RELEASE/," .
|
|
ln -s ~/rpmbuild/SOURCES/3proxy-$RELEASE.tar.gz ~/rpmbuild/SOURCES/$RELEASE.tar.gz
|
|
cp scripts/rh/3proxy.spec ~/rpmbuild/SPECS/3proxy-$RELEASE.spec
|
|
cp ~/rpmbuild/SOURCES/3proxy-$RELEASE.tar.gz ~/debian/3proxy_$RELEASE.orig.tar.gz
|
|
- name: rpmbuild
|
|
run: |
|
|
mkdir -p rpmout
|
|
for EL in 8 9 10; do
|
|
docker run --rm \
|
|
-v "$HOME/rpmbuild/SOURCES/3proxy-$RELEASE.tar.gz:/src.tar.gz:ro" \
|
|
-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
|
|
mkdir -p ~/rpmbuild/{BUILD,RPMS,SOURCES,SPECS,SRPMS}
|
|
cp /src.tar.gz ~/rpmbuild/SOURCES/3proxy-$RELEASE.tar.gz
|
|
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 \
|
|
--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
|
|
for f in rpmout/*.rpm; do
|
|
dist=$(rpm -qp --qf '%{RELEASE}' "$f" | sed 's/^1\.//')
|
|
arch=$(rpm -qp --qf '%{ARCH}' "$f")
|
|
mv "$f" "3proxy-$RELEASE.$dist.$arch.rpm"
|
|
done
|
|
rmdir rpmout
|
|
ls -l *.rpm
|
|
- name: Get artifact rpm
|
|
uses: actions/upload-artifact@v7
|
|
with:
|
|
name: "3proxy-${{ env.RELEASE }}-arm64.rpm"
|
|
path: "*.rpm"
|
|
- name: debbuild
|
|
run: |
|
|
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
|
|
apt-get update
|
|
apt-get install -y build-essential debhelper fakeroot libssl-dev libpcre2-dev libpam0g-dev
|
|
cd /debian
|
|
tar xzf 3proxy_$RELEASE.orig.tar.gz
|
|
cd 3proxy-$RELEASE
|
|
{ echo "3proxy ($RELEASE-$VERSION) buster; urgency=medium"
|
|
echo " "
|
|
echo " *3proxy $RELEASE build"
|
|
echo " "
|
|
echo " -- z3APA3A <3apa3a@3proxy.org> $(date -R -u -d @$SOURCE_DATE_EPOCH)"
|
|
echo ""
|
|
} > debian/changelog
|
|
dpkg-buildpackage'
|
|
cp ~/debian/3proxy_$RELEASE-"$VERSION"_arm64.deb ./3proxy-$RELEASE.arm64.deb
|
|
- name: Get artifact deb
|
|
uses: actions/upload-artifact@v7
|
|
with:
|
|
name: "3proxy-${{ env.RELEASE }}-arm64.deb"
|
|
path: "*.deb"
|
|
- name: Import signing key
|
|
if: github.event_name == 'release'
|
|
env:
|
|
GPG_PRIVATE_KEY: ${{ secrets.GPG_PRIVATE_KEY }}
|
|
GPG_PASSPHRASE: ${{ secrets.GPG_PASSPHRASE }}
|
|
run: |
|
|
if [ -z "$GPG_PRIVATE_KEY" ]; then echo "GPG_PRIVATE_KEY is not set"; exit 1; fi
|
|
mkdir -p ~/.gnupg && chmod 700 ~/.gnupg
|
|
printf 'allow-loopback-pinentry\ndefault-cache-ttl 7200\nmax-cache-ttl 7200\n' > ~/.gnupg/gpg-agent.conf
|
|
gpgconf --kill gpg-agent || true
|
|
printf '%s' "$GPG_PRIVATE_KEY" | gpg --batch --import
|
|
KEYID=$(gpg --list-secret-keys --with-colons | awk -F: '/^sec:/{print $5; exit}')
|
|
echo "GPG_KEYID=$KEYID" >> $GITHUB_ENV
|
|
echo prime > /tmp/prime.txt
|
|
gpg --batch --yes --pinentry-mode loopback --passphrase "$GPG_PASSPHRASE" \
|
|
-u "$KEYID" --detach-sign -o /dev/null /tmp/prime.txt
|
|
rm -f /tmp/prime.txt
|
|
- name: Sign rpm
|
|
if: github.event_name == 'release'
|
|
env:
|
|
GPG_PASSPHRASE: ${{ secrets.GPG_PASSPHRASE }}
|
|
run: |
|
|
GPGBIN=$(command -v gpg)
|
|
if [ -z "$GPGBIN" ]; then echo "gpg not found"; exit 1; fi
|
|
umask 077
|
|
printf '%s' "$GPG_PASSPHRASE" > /tmp/gpgpass
|
|
echo test > /tmp/signtest
|
|
gpg --batch --yes --pinentry-mode loopback --passphrase-file /tmp/gpgpass \
|
|
-u "$GPG_KEYID" --detach-sign -o /tmp/signtest.sig /tmp/signtest
|
|
echo "key can sign"
|
|
{ echo "%_gpg_name $GPG_KEYID"
|
|
echo "%__gpg $GPGBIN"
|
|
echo '%__gpg_sign_cmd %{__gpg} gpg --batch --no-armor --pinentry-mode loopback --passphrase-file /tmp/gpgpass --no-secmem-warning --digest-algo sha256 -u "%{_gpg_name}" -sbo %{__signature_filename} %{__plaintext_filename}'
|
|
} > ~/.rpmmacros
|
|
rpm --addsign *.rpm
|
|
rm -f /tmp/gpgpass /tmp/signtest /tmp/signtest.sig
|
|
for f in *.rpm; do
|
|
sig=$(rpm -qp --qf '%{RSAHEADER:pgpsig}' "$f" 2>/dev/null)
|
|
case "$sig" in ""|"(none)")
|
|
sig=$(rpm -qp --qf '%{DSAHEADER:pgpsig}' "$f" 2>/dev/null) ;;
|
|
esac
|
|
case "$sig" in ""|"(none)")
|
|
echo "$f is not signed"
|
|
echo "--- rpm version ---"; rpm --version
|
|
echo "--- sign cmd ---"; rpm --eval '%{__gpg_sign_cmd}'
|
|
echo "--- secret keys ---"; gpg --list-secret-keys --with-colons | grep -E '^(sec|ssb):' || true
|
|
exit 1 ;;
|
|
esac
|
|
echo "$f: $sig"
|
|
done
|
|
- name: Checksums and detached signatures
|
|
if: github.event_name == 'release'
|
|
env:
|
|
GPG_PASSPHRASE: ${{ secrets.GPG_PASSPHRASE }}
|
|
run: |
|
|
sha256sum *.rpm *.deb > SHA256SUMS-arm64
|
|
for f in *.deb SHA256SUMS-arm64; do
|
|
gpg --batch --yes --pinentry-mode loopback --passphrase "$GPG_PASSPHRASE" \
|
|
-u "$GPG_KEYID" --armor --detach-sign "$f"
|
|
done
|
|
sha256sum -c SHA256SUMS-arm64
|
|
gpg --verify SHA256SUMS-arm64.asc SHA256SUMS-arm64
|
|
- name: Attest build provenance
|
|
if: github.event_name == 'release'
|
|
uses: actions/attest-build-provenance@v2
|
|
with:
|
|
subject-path: |
|
|
*.rpm
|
|
*.deb
|
|
- name: Upload to release
|
|
if: github.event_name == 'release'
|
|
env:
|
|
GH_TOKEN: ${{ github.token }}
|
|
TAG: ${{ github.event.release.tag_name }}
|
|
run: gh release upload "$TAG" *.rpm *.deb *.deb.asc SHA256SUMS-arm64 SHA256SUMS-arm64.asc
|