#!/usr/bin/env bash # # 从 release.sh 的交叉编译产物构建原生安装包: # - linux amd64/arm64 → .deb # - linux amd64/arm64 → .rpm # - windows amd64/arm64 → NSIS .exe 安装器 # - darwin amd64/arm64 → macOS .pkg # # 用法: build_installers.sh [arch...] # arch 默认: linux amd64 arm64 # # 在 release.sh 流程内被调用;依赖 dist/artifacts//bin/-/ 下的二进制。 set -euo pipefail VERSION="${1:-0.1.0}" VERSION="${VERSION#v}" ROOT="$(cd "$(dirname "$0")/.." && pwd)" OUT="$ROOT/dist/artifacts/$VERSION" PKG="$ROOT/packaging" # 工具检测(缺工具则给出明确提示后跳过该平台) have() { command -v "$1" >/dev/null 2>&1; } build_deb() { local arch="$1" key="$2" bindir bindir="$OUT/bin/linux-$arch" [ -x "$bindir/webui4frpc" ] || { echo " ! 缺二进制 linux-$arch,跳过 deb"; return; } local deb=/tmp/w4f-deb-build; rm -rf "$deb" mkdir -p "$deb/DEBIAN" "$deb/usr/bin" "$deb/etc/webui4frpc" \ "$deb/lib/systemd/system" "$deb/usr/share/doc/webui4frpc" # control cat > "$deb/DEBIAN/control" < Description: visual frpc controller with token-ring cluster A web UI to manage FRP forwards across a cluster of nodes. Single statically-linked binary with an embedded Vue frontend. Includes a token-ring based cluster for distributed forward management, NIC network load sampling, and audit-log CSV export. Homepage: https://gitcode.com/JianFeeeee/webui4frpc EOF install -m 0755 "$bindir/webui4frpc" "$deb/usr/bin/webui4frpc" install -m 0644 "$PKG/common/webui4frpc.service" "$deb/lib/systemd/system/webui4frpc.service" install -m 0640 "$PKG/common/webui4frpc.env" "$deb/etc/webui4frpc/webui4frpc.env" install -m 0644 "$ROOT/README.md" "$deb/usr/share/doc/webui4frpc/README.md" cat > "$deb/usr/share/doc/webui4frpc/copyright" <<'EOF' webui4frpc - visual frpc controller Copyright (C) 2026 JianFeeeee SPDX-License-Identifier: MIT EOF install -m 0755 "$PKG/deb/postinst" "$deb/DEBIAN/postinst" install -m 0755 "$PKG/deb/prerm" "$deb/DEBIAN/prerm" install -m 0755 "$PKG/deb/postrm" "$deb/DEBIAN/postrm" echo "/etc/webui4frpc/webui4frpc.env" > "$deb/DEBIAN/conffiles" ( cd "$deb" && find usr etc lib -type f -exec md5sum {} \; > DEBIAN/md5sums ) dpkg-deb -b --root-owner-group "$deb" "$OUT/webui4frpc-${VERSION}-linux-${arch}.deb" >/dev/null echo " ✔ .deb linux/$arch" } build_rpm() { local arch="$1" rarch key="$2" bindir case "$arch" in amd64) rarch=x86_64;; arm64) rarch=aarch64;; *) return;; esac bindir="$OUT/bin/linux-$arch" [ -x "$bindir/webui4frpc" ] || { echo " ! 缺二进制 linux-$arch,跳过 rpm"; return; } local R=/tmp/w4f-rpmbuild; rm -rf "$R"; mkdir -p "$R"/{BUILD,RPMS,SPECS,SOURCES} rpmbuild -bb "$PKG/rpm/webui4frpc.spec" --nodeps --target "$rarch" \ --define "_topdir $R" \ --define "_w4f_version $VERSION" \ --define "_w4f_arch $rarch" \ --define "_w4f_bin $bindir/webui4frpc" \ --define "_w4f_service $PKG/common/webui4frpc.service" \ --define "_w4f_env $PKG/common/webui4frpc.env" \ --define "_w4f_readme $ROOT/README.md" \ --define "_unitdir /usr/lib/systemd/system" \ --define "_sharedstatedir /var/lib" >/tmp/w4f-rpm.log 2>&1 || true cp "$R"/RPMS/$rarch/*.rpm "$OUT/webui4frpc-${VERSION}-linux-${rarch}.rpm" 2>/dev/null \ && echo " ✔ .rpm linux/$rarch" || { echo " ! rpm 失败: $(tail -3 /tmp/w4f-rpm.log)"; } } build_nsis() { local arch="$1" key="$2" bindir bindir="$OUT/bin/windows-$arch" [ -f "$bindir/webui4frpc.exe" ] || { echo " ! 缺二进制 windows-$arch,跳过 NSIS"; return; } [ -f "$PKG/windows/LICENSE.txt" ] || { echo " ! 缺 $PKG/windows/LICENSE.txt"; return; } cp -f "$ROOT/README.md" "$PKG/windows/README.md" makensis "-DVERSION=$VERSION" "-DARCH=$arch" \ "-DBINSRC=$bindir/webui4frpc.exe" \ "-DOUTFILE=$OUT/webui4frpc-${VERSION}-windows-${arch}-setup.exe" \ "$PKG/windows/webui4frpc.nsi" >/tmp/w4f-nsis.log 2>&1 \ && echo " ✔ NSIS setup.exe windows/$arch" \ || { echo " ! NSIS 失败: $(tail -4 /tmp/w4f-nsis.log)"; } } build_pkg() { local arch="$1" key="$2" bindir bindir="$OUT/bin/darwin-$arch" [ -x "$bindir/webui4frpc" ] || { echo " ! 缺二进制 darwin-$arch,跳过 pkg"; return; } "$PKG/macos/build_pkg.sh" "$VERSION" "$arch" \ "$bindir/webui4frpc" \ "$OUT/webui4frpc-${VERSION}-darwin-${arch}.pkg" >/dev/null \ && echo " ✔ .pkg darwin/$arch" \ || echo " ! macOS pkg 失败 darwin/$arch" } ARCHES=("${@:2}") [ ${#ARCHES[@]} -eq 0 ] && ARCHES=(amd64 arm64) echo "==> 原生安装包 (v$VERSION):" for arch in "${ARCHES[@]}"; do key="linux-$arch" if have dpkg-deb; then build_deb "$arch" "$key"; else echo " . dpkg-deb 不可用,跳过 deb"; fi if have rpmbuild; then build_rpm "$arch" "$key"; else echo " . rpmbuild 不可用,跳过 rpm"; fi done if have makensis; then for arch in "${ARCHES[@]}"; do build_nsis "$arch" "windows-$arch"; done else echo " . makensis 不可用,跳过 windows setup.exe" fi if have xar && have mkbom && have cpio; then for arch in "${ARCHES[@]}"; do build_pkg "$arch" "darwin-$arch"; done else echo " . xar/mkbom 不可用,跳过 macOS pkg" fi echo "" echo "==> 安装包产物:" ls -lh "$OUT"/*.deb "$OUT"/*.rpm "$OUT"/*-setup.exe "$OUT"/*.pkg 2>/dev/null || true