#!/usr/bin/env bash # ============================================================================ # Package the compiled MoonBite node binaries for a GitHub Release, so fresh # VPS hosts can pull them via setup-node.sh (MOONBITED_URL / MOONBITECLI_URL). # # Run inside WSL (where the chain is built): # bash deploy/publish-node-binaries.sh # # The fork compiles under the upstream names litecoind / litecoin-cli; this # copies them to the MoonBite names, strips them, and computes checksums. # # Override the build tree or version: # SRC=/root/bigcoin-core/src TAG=node-v1 bash deploy/publish-node-binaries.sh # ============================================================================ set -euo pipefail SRC="${SRC:-/root/bigcoin-core/src}" TAG="${TAG:-node-v1}" REPO="${REPO:-moonbitecoin/moonbite-network}" OUT="${OUT:-$(cd "$(dirname "$0")" && pwd)/dist/$TAG}" DAEMON_SRC="$SRC/litecoind" CLI_SRC="$SRC/litecoin-cli" echo "==> [1/7] Locate compiled binaries" [ -f "$DAEMON_SRC" ] || { echo "ERROR: $DAEMON_SRC not found. Build the chain first, or set SRC=."; exit 1; } [ -f "$CLI_SRC" ] || { echo "ERROR: $CLI_SRC not found. Set SRC= to your build's src/ dir."; exit 1; } echo "==> [2/7] Stage + rename to MoonBite names" mkdir -p "$OUT" install -m 0755 "$DAEMON_SRC" "$OUT/moonbited" install -m 0755 "$CLI_SRC" "$OUT/moonbite-cli" echo "==> [3/7] Strip debug symbols (smaller downloads)" if command -v strip >/dev/null 2>&1; then strip "$OUT/moonbited" "$OUT/moonbite-cli" echo " stripped." else echo " 'strip' not installed (apt-get install binutils) — shipping unstripped." fi echo "==> [4/7] Verify they run + resolve shared libs" "$OUT/moonbited" -version 2>/dev/null | head -1 || echo " (moonbited -version produced no output; continuing)" if ldd "$OUT/moonbited" 2>/dev/null | grep -q "not found"; then echo " WARNING: some shared libs are missing on THIS host; target VPS installs them" echo " via setup-node.sh (libboost/libevent/libdb5.3++/libzmq5/...)." else echo " all shared libs resolve on this host." fi # Seeds (Ubuntu 24.04) load the 22.04 runtime libs from /opt/moonbite/lib via # RUNPATH baked in at link time (LDFLAGS="-Wl,-rpath,/opt/moonbite/lib"). # A binary without it needs patchelf on-host -- warn loudly (doc/linux-runpath.md). if command -v readelf >/dev/null 2>&1 && ! readelf -d "$OUT/moonbited" 2>/dev/null | grep -q "/opt/moonbite/lib"; then echo " WARNING: moonbited has no RUNPATH=/opt/moonbite/lib -- rebuild with" echo " LDFLAGS=\"-Wl,-rpath,/opt/moonbite/lib\" (see deploy/README.md)." fi echo "==> [5/7] Linux miner archive (node + cli + mine.sh + docs; NO wallet)" # docs/ADR-013-miner-distribution-policy.md: the miner ships on its own, the # wallet ships on its own, and the two are never in one archive. This step # assembles moonbite-miner-linux-x86_64.tar.gz from the bare binaries staged # above plus the user-facing scripts in release/miner/. It deliberately has no # way to pick up anything from release/wallet/. REPO_ROOT="$(cd "$(dirname "$0")/.." && pwd)" MINER_TAR="moonbite-miner-linux-x86_64.tar.gz" STAGE_DIR="$(mktemp -d)" mkdir -p "$STAGE_DIR/moonbite-miner" install -m 0755 "$OUT/moonbited" "$STAGE_DIR/moonbite-miner/moonbited" install -m 0755 "$OUT/moonbite-cli" "$STAGE_DIR/moonbite-miner/moonbite-cli" install -m 0755 "$REPO_ROOT/release/miner/mine.sh" "$STAGE_DIR/moonbite-miner/mine.sh" install -m 0644 "$REPO_ROOT/release/miner/README.md" "$STAGE_DIR/moonbite-miner/README.md" install -m 0644 "$REPO_ROOT/release/miner/ANTIVIRUS.md" "$STAGE_DIR/moonbite-miner/ANTIVIRUS.md" # Reproducible tar: fixed owner, mtime, sort order and gzip without a timestamp. ( cd "$STAGE_DIR" && \ tar --sort=name --owner=0 --group=0 --numeric-owner --mtime='1980-01-01 00:00Z' \ -cf - moonbite-miner | gzip -9 -n > "$OUT/$MINER_TAR" ) rm -rf "$STAGE_DIR" echo " $OUT/$MINER_TAR" echo "==> [6/7] Checksums" ( cd "$OUT" && sha256sum moonbited moonbite-cli "$MINER_TAR" | tee SHA256SUMS.txt ) echo "==> [7/7] Sign the manifest (authenticity, not just a co-located hash)" # A checksum sitting next to the binary proves nothing against an origin/release # swap — whoever replaces the binary regenerates the sums in the same motion. # setup-node.sh / setup-seed2.sh verify a minisign signature over the manifest # and pin the public key (deploy/moonbite-release.pub). Sign here if the secret # key is available; otherwise fail LOUD so an unsigned manifest is never quietly # published as if it were trustworthy. See deploy/RELEASE-SIGNING.md. SIGNING_KEY="${SIGNING_KEY:-$(cd "$(dirname "$0")" && pwd)/moonbite-release.key}" SIGNED=0 if command -v minisign >/dev/null 2>&1 && [ -f "$SIGNING_KEY" ]; then # -Sm writes "$OUT/SHA256SUMS.txt.minisig". minisign prompts for the key # passphrase (keep the key offline + passphrase-protected). minisign -Sm "$OUT/SHA256SUMS.txt" -s "$SIGNING_KEY" echo " signed -> $OUT/SHA256SUMS.txt.minisig" SIGNED=1 elif ! command -v minisign >/dev/null 2>&1; then echo " !! minisign not installed — cannot sign. Install it and re-run, or" echo " sign on your offline key box: minisign -Sm \"$OUT/SHA256SUMS.txt\"" else echo " !! no signing key at $SIGNING_KEY — manifest is UNSIGNED." echo " Complete the key ceremony (deploy/RELEASE-SIGNING.md), then sign:" echo " minisign -Sm \"$OUT/SHA256SUMS.txt\" -s /path/to/moonbite-release.key" fi # Build the release/install snippets, including the .minisig only when we have it. if [ "$SIGNED" = "1" ]; then _SIG_ASSET=" \"$OUT/SHA256SUMS.txt.minisig\" \\" _SUMS_URL_LINE=" MOONBITE_SUMS_URL=https://github.com/$REPO/releases/download/$TAG/SHA256SUMS.txt \\" _VERIFY_NOTE="Verify authenticity with minisign against deploy/moonbite-release.pub, then sha256 with SHA256SUMS.txt." else _SIG_ASSET=" # (no SHA256SUMS.txt.minisig — sign the manifest first; see RELEASE-SIGNING.md)" _SUMS_URL_LINE=" # MOONBITE_SUMS_URL=.../SHA256SUMS.txt <-- add once the manifest is SIGNED (RELEASE-SIGNING.md)" _VERIFY_NOTE="WARNING: manifest is UNSIGNED. Do not advertise these as verifiable until signed (RELEASE-SIGNING.md)." fi cat <