diff options
| author | diogo464 <[email protected]> | 2025-07-10 22:20:34 +0100 |
|---|---|---|
| committer | diogo464 <[email protected]> | 2025-07-10 22:20:34 +0100 |
| commit | 0ead2c37efe34278a859edbce40e8bba7bf021fd (patch) | |
| tree | aaf17c0a8bd10b596962ae52f25e8bcb0e62dea8 | |
| parent | 3b0721341c46922b5c1c94bdbbf37099424ee5bc (diff) | |
Add GitHub Actions release workflow and build scripts
- 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 <[email protected]>
| -rw-r--r-- | .github/workflows/release.yml | 169 | ||||
| -rw-r--r-- | Cargo.toml | 13 | ||||
| -rw-r--r-- | scripts/README.md | 56 | ||||
| -rwxr-xr-x | scripts/build-static.sh | 218 | ||||
| -rwxr-xr-x | scripts/prepare-release.sh | 206 |
5 files changed, 662 insertions, 0 deletions
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..4a040e7 --- /dev/null +++ b/.github/workflows/release.yml | |||
| @@ -0,0 +1,169 @@ | |||
| 1 | name: Release | ||
| 2 | |||
| 3 | on: | ||
| 4 | push: | ||
| 5 | tags: | ||
| 6 | - 'v*' | ||
| 7 | |||
| 8 | permissions: | ||
| 9 | contents: write | ||
| 10 | |||
| 11 | jobs: | ||
| 12 | build: | ||
| 13 | name: Build Release Binaries | ||
| 14 | runs-on: ${{ matrix.os }} | ||
| 15 | strategy: | ||
| 16 | matrix: | ||
| 17 | include: | ||
| 18 | # Linux builds | ||
| 19 | - os: ubuntu-latest | ||
| 20 | target: x86_64-unknown-linux-musl | ||
| 21 | platform: linux-x86_64 | ||
| 22 | |||
| 23 | # macOS builds | ||
| 24 | - os: macos-latest | ||
| 25 | target: x86_64-apple-darwin | ||
| 26 | platform: macos-x86_64 | ||
| 27 | |||
| 28 | - os: macos-latest | ||
| 29 | target: aarch64-apple-darwin | ||
| 30 | platform: macos-aarch64 | ||
| 31 | |||
| 32 | steps: | ||
| 33 | - name: Checkout code | ||
| 34 | uses: actions/checkout@v4 | ||
| 35 | |||
| 36 | - name: Install Rust toolchain | ||
| 37 | uses: dtolnay/rust-toolchain@nightly | ||
| 38 | with: | ||
| 39 | targets: ${{ matrix.target }} | ||
| 40 | |||
| 41 | - name: Install dependencies (Linux) | ||
| 42 | if: runner.os == 'Linux' | ||
| 43 | run: | | ||
| 44 | sudo apt-get update | ||
| 45 | sudo apt-get install -y musl-tools | ||
| 46 | |||
| 47 | - name: Cache cargo registry | ||
| 48 | uses: actions/cache@v3 | ||
| 49 | with: | ||
| 50 | path: ~/.cargo/registry | ||
| 51 | key: ${{ runner.os }}-cargo-registry-${{ hashFiles('**/Cargo.lock') }} | ||
| 52 | |||
| 53 | - name: Cache cargo index | ||
| 54 | uses: actions/cache@v3 | ||
| 55 | with: | ||
| 56 | path: ~/.cargo/git | ||
| 57 | key: ${{ runner.os }}-cargo-index-${{ hashFiles('**/Cargo.lock') }} | ||
| 58 | |||
| 59 | - name: Cache cargo build | ||
| 60 | uses: actions/cache@v3 | ||
| 61 | with: | ||
| 62 | path: target | ||
| 63 | key: ${{ runner.os }}-cargo-build-target-${{ hashFiles('**/Cargo.lock') }} | ||
| 64 | |||
| 65 | - name: Build binary | ||
| 66 | env: | ||
| 67 | RUSTFLAGS: "-C target-feature=+crt-static" | ||
| 68 | run: | | ||
| 69 | cargo build --release --target ${{ matrix.target }} | ||
| 70 | |||
| 71 | - name: Strip binary (Linux) | ||
| 72 | if: runner.os == 'Linux' | ||
| 73 | run: | | ||
| 74 | strip target/${{ matrix.target }}/release/oar-p2p | ||
| 75 | |||
| 76 | - name: Strip binary (macOS) | ||
| 77 | if: runner.os == 'macOS' | ||
| 78 | run: | | ||
| 79 | strip target/${{ matrix.target }}/release/oar-p2p || true | ||
| 80 | |||
| 81 | - name: Create tarball | ||
| 82 | run: | | ||
| 83 | cd target/${{ matrix.target }}/release | ||
| 84 | tar -czf ../../../oar-p2p-${{ github.ref_name }}-${{ matrix.platform }}.tar.gz oar-p2p | ||
| 85 | cd ../../.. | ||
| 86 | |||
| 87 | - name: Upload artifact | ||
| 88 | uses: actions/upload-artifact@v3 | ||
| 89 | with: | ||
| 90 | name: oar-p2p-${{ matrix.platform }} | ||
| 91 | path: oar-p2p-${{ github.ref_name }}-${{ matrix.platform }}.tar.gz | ||
| 92 | |||
| 93 | release: | ||
| 94 | name: Create Release | ||
| 95 | needs: build | ||
| 96 | runs-on: ubuntu-latest | ||
| 97 | |||
| 98 | steps: | ||
| 99 | - name: Checkout code | ||
| 100 | uses: actions/checkout@v4 | ||
| 101 | |||
| 102 | - name: Download artifacts | ||
| 103 | uses: actions/download-artifact@v3 | ||
| 104 | with: | ||
| 105 | path: artifacts | ||
| 106 | |||
| 107 | - name: Move artifacts to release directory | ||
| 108 | run: | | ||
| 109 | mkdir -p release | ||
| 110 | mv artifacts/*/*.tar.gz release/ | ||
| 111 | |||
| 112 | - name: Generate checksums | ||
| 113 | run: | | ||
| 114 | cd release | ||
| 115 | sha256sum *.tar.gz > checksums-sha256.txt | ||
| 116 | sha512sum *.tar.gz > checksums-sha512.txt | ||
| 117 | |||
| 118 | - name: Generate release notes | ||
| 119 | run: | | ||
| 120 | VERSION="${{ github.ref_name }}" | ||
| 121 | VERSION_NUMBER="${VERSION#v}" | ||
| 122 | |||
| 123 | cat > release-notes.md << EOF | ||
| 124 | # Release ${{ github.ref_name }} | ||
| 125 | |||
| 126 | ## Installation | ||
| 127 | |||
| 128 | ### Linux x86_64 | ||
| 129 | \`\`\`bash | ||
| 130 | curl -L https://github.com/${{ github.repository }}/releases/download/${{ github.ref_name }}/oar-p2p-${{ github.ref_name }}-linux-x86_64.tar.gz | tar -xz | ||
| 131 | sudo mv oar-p2p /usr/local/bin/ | ||
| 132 | \`\`\` | ||
| 133 | |||
| 134 | ### macOS Intel | ||
| 135 | \`\`\`bash | ||
| 136 | curl -L https://github.com/${{ github.repository }}/releases/download/${{ github.ref_name }}/oar-p2p-${{ github.ref_name }}-macos-x86_64.tar.gz | tar -xz | ||
| 137 | sudo mv oar-p2p /usr/local/bin/ | ||
| 138 | \`\`\` | ||
| 139 | |||
| 140 | ### macOS Apple Silicon | ||
| 141 | \`\`\`bash | ||
| 142 | curl -L https://github.com/${{ github.repository }}/releases/download/${{ github.ref_name }}/oar-p2p-${{ github.ref_name }}-macos-aarch64.tar.gz | tar -xz | ||
| 143 | sudo mv oar-p2p /usr/local/bin/ | ||
| 144 | \`\`\` | ||
| 145 | |||
| 146 | ## Checksums | ||
| 147 | |||
| 148 | ### SHA256 | ||
| 149 | \`\`\` | ||
| 150 | $(cat release/checksums-sha256.txt) | ||
| 151 | \`\`\` | ||
| 152 | |||
| 153 | ### SHA512 | ||
| 154 | \`\`\` | ||
| 155 | $(cat release/checksums-sha512.txt) | ||
| 156 | \`\`\` | ||
| 157 | EOF | ||
| 158 | |||
| 159 | - name: Create GitHub Release | ||
| 160 | uses: softprops/action-gh-release@v1 | ||
| 161 | with: | ||
| 162 | files: | | ||
| 163 | release/*.tar.gz | ||
| 164 | release/checksums-*.txt | ||
| 165 | body_path: release-notes.md | ||
| 166 | draft: false | ||
| 167 | prerelease: false | ||
| 168 | env: | ||
| 169 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} \ No newline at end of file | ||
| @@ -14,3 +14,16 @@ thiserror = "2.0.12" | |||
| 14 | tokio = { version = "1.46.1", features = ["full"] } | 14 | tokio = { version = "1.46.1", features = ["full"] } |
| 15 | tracing = "0.1.41" | 15 | tracing = "0.1.41" |
| 16 | tracing-subscriber = { version = "0.3.19", features = ["env-filter"] } | 16 | tracing-subscriber = { version = "0.3.19", features = ["env-filter"] } |
| 17 | |||
| 18 | [profile.release] | ||
| 19 | # Optimize for size | ||
| 20 | opt-level = "z" # Optimize for size | ||
| 21 | lto = true # Enable Link Time Optimization | ||
| 22 | codegen-units = 1 # Compile crates one after another for better optimizations | ||
| 23 | strip = true # Strip symbols from binary | ||
| 24 | debug = false # Disable debug info | ||
| 25 | |||
| 26 | # Additional size optimizations | ||
| 27 | [profile.release.package."*"] | ||
| 28 | opt-level = "z" | ||
| 29 | strip = "symbols" | ||
diff --git a/scripts/README.md b/scripts/README.md new file mode 100644 index 0000000..65b69ee --- /dev/null +++ b/scripts/README.md | |||
| @@ -0,0 +1,56 @@ | |||
| 1 | # Build Scripts | ||
| 2 | |||
| 3 | This directory contains scripts for building and releasing the oar-p2p binary. | ||
| 4 | |||
| 5 | ## Scripts | ||
| 6 | |||
| 7 | ### build-static.sh | ||
| 8 | |||
| 9 | Builds statically linked binaries for Linux and macOS. | ||
| 10 | |||
| 11 | ```bash | ||
| 12 | # Build for all platforms (macOS only) | ||
| 13 | ./scripts/build-static.sh all | ||
| 14 | |||
| 15 | # Build for Linux only | ||
| 16 | ./scripts/build-static.sh linux | ||
| 17 | |||
| 18 | # Build for macOS only (macOS only) | ||
| 19 | ./scripts/build-static.sh macos | ||
| 20 | |||
| 21 | # Specify custom output directory | ||
| 22 | ./scripts/build-static.sh linux /path/to/output | ||
| 23 | ``` | ||
| 24 | |||
| 25 | **Note**: Cross-compilation is not supported. Linux binaries must be built on Linux, and macOS binaries must be built on macOS. The GitHub Actions workflow handles this by using different runners. | ||
| 26 | |||
| 27 | ### prepare-release.sh | ||
| 28 | |||
| 29 | Prepares a release by building binaries, creating tarballs, and generating checksums. | ||
| 30 | |||
| 31 | ```bash | ||
| 32 | # Prepare release for version v1.0.0 | ||
| 33 | ./scripts/prepare-release.sh v1.0.0 | ||
| 34 | |||
| 35 | # Specify custom output directory | ||
| 36 | ./scripts/prepare-release.sh v1.0.0 /path/to/dist | ||
| 37 | ``` | ||
| 38 | |||
| 39 | The script will: | ||
| 40 | 1. Build static binaries for the current platform | ||
| 41 | 2. Create tarballs with the binary and README | ||
| 42 | 3. Generate SHA256 and SHA512 checksums | ||
| 43 | 4. Create a release notes template | ||
| 44 | |||
| 45 | ## GitHub Actions | ||
| 46 | |||
| 47 | The `.github/workflows/release.yml` workflow automatically: | ||
| 48 | 1. Triggers on version tags (e.g., `v1.0.0`) | ||
| 49 | 2. Builds binaries on Linux and macOS runners | ||
| 50 | 3. Creates a GitHub release with all artifacts | ||
| 51 | |||
| 52 | To create a release: | ||
| 53 | ```bash | ||
| 54 | git tag -a v1.0.0 -m "Release v1.0.0" | ||
| 55 | git push origin v1.0.0 | ||
| 56 | ``` \ No newline at end of file | ||
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 @@ | |||
| 1 | #!/bin/bash | ||
| 2 | set -euo pipefail | ||
| 3 | |||
| 4 | # Script to build static binaries for Linux and macOS | ||
| 5 | # Can be run locally or in CI | ||
| 6 | |||
| 7 | SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" | ||
| 8 | PROJECT_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)" | ||
| 9 | BINARY_NAME="oar-p2p" | ||
| 10 | |||
| 11 | # Parse command line arguments | ||
| 12 | TARGET_OS="${1:-all}" # linux, macos, or all | ||
| 13 | OUTPUT_DIR="${2:-$PROJECT_ROOT/target/release-static}" | ||
| 14 | |||
| 15 | # Colors for output | ||
| 16 | RED='\033[0;31m' | ||
| 17 | GREEN='\033[0;32m' | ||
| 18 | YELLOW='\033[1;33m' | ||
| 19 | NC='\033[0m' # No Color | ||
| 20 | |||
| 21 | log_info() { | ||
| 22 | echo -e "${GREEN}[INFO]${NC} $1" | ||
| 23 | } | ||
| 24 | |||
| 25 | log_error() { | ||
| 26 | echo -e "${RED}[ERROR]${NC} $1" >&2 | ||
| 27 | } | ||
| 28 | |||
| 29 | log_warn() { | ||
| 30 | echo -e "${YELLOW}[WARN]${NC} $1" | ||
| 31 | } | ||
| 32 | |||
| 33 | # Ensure we're in the project root | ||
| 34 | cd "$PROJECT_ROOT" | ||
| 35 | |||
| 36 | # Create output directory | ||
| 37 | mkdir -p "$OUTPUT_DIR" | ||
| 38 | |||
| 39 | # Function to build for Linux with musl | ||
| 40 | build_linux() { | ||
| 41 | local arch="${1:-x86_64}" | ||
| 42 | local target="${arch}-unknown-linux-musl" | ||
| 43 | |||
| 44 | log_info "Building static binary for Linux ($arch)..." | ||
| 45 | |||
| 46 | # Check if target is installed | ||
| 47 | if ! rustup target list --installed | grep -q "$target"; then | ||
| 48 | log_info "Installing Rust target: $target" | ||
| 49 | rustup target add "$target" | ||
| 50 | fi | ||
| 51 | |||
| 52 | # Set environment variables for static linking | ||
| 53 | export RUSTFLAGS="-C target-feature=+crt-static" | ||
| 54 | |||
| 55 | # Build the binary | ||
| 56 | log_info "Running cargo build for $target..." | ||
| 57 | cargo build --release --target "$target" --target-dir "$PROJECT_ROOT/target" | ||
| 58 | |||
| 59 | # Copy binary to output directory with platform suffix | ||
| 60 | local output_name="${BINARY_NAME}-linux-${arch}" | ||
| 61 | cp "target/$target/release/$BINARY_NAME" "$OUTPUT_DIR/$output_name" | ||
| 62 | |||
| 63 | # Strip the binary to reduce size | ||
| 64 | if command -v strip >/dev/null 2>&1; then | ||
| 65 | log_info "Stripping binary to reduce size..." | ||
| 66 | strip "$OUTPUT_DIR/$output_name" | ||
| 67 | fi | ||
| 68 | |||
| 69 | # Make it executable | ||
| 70 | chmod +x "$OUTPUT_DIR/$output_name" | ||
| 71 | |||
| 72 | log_info "Linux binary built: $OUTPUT_DIR/$output_name" | ||
| 73 | |||
| 74 | # Print binary info | ||
| 75 | if command -v file >/dev/null 2>&1; then | ||
| 76 | file "$OUTPUT_DIR/$output_name" | ||
| 77 | fi | ||
| 78 | |||
| 79 | # Check if it's actually statically linked | ||
| 80 | if command -v ldd >/dev/null 2>&1; then | ||
| 81 | if ldd "$OUTPUT_DIR/$output_name" 2>&1 | grep -q "not a dynamic executable"; then | ||
| 82 | log_info "✓ Binary is statically linked" | ||
| 83 | else | ||
| 84 | log_warn "Binary appears to be dynamically linked" | ||
| 85 | fi | ||
| 86 | fi | ||
| 87 | } | ||
| 88 | |||
| 89 | # Function to build for macOS | ||
| 90 | build_macos() { | ||
| 91 | local arch="${1:-x86_64}" | ||
| 92 | local target | ||
| 93 | |||
| 94 | case "$arch" in | ||
| 95 | x86_64) | ||
| 96 | target="x86_64-apple-darwin" | ||
| 97 | ;; | ||
| 98 | aarch64|arm64) | ||
| 99 | target="aarch64-apple-darwin" | ||
| 100 | ;; | ||
| 101 | *) | ||
| 102 | log_error "Unknown macOS architecture: $arch" | ||
| 103 | return 1 | ||
| 104 | ;; | ||
| 105 | esac | ||
| 106 | |||
| 107 | # Check if we're on macOS | ||
| 108 | if [[ "$OSTYPE" != "darwin"* ]]; then | ||
| 109 | log_warn "Cannot build macOS binaries on non-macOS systems" | ||
| 110 | log_info "macOS binaries must be built on macOS or in CI" | ||
| 111 | return 0 | ||
| 112 | fi | ||
| 113 | |||
| 114 | log_info "Building binary for macOS ($arch)..." | ||
| 115 | |||
| 116 | # Check if target is installed | ||
| 117 | if ! rustup target list --installed | grep -q "$target"; then | ||
| 118 | log_info "Installing Rust target: $target" | ||
| 119 | rustup target add "$target" | ||
| 120 | fi | ||
| 121 | |||
| 122 | # macOS doesn't support fully static binaries, but we can minimize dependencies | ||
| 123 | export RUSTFLAGS="-C target-feature=+crt-static" | ||
| 124 | |||
| 125 | # Build the binary | ||
| 126 | log_info "Running cargo build for $target..." | ||
| 127 | cargo build --release --target "$target" --target-dir "$PROJECT_ROOT/target" | ||
| 128 | |||
| 129 | # Copy binary to output directory with platform suffix | ||
| 130 | local output_name="${BINARY_NAME}-macos-${arch}" | ||
| 131 | cp "target/$target/release/$BINARY_NAME" "$OUTPUT_DIR/$output_name" | ||
| 132 | |||
| 133 | # Strip the binary to reduce size (macOS strip is different) | ||
| 134 | if [[ "$OSTYPE" == "darwin"* ]] && command -v strip >/dev/null 2>&1; then | ||
| 135 | log_info "Stripping binary to reduce size..." | ||
| 136 | strip "$OUTPUT_DIR/$output_name" | ||
| 137 | fi | ||
| 138 | |||
| 139 | # Make it executable | ||
| 140 | chmod +x "$OUTPUT_DIR/$output_name" | ||
| 141 | |||
| 142 | log_info "macOS binary built: $OUTPUT_DIR/$output_name" | ||
| 143 | |||
| 144 | # Print binary info | ||
| 145 | if command -v file >/dev/null 2>&1; then | ||
| 146 | file "$OUTPUT_DIR/$output_name" | ||
| 147 | fi | ||
| 148 | } | ||
| 149 | |||
| 150 | # Function to check dependencies | ||
| 151 | check_dependencies() { | ||
| 152 | local missing_deps=() | ||
| 153 | |||
| 154 | # Check for Rust | ||
| 155 | if ! command -v cargo >/dev/null 2>&1; then | ||
| 156 | missing_deps+=("cargo (Rust)") | ||
| 157 | fi | ||
| 158 | |||
| 159 | # Check for rustup | ||
| 160 | if ! command -v rustup >/dev/null 2>&1; then | ||
| 161 | missing_deps+=("rustup") | ||
| 162 | fi | ||
| 163 | |||
| 164 | if [ ${#missing_deps[@]} -ne 0 ]; then | ||
| 165 | log_error "Missing required dependencies:" | ||
| 166 | for dep in "${missing_deps[@]}"; do | ||
| 167 | echo " - $dep" | ||
| 168 | done | ||
| 169 | exit 1 | ||
| 170 | fi | ||
| 171 | |||
| 172 | # Check Rust version (nightly required based on Cargo.toml) | ||
| 173 | if ! rustc --version | grep -q "nightly"; then | ||
| 174 | log_warn "This project requires Rust nightly. Current version:" | ||
| 175 | rustc --version | ||
| 176 | log_info "Attempting to use nightly for this build..." | ||
| 177 | export RUSTUP_TOOLCHAIN=nightly | ||
| 178 | fi | ||
| 179 | } | ||
| 180 | |||
| 181 | # Main execution | ||
| 182 | main() { | ||
| 183 | log_info "Starting static build process..." | ||
| 184 | log_info "Output directory: $OUTPUT_DIR" | ||
| 185 | |||
| 186 | # Check dependencies | ||
| 187 | check_dependencies | ||
| 188 | |||
| 189 | case "$TARGET_OS" in | ||
| 190 | linux) | ||
| 191 | build_linux "x86_64" | ||
| 192 | # Optionally build for ARM64 | ||
| 193 | # build_linux "aarch64" | ||
| 194 | ;; | ||
| 195 | macos|darwin) | ||
| 196 | # Build for both Intel and Apple Silicon | ||
| 197 | build_macos "x86_64" | ||
| 198 | build_macos "aarch64" | ||
| 199 | ;; | ||
| 200 | all) | ||
| 201 | # Build for all platforms | ||
| 202 | build_linux "x86_64" | ||
| 203 | build_macos "x86_64" | ||
| 204 | build_macos "aarch64" | ||
| 205 | ;; | ||
| 206 | *) | ||
| 207 | log_error "Unknown target OS: $TARGET_OS" | ||
| 208 | echo "Usage: $0 [linux|macos|all] [output_dir]" | ||
| 209 | exit 1 | ||
| 210 | ;; | ||
| 211 | esac | ||
| 212 | |||
| 213 | log_info "Build complete! Binaries available in: $OUTPUT_DIR" | ||
| 214 | ls -lh "$OUTPUT_DIR" | ||
| 215 | } | ||
| 216 | |||
| 217 | # Run main function | ||
| 218 | main \ No newline at end of file | ||
diff --git a/scripts/prepare-release.sh b/scripts/prepare-release.sh new file mode 100755 index 0000000..ba654e2 --- /dev/null +++ b/scripts/prepare-release.sh | |||
| @@ -0,0 +1,206 @@ | |||
| 1 | #!/bin/bash | ||
| 2 | set -euo pipefail | ||
| 3 | |||
| 4 | # Script to prepare release artifacts | ||
| 5 | # Builds binaries, creates checksums, and prepares release notes | ||
| 6 | |||
| 7 | SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" | ||
| 8 | PROJECT_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)" | ||
| 9 | BINARY_NAME="oar-p2p" | ||
| 10 | |||
| 11 | # Parse command line arguments | ||
| 12 | VERSION="${1:-}" | ||
| 13 | OUTPUT_DIR="${2:-$PROJECT_ROOT/dist}" | ||
| 14 | |||
| 15 | # Colors for output | ||
| 16 | RED='\033[0;31m' | ||
| 17 | GREEN='\033[0;32m' | ||
| 18 | YELLOW='\033[1;33m' | ||
| 19 | BLUE='\033[0;34m' | ||
| 20 | NC='\033[0m' # No Color | ||
| 21 | |||
| 22 | log_info() { | ||
| 23 | echo -e "${GREEN}[INFO]${NC} $1" | ||
| 24 | } | ||
| 25 | |||
| 26 | log_error() { | ||
| 27 | echo -e "${RED}[ERROR]${NC} $1" >&2 | ||
| 28 | } | ||
| 29 | |||
| 30 | log_warn() { | ||
| 31 | echo -e "${YELLOW}[WARN]${NC} $1" | ||
| 32 | } | ||
| 33 | |||
| 34 | # Ensure we're in the project root | ||
| 35 | cd "$PROJECT_ROOT" | ||
| 36 | |||
| 37 | # Check if version is provided | ||
| 38 | if [ -z "$VERSION" ]; then | ||
| 39 | log_error "Version not provided" | ||
| 40 | echo "Usage: $0 <version> [output_dir]" | ||
| 41 | echo "Example: $0 v1.0.0" | ||
| 42 | exit 1 | ||
| 43 | fi | ||
| 44 | |||
| 45 | # Remove 'v' prefix if present for consistency | ||
| 46 | VERSION_NUMBER="${VERSION#v}" | ||
| 47 | |||
| 48 | log_info "Preparing release for version: $VERSION_NUMBER" | ||
| 49 | |||
| 50 | # Create output directories | ||
| 51 | BUILD_DIR="$PROJECT_ROOT/target/release-static" | ||
| 52 | mkdir -p "$OUTPUT_DIR" | ||
| 53 | mkdir -p "$BUILD_DIR" | ||
| 54 | |||
| 55 | # Build all binaries | ||
| 56 | log_info "Building static binaries for all platforms..." | ||
| 57 | if [[ "$OSTYPE" == "darwin"* ]]; then | ||
| 58 | # On macOS, build all platforms | ||
| 59 | "$SCRIPT_DIR/build-static.sh" all "$BUILD_DIR" | ||
| 60 | else | ||
| 61 | # On Linux, only build Linux binaries | ||
| 62 | log_warn "Running on Linux - only Linux binaries will be built" | ||
| 63 | log_info "macOS binaries must be built on macOS or in CI" | ||
| 64 | "$SCRIPT_DIR/build-static.sh" linux "$BUILD_DIR" | ||
| 65 | fi | ||
| 66 | |||
| 67 | # Function to create tarball for a binary | ||
| 68 | create_tarball() { | ||
| 69 | local binary_path="$1" | ||
| 70 | local binary_name="$(basename "$binary_path")" | ||
| 71 | local platform_name="${binary_name#$BINARY_NAME-}" | ||
| 72 | local tarball_name="${BINARY_NAME}-${VERSION_NUMBER}-${platform_name}.tar.gz" | ||
| 73 | |||
| 74 | log_info "Creating tarball: $tarball_name" | ||
| 75 | |||
| 76 | # Create temporary directory for tarball contents | ||
| 77 | local temp_dir="$(mktemp -d)" | ||
| 78 | |||
| 79 | # Copy binary to temp directory | ||
| 80 | cp "$binary_path" "$temp_dir/$BINARY_NAME" | ||
| 81 | chmod +x "$temp_dir/$BINARY_NAME" | ||
| 82 | |||
| 83 | # Create README for the tarball | ||
| 84 | cat > "$temp_dir/README.md" << EOF | ||
| 85 | # $BINARY_NAME v$VERSION_NUMBER | ||
| 86 | |||
| 87 | Platform: ${platform_name} | ||
| 88 | |||
| 89 | ## Installation | ||
| 90 | |||
| 91 | 1. Extract the binary: | ||
| 92 | \`\`\`bash | ||
| 93 | tar -xzf $tarball_name | ||
| 94 | \`\`\` | ||
| 95 | |||
| 96 | 2. Move to a directory in your PATH: | ||
| 97 | \`\`\`bash | ||
| 98 | sudo mv $BINARY_NAME /usr/local/bin/ | ||
| 99 | \`\`\` | ||
| 100 | |||
| 101 | 3. Verify installation: | ||
| 102 | \`\`\`bash | ||
| 103 | $BINARY_NAME --version | ||
| 104 | \`\`\` | ||
| 105 | |||
| 106 | ## Usage | ||
| 107 | |||
| 108 | Run \`$BINARY_NAME --help\` for usage information. | ||
| 109 | |||
| 110 | EOF | ||
| 111 | |||
| 112 | # Create tarball | ||
| 113 | tar -czf "$OUTPUT_DIR/$tarball_name" -C "$temp_dir" . | ||
| 114 | |||
| 115 | # Cleanup | ||
| 116 | rm -rf "$temp_dir" | ||
| 117 | |||
| 118 | return 0 | ||
| 119 | } | ||
| 120 | |||
| 121 | # Create tarballs for all binaries | ||
| 122 | log_info "Creating release tarballs..." | ||
| 123 | for binary in "$BUILD_DIR"/${BINARY_NAME}-*; do | ||
| 124 | if [ -f "$binary" ]; then | ||
| 125 | create_tarball "$binary" | ||
| 126 | fi | ||
| 127 | done | ||
| 128 | |||
| 129 | # Generate checksums | ||
| 130 | log_info "Generating checksums..." | ||
| 131 | cd "$OUTPUT_DIR" | ||
| 132 | |||
| 133 | # Create SHA256 checksums | ||
| 134 | if command -v sha256sum >/dev/null 2>&1; then | ||
| 135 | sha256sum *.tar.gz > "checksums-sha256.txt" | ||
| 136 | elif command -v shasum >/dev/null 2>&1; then | ||
| 137 | shasum -a 256 *.tar.gz > "checksums-sha256.txt" | ||
| 138 | else | ||
| 139 | log_warn "SHA256 checksum tool not found, skipping checksums" | ||
| 140 | fi | ||
| 141 | |||
| 142 | # Create SHA512 checksums | ||
| 143 | if command -v sha512sum >/dev/null 2>&1; then | ||
| 144 | sha512sum *.tar.gz > "checksums-sha512.txt" | ||
| 145 | elif command -v shasum >/dev/null 2>&1; then | ||
| 146 | shasum -a 512 *.tar.gz > "checksums-sha512.txt" | ||
| 147 | fi | ||
| 148 | |||
| 149 | # Generate release notes template | ||
| 150 | log_info "Generating release notes template..." | ||
| 151 | cat > "$OUTPUT_DIR/RELEASE_NOTES.md" << EOF | ||
| 152 | # Release Notes - $BINARY_NAME v$VERSION_NUMBER | ||
| 153 | |||
| 154 | ## What's Changed | ||
| 155 | |||
| 156 | <!-- Add your changes here --> | ||
| 157 | |||
| 158 | ## Installation | ||
| 159 | |||
| 160 | ### Using curl (Linux/macOS) | ||
| 161 | |||
| 162 | \`\`\`bash | ||
| 163 | # Linux x86_64 | ||
| 164 | curl -L https://github.com/diogo464/oar-p2p/releases/download/v$VERSION_NUMBER/${BINARY_NAME}-${VERSION_NUMBER}-linux-x86_64.tar.gz | tar -xz | ||
| 165 | sudo mv $BINARY_NAME /usr/local/bin/ | ||
| 166 | |||
| 167 | # macOS Intel | ||
| 168 | curl -L https://github.com/diogo464/oar-p2p/releases/download/v$VERSION_NUMBER/${BINARY_NAME}-${VERSION_NUMBER}-macos-x86_64.tar.gz | tar -xz | ||
| 169 | sudo mv $BINARY_NAME /usr/local/bin/ | ||
| 170 | |||
| 171 | # macOS Apple Silicon | ||
| 172 | curl -L https://github.com/diogo464/oar-p2p/releases/download/v$VERSION_NUMBER/${BINARY_NAME}-${VERSION_NUMBER}-macos-aarch64.tar.gz | tar -xz | ||
| 173 | sudo mv $BINARY_NAME /usr/local/bin/ | ||
| 174 | \`\`\` | ||
| 175 | |||
| 176 | ## Checksums | ||
| 177 | |||
| 178 | ### SHA256 | ||
| 179 | \`\`\` | ||
| 180 | $(cat checksums-sha256.txt 2>/dev/null || echo "Checksums will be generated during release") | ||
| 181 | \`\`\` | ||
| 182 | |||
| 183 | ### SHA512 | ||
| 184 | \`\`\` | ||
| 185 | $(cat checksums-sha512.txt 2>/dev/null || echo "Checksums will be generated during release") | ||
| 186 | \`\`\` | ||
| 187 | |||
| 188 | ## Full Changelog | ||
| 189 | |||
| 190 | See the full changelog at: https://github.com/diogo464/oar-p2p/compare/v<PREVIOUS_VERSION>...v$VERSION_NUMBER | ||
| 191 | |||
| 192 | EOF | ||
| 193 | |||
| 194 | # List all artifacts | ||
| 195 | log_info "Release artifacts created in: $OUTPUT_DIR" | ||
| 196 | echo -e "${BLUE}Contents:${NC}" | ||
| 197 | ls -lh "$OUTPUT_DIR" | ||
| 198 | |||
| 199 | # Print summary | ||
| 200 | echo | ||
| 201 | log_info "Release preparation complete!" | ||
| 202 | echo -e "${BLUE}Next steps:${NC}" | ||
| 203 | echo "1. Review and edit the release notes: $OUTPUT_DIR/RELEASE_NOTES.md" | ||
| 204 | echo "2. Create a git tag: git tag -a v$VERSION_NUMBER -m \"Release v$VERSION_NUMBER\"" | ||
| 205 | echo "3. Push the tag: git push origin v$VERSION_NUMBER" | ||
| 206 | echo "4. The GitHub Action will automatically create the release and upload artifacts" \ No newline at end of file | ||
