From 0ead2c37efe34278a859edbce40e8bba7bf021fd Mon Sep 17 00:00:00 2001 From: diogo464 Date: Thu, 10 Jul 2025 22:20:34 +0100 Subject: Add GitHub Actions release workflow and build scripts MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Add .github/workflows/release.yml for automated releases on version tags - Add scripts/build-static.sh for building statically linked binaries - Add scripts/prepare-release.sh for preparing release artifacts - Optimize Cargo.toml for smaller binary size (reduced from 4.5MB to 2.9MB) - Add scripts/README.md with usage documentation The workflow automatically builds binaries for Linux (musl) and macOS (Intel/ARM) when a version tag is pushed. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude --- scripts/build-static.sh | 218 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 218 insertions(+) create mode 100755 scripts/build-static.sh (limited to 'scripts/build-static.sh') diff --git a/scripts/build-static.sh b/scripts/build-static.sh new file mode 100755 index 0000000..d835e79 --- /dev/null +++ b/scripts/build-static.sh @@ -0,0 +1,218 @@ +#!/bin/bash +set -euo pipefail + +# Script to build static binaries for Linux and macOS +# Can be run locally or in CI + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +PROJECT_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)" +BINARY_NAME="oar-p2p" + +# Parse command line arguments +TARGET_OS="${1:-all}" # linux, macos, or all +OUTPUT_DIR="${2:-$PROJECT_ROOT/target/release-static}" + +# Colors for output +RED='\033[0;31m' +GREEN='\033[0;32m' +YELLOW='\033[1;33m' +NC='\033[0m' # No Color + +log_info() { + echo -e "${GREEN}[INFO]${NC} $1" +} + +log_error() { + echo -e "${RED}[ERROR]${NC} $1" >&2 +} + +log_warn() { + echo -e "${YELLOW}[WARN]${NC} $1" +} + +# Ensure we're in the project root +cd "$PROJECT_ROOT" + +# Create output directory +mkdir -p "$OUTPUT_DIR" + +# Function to build for Linux with musl +build_linux() { + local arch="${1:-x86_64}" + local target="${arch}-unknown-linux-musl" + + log_info "Building static binary for Linux ($arch)..." + + # Check if target is installed + if ! rustup target list --installed | grep -q "$target"; then + log_info "Installing Rust target: $target" + rustup target add "$target" + fi + + # Set environment variables for static linking + export RUSTFLAGS="-C target-feature=+crt-static" + + # Build the binary + log_info "Running cargo build for $target..." + cargo build --release --target "$target" --target-dir "$PROJECT_ROOT/target" + + # Copy binary to output directory with platform suffix + local output_name="${BINARY_NAME}-linux-${arch}" + cp "target/$target/release/$BINARY_NAME" "$OUTPUT_DIR/$output_name" + + # Strip the binary to reduce size + if command -v strip >/dev/null 2>&1; then + log_info "Stripping binary to reduce size..." + strip "$OUTPUT_DIR/$output_name" + fi + + # Make it executable + chmod +x "$OUTPUT_DIR/$output_name" + + log_info "Linux binary built: $OUTPUT_DIR/$output_name" + + # Print binary info + if command -v file >/dev/null 2>&1; then + file "$OUTPUT_DIR/$output_name" + fi + + # Check if it's actually statically linked + if command -v ldd >/dev/null 2>&1; then + if ldd "$OUTPUT_DIR/$output_name" 2>&1 | grep -q "not a dynamic executable"; then + log_info "✓ Binary is statically linked" + else + log_warn "Binary appears to be dynamically linked" + fi + fi +} + +# Function to build for macOS +build_macos() { + local arch="${1:-x86_64}" + local target + + case "$arch" in + x86_64) + target="x86_64-apple-darwin" + ;; + aarch64|arm64) + target="aarch64-apple-darwin" + ;; + *) + log_error "Unknown macOS architecture: $arch" + return 1 + ;; + esac + + # Check if we're on macOS + if [[ "$OSTYPE" != "darwin"* ]]; then + log_warn "Cannot build macOS binaries on non-macOS systems" + log_info "macOS binaries must be built on macOS or in CI" + return 0 + fi + + log_info "Building binary for macOS ($arch)..." + + # Check if target is installed + if ! rustup target list --installed | grep -q "$target"; then + log_info "Installing Rust target: $target" + rustup target add "$target" + fi + + # macOS doesn't support fully static binaries, but we can minimize dependencies + export RUSTFLAGS="-C target-feature=+crt-static" + + # Build the binary + log_info "Running cargo build for $target..." + cargo build --release --target "$target" --target-dir "$PROJECT_ROOT/target" + + # Copy binary to output directory with platform suffix + local output_name="${BINARY_NAME}-macos-${arch}" + cp "target/$target/release/$BINARY_NAME" "$OUTPUT_DIR/$output_name" + + # Strip the binary to reduce size (macOS strip is different) + if [[ "$OSTYPE" == "darwin"* ]] && command -v strip >/dev/null 2>&1; then + log_info "Stripping binary to reduce size..." + strip "$OUTPUT_DIR/$output_name" + fi + + # Make it executable + chmod +x "$OUTPUT_DIR/$output_name" + + log_info "macOS binary built: $OUTPUT_DIR/$output_name" + + # Print binary info + if command -v file >/dev/null 2>&1; then + file "$OUTPUT_DIR/$output_name" + fi +} + +# Function to check dependencies +check_dependencies() { + local missing_deps=() + + # Check for Rust + if ! command -v cargo >/dev/null 2>&1; then + missing_deps+=("cargo (Rust)") + fi + + # Check for rustup + if ! command -v rustup >/dev/null 2>&1; then + missing_deps+=("rustup") + fi + + if [ ${#missing_deps[@]} -ne 0 ]; then + log_error "Missing required dependencies:" + for dep in "${missing_deps[@]}"; do + echo " - $dep" + done + exit 1 + fi + + # Check Rust version (nightly required based on Cargo.toml) + if ! rustc --version | grep -q "nightly"; then + log_warn "This project requires Rust nightly. Current version:" + rustc --version + log_info "Attempting to use nightly for this build..." + export RUSTUP_TOOLCHAIN=nightly + fi +} + +# Main execution +main() { + log_info "Starting static build process..." + log_info "Output directory: $OUTPUT_DIR" + + # Check dependencies + check_dependencies + + case "$TARGET_OS" in + linux) + build_linux "x86_64" + # Optionally build for ARM64 + # build_linux "aarch64" + ;; + macos|darwin) + # Build for both Intel and Apple Silicon + build_macos "x86_64" + build_macos "aarch64" + ;; + all) + # Build for all platforms + build_linux "x86_64" + build_macos "x86_64" + build_macos "aarch64" + ;; + *) + log_error "Unknown target OS: $TARGET_OS" + echo "Usage: $0 [linux|macos|all] [output_dir]" + exit 1 + ;; + esac + + log_info "Build complete! Binaries available in: $OUTPUT_DIR" + ls -lh "$OUTPUT_DIR" +} + +# Run main function +main \ No newline at end of file -- cgit