#!/usr/bin/env bash # Build a Debian/Ubuntu package with dpkg-deb only (no debhelper needed). # scripts/build-deb.sh build release binary for the host and package it # scripts/build-deb.sh --no-build package an existing target/release/active-push # TARGET=aarch64-unknown-linux-gnu scripts/build-deb.sh (cross toolchain must be installed) set -euo pipefail ROOT="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")/.." && pwd)" cd "$ROOT" fail() { printf 'error: %s\n' "$*" >&2; exit 1; } command -v dpkg-deb >/dev/null || fail "dpkg-deb is required (apt install dpkg)" VERSION="$(sed -n 's/^version = "\(.*\)"/\1/p' Cargo.toml | head -1)" REVISION="${DEB_REVISION:-1}" BUILD=1 [[ "${1:-}" == "--no-build" ]] && BUILD=0 HOST_ARCH="$(uname -m)" # Portable builds: link against an old glibc with cargo-zigbuild when available # (pip install ziglang && cargo install cargo-zigbuild). GLIBC_TARGET=0 disables it. GLIBC_TARGET="${GLIBC_TARGET:-2.31}" TARGET="${TARGET:-}" ZIG=0 if [[ -z "$TARGET" && "$GLIBC_TARGET" != "0" ]] && command -v cargo-zigbuild >/dev/null 2>&1; then TARGET="${HOST_ARCH}-unknown-linux-gnu" ZIG=1 fi case "${TARGET:-$HOST_ARCH}" in x86_64*) ARCH=amd64 ;; aarch64*) ARCH=arm64 ;; armv7*) ARCH=armhf ;; *) ARCH="$(dpkg --print-architecture 2>/dev/null || echo amd64)" ;; esac if [[ -n "${BIN:-}" ]]; then : elif [[ -n "$TARGET" ]]; then BIN="${CARGO_TARGET_DIR:-target}/$TARGET/release/active-push" else BIN="${CARGO_TARGET_DIR:-target}/release/active-push" fi if [[ $BUILD == 1 ]]; then printf 'Building release binary %s...\n' "$VERSION" if [[ $ZIG == 1 ]]; then cargo zigbuild --release --locked --target "$TARGET.$GLIBC_TARGET" elif [[ -n "$TARGET" ]]; then cargo build --release --locked --target "$TARGET" else cargo build --release --locked fi fi [[ -x "$BIN" ]] || fail "binary $BIN not found" # minimal libc6 version from the binary's versioned symbols LIBC_MIN="2.31" if command -v objdump >/dev/null; then v="$(objdump -T "$BIN" 2>/dev/null | grep -o 'GLIBC_[0-9.]*' | sed 's/GLIBC_//' | sort -V | tail -1)" [[ -n "$v" ]] && LIBC_MIN="$v" fi printf 'Binary %s requires glibc >= %s\n' "$BIN" "$LIBC_MIN" PKG="active-push_${VERSION}-${REVISION}_${ARCH}" STAGE="$(mktemp -d)" trap 'rm -rf "$STAGE"' EXIT D="$STAGE/$PKG" install -d -m 0755 "$D/DEBIAN" "$D/usr/bin" "$D/lib/systemd/system" "$D/etc/active-push" \ "$D/usr/share/doc/active-push/examples" "$D/usr/share/active-push" install -m 0755 "$BIN" "$D/usr/bin/active-push" strip --strip-unneeded "$D/usr/bin/active-push" 2>/dev/null || true install -m 0644 deploy/active-push.service "$D/lib/systemd/system/active-push.service" install -m 0640 deploy/environment.example "$D/etc/active-push/environment" install -m 0644 deploy/nginx-active-push.conf "$D/usr/share/doc/active-push/examples/nginx-active-push.conf" install -m 0644 deploy/active-push-autodiscover.conf "$D/usr/share/doc/active-push/examples/active-push-autodiscover.conf" install -m 0644 README.md "$D/usr/share/doc/active-push/README.md" for f in docs/*.md; do install -m 0644 "$f" "$D/usr/share/doc/active-push/"; done install -m 0755 tools/zpush-import.py "$D/usr/share/active-push/zpush-import.py" install -m 0644 LICENSE "$D/usr/share/doc/active-push/copyright" gzip -9n -c CHANGELOG.md > "$D/usr/share/doc/active-push/changelog.gz" SIZE="$(du -sk "$D" | cut -f1)" cat > "$D/DEBIAN/control" < Installed-Size: ${SIZE} Depends: libc6 (>= ${LIBC_MIN}), adduser, ca-certificates Recommends: nginx | apache2 | rust-proxy Suggests: dovecot-imapd, postfix, radicale Conflicts: z-push-common Description: Exchange ActiveSync server for IMAP/SMTP, CalDAV and CardDAV ActivePush lets phones and Outlook synchronise mail, calendars, tasks and contacts over Exchange ActiveSync (2.5-14.1) with standard IMAP/SMTP, CalDAV and CardDAV servers. It is a Rust rewrite of Z-Push with a built-in administration panel (devices, remote wipe, policies, live statistics). EOF # Z-Push can be installed side by side; drop the Conflicts line if you rely on that. sed -i '/^Conflicts: z-push-common/d' "$D/DEBIAN/control" echo "/etc/active-push/environment" > "$D/DEBIAN/conffiles" cat > "$D/DEBIAN/postinst" <<'EOF' #!/bin/sh set -e case "$1" in configure) if ! getent group active-push >/dev/null; then addgroup --system active-push >/dev/null; fi if ! getent passwd active-push >/dev/null; then adduser --system --ingroup active-push --home /var/lib/active-push --no-create-home \ --shell /usr/sbin/nologin --gecos "ActivePush" active-push >/dev/null fi install -d -o active-push -g active-push -m 0700 /var/lib/active-push chown root:active-push /etc/active-push /etc/active-push/environment chmod 0750 /etc/active-push chmod 0640 /etc/active-push/environment if [ -d /run/systemd/system ]; then systemctl daemon-reload >/dev/null 2>&1 || true if [ -z "$2" ]; then systemctl enable --now active-push.service >/dev/null 2>&1 || true echo "" echo "ActivePush installed and started." echo " ActiveSync listener : 127.0.0.1:8081 (proxy /Microsoft-Server-ActiveSync and autodiscover here)" echo " Admin panel : http://127.0.0.1:9091/ (ssh -L 9091:127.0.0.1:9091 server)" echo " First administrator : sudo -u active-push active-push admin setup-token" echo " nginx example : /usr/share/doc/active-push/examples/nginx-active-push.conf" echo " Import Z-Push config: python3 /usr/share/active-push/zpush-import.py /usr/share/z-push > zpush.json" echo " sudo -u active-push active-push config apply zpush.json" echo "" else systemctl try-restart active-push.service >/dev/null 2>&1 || true fi fi ;; esac exit 0 EOF cat > "$D/DEBIAN/prerm" <<'EOF' #!/bin/sh set -e if [ -d /run/systemd/system ] && [ "$1" = remove ]; then systemctl disable --now active-push.service >/dev/null 2>&1 || true fi exit 0 EOF cat > "$D/DEBIAN/postrm" <<'EOF' #!/bin/sh set -e if [ "$1" = purge ]; then rm -rf /etc/active-push # device states, statistics and settings rm -rf /var/lib/active-push if getent passwd active-push >/dev/null; then deluser --system active-push >/dev/null 2>&1 || true; fi if getent group active-push >/dev/null; then delgroup --system active-push >/dev/null 2>&1 || true; fi fi if [ -d /run/systemd/system ]; then systemctl daemon-reload >/dev/null 2>&1 || true; fi exit 0 EOF chmod 0755 "$D/DEBIAN/postinst" "$D/DEBIAN/prerm" "$D/DEBIAN/postrm" mkdir -p dist dpkg-deb --root-owner-group -Zxz --build "$D" "dist/$PKG.deb" >/dev/null sha256sum "dist/$PKG.deb" > "dist/$PKG.deb.sha256" printf 'Package: dist/%s.deb\n' "$PKG" dpkg-deb --info "dist/$PKG.deb" | sed -n '1,12p'