Skip to content

Commit 5180a4a

Browse files
author
Paul C
committed
ci: prebuilt WolfScale release pipeline; setup.sh downloads instead of compiling
Add .github/workflows/wolfscale-release.yml — builds static musl wolfscale + wolfctl binaries for x86_64 and aarch64 (via cross) on push to main, and publishes them under a rolling 'wolfscale-latest' GitHub release so consumers have a stable download URL (the repo also ships WolfDisk releases, so a plain 'latest' would be ambiguous). setup.sh now downloads the prebuilt binary for the host's architecture and only falls back to a source build (rustup + cargo) when no prebuilt is available — turning a multi-minute compile into a quick download. WolfStack's WolfScale cluster builder pulls the same artifact.
1 parent 771e9e5 commit 5180a4a

2 files changed

Lines changed: 163 additions & 53 deletions

File tree

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
name: WolfScale — Build Release Binaries
2+
3+
on:
4+
push:
5+
branches: [main]
6+
paths:
7+
- 'Cargo.toml'
8+
- 'src/**'
9+
- '.github/workflows/wolfscale-release.yml'
10+
workflow_dispatch:
11+
12+
jobs:
13+
build:
14+
strategy:
15+
matrix:
16+
include:
17+
- target: x86_64-unknown-linux-musl
18+
arch: x86_64
19+
runner: ubuntu-latest
20+
- target: aarch64-unknown-linux-musl
21+
arch: aarch64
22+
runner: ubuntu-latest
23+
24+
runs-on: ${{ matrix.runner }}
25+
steps:
26+
- uses: actions/checkout@v4
27+
28+
- name: Install Rust
29+
uses: dtolnay/rust-toolchain@stable
30+
with:
31+
targets: ${{ matrix.target }}
32+
33+
- name: Install cross
34+
run: cargo install cross --git https://github.com/cross-rs/cross
35+
36+
- name: Build static binaries
37+
run: cross build --release --target ${{ matrix.target }} --bin wolfscale --bin wolfctl
38+
39+
- name: Package binaries
40+
run: |
41+
mkdir -p dist
42+
cp target/${{ matrix.target }}/release/wolfscale dist/wolfscale-${{ matrix.arch }}
43+
cp target/${{ matrix.target }}/release/wolfctl dist/wolfctl-${{ matrix.arch }}
44+
chmod +x dist/wolfscale-${{ matrix.arch }} dist/wolfctl-${{ matrix.arch }}
45+
46+
- name: Upload artifacts
47+
uses: actions/upload-artifact@v4
48+
with:
49+
name: wolfscale-${{ matrix.arch }}
50+
path: dist/*
51+
52+
release:
53+
needs: build
54+
runs-on: ubuntu-latest
55+
permissions:
56+
contents: write
57+
steps:
58+
- uses: actions/checkout@v4
59+
60+
- name: Get version
61+
id: version
62+
run: echo "version=$(grep '^version' Cargo.toml | head -1 | sed 's/.*\"\(.*\)\".*/\1/')" >> "$GITHUB_OUTPUT"
63+
64+
- name: Download all artifacts
65+
uses: actions/download-artifact@v4
66+
with:
67+
path: dist
68+
merge-multiple: true
69+
70+
# Rolling 'wolfscale-latest' release so consumers (WolfStack's cluster
71+
# builder, setup.sh) have a STABLE download URL. The WolfScale repo also
72+
# ships WolfDisk releases, so a plain 'latest' would be ambiguous — this
73+
# tag is deleted + recreated on every build.
74+
- name: Publish rolling 'wolfscale-latest' release
75+
env:
76+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
77+
run: |
78+
gh release delete "wolfscale-latest" --yes --cleanup-tag 2>/dev/null || true
79+
git push --delete origin "wolfscale-latest" 2>/dev/null || true
80+
gh release create "wolfscale-latest" \
81+
--title "WolfScale (latest — ${{ steps.version.outputs.version }})" \
82+
--notes "Prebuilt static WolfScale + wolfctl binaries for Linux x86_64 and aarch64 (ARM64/Raspberry Pi 4+). Rolling 'latest' tag, rebuilt on every push to main. Built from version ${{ steps.version.outputs.version }}." \
83+
dist/wolfscale-x86_64 \
84+
dist/wolfscale-aarch64 \
85+
dist/wolfctl-x86_64 \
86+
dist/wolfctl-aarch64

setup.sh

Lines changed: 77 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,11 @@
11
#!/bin/bash
22
#
33
# WolfScale Quick Install Script
4-
# Installs WolfScale on Ubuntu/Debian (apt) or Fedora/RHEL (dnf)
4+
# Installs WolfScale on Ubuntu/Debian (apt) or Fedora/RHEL (dnf).
5+
#
6+
# Downloads a prebuilt static binary from the release pipeline (the
7+
# 'wolfscale-latest' GitHub release). Only falls back to a source build if no
8+
# prebuilt binary is available for this CPU architecture or the download fails.
59
#
610
# Usage: curl -sSL https://raw.githubusercontent.com/wolfsoftwaresystemsltd/WolfScale/main/setup.sh | bash
711
#
@@ -30,65 +34,89 @@ else
3034
exit 1
3135
fi
3236

33-
# Install dependencies
34-
echo ""
35-
echo "Installing system dependencies..."
37+
# Detect CPU architecture for the prebuilt binary
38+
case "$(uname -m)" in
39+
x86_64|amd64) ARCH="x86_64" ;;
40+
aarch64|arm64) ARCH="aarch64" ;;
41+
*) ARCH="" ;;
42+
esac
3643

44+
RELEASE_BASE="https://github.com/wolfsoftwaresystemsltd/WolfScale/releases/download/wolfscale-latest"
45+
46+
# Base dependencies: git + curl are enough to fetch the repo (for
47+
# install_service.sh) and download the prebuilt binary. Build tools are only
48+
# installed in the source-build fallback below.
49+
echo ""
50+
echo "Installing base dependencies..."
3751
if [ "$PKG_MANAGER" = "apt" ]; then
3852
sudo apt update
39-
sudo apt install -y git curl build-essential pkg-config libssl-dev
40-
elif [ "$PKG_MANAGER" = "dnf" ]; then
41-
sudo dnf install -y git curl gcc gcc-c++ make openssl-devel pkg-config
42-
elif [ "$PKG_MANAGER" = "yum" ]; then
43-
sudo yum install -y git curl gcc gcc-c++ make openssl-devel pkgconfig
44-
fi
45-
46-
echo "✓ System dependencies installed"
47-
48-
# Install Rust if not present
49-
if ! command -v rustc &> /dev/null; then
50-
echo ""
51-
echo "Installing Rust..."
52-
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y
53-
source "$HOME/.cargo/env"
54-
echo "✓ Rust installed"
53+
sudo apt install -y git curl ca-certificates
5554
else
56-
echo "✓ Rust already installed ($(rustc --version))"
55+
sudo "$PKG_MANAGER" install -y git curl ca-certificates
5756
fi
57+
echo "✓ Base dependencies installed"
5858

59-
# Ensure cargo is in PATH
60-
export PATH="$HOME/.cargo/bin:$PATH"
61-
62-
# Clone or update repository
59+
# Clone or update the repository — needed for install_service.sh + upgrade
60+
# detection. (A shallow clone is cheap; we no longer build it here.)
6361
INSTALL_DIR="/opt/wolfscale-src"
6462
echo ""
65-
echo "Cloning WolfScale repository..."
66-
67-
if [ -d "$INSTALL_DIR" ]; then
68-
echo " Updating existing installation..."
63+
echo "Fetching WolfScale..."
64+
if [ -d "$INSTALL_DIR/.git" ]; then
65+
echo " Updating existing checkout..."
6966
cd "$INSTALL_DIR"
70-
# Use fetch + reset instead of pull to handle force-pushes cleanly
7167
sudo git fetch origin
7268
sudo git reset --hard origin/main
73-
# Clear logs to prevent huge log files from accumulating
7469
if [ -f "/var/log/wolfscale/wolfscale.log" ]; then
75-
echo " Clearing logs..."
7670
sudo truncate -s 0 /var/log/wolfscale/wolfscale.log
7771
fi
7872
else
79-
sudo git clone https://github.com/wolfsoftwaresystemsltd/WolfScale.git "$INSTALL_DIR"
73+
sudo git clone --depth 1 https://github.com/wolfsoftwaresystemsltd/WolfScale.git "$INSTALL_DIR"
8074
cd "$INSTALL_DIR"
8175
fi
82-
8376
sudo chown -R "$USER:$USER" "$INSTALL_DIR"
84-
echo "✓ Repository cloned to $INSTALL_DIR"
77+
mkdir -p "$INSTALL_DIR/target/release"
78+
echo "✓ Repository ready at $INSTALL_DIR"
8579

86-
# Build
80+
# Get the binary: prefer the prebuilt release artifact, build from source only
81+
# if it's unavailable for this arch. The rest of the script copies from
82+
# $INSTALL_DIR/target/release, so we drop the downloaded binary there.
8783
echo ""
88-
echo "Building WolfScale (this may take a few minutes)..."
89-
cd "$INSTALL_DIR"
90-
cargo build --release
91-
echo "✓ Build complete"
84+
GOT_BINARY=false
85+
if [ -n "$ARCH" ]; then
86+
echo "Downloading prebuilt WolfScale binary ($ARCH)..."
87+
if curl -fsSL "$RELEASE_BASE/wolfscale-$ARCH" -o "$INSTALL_DIR/target/release/wolfscale" \
88+
&& chmod +x "$INSTALL_DIR/target/release/wolfscale" \
89+
&& "$INSTALL_DIR/target/release/wolfscale" --version >/dev/null 2>&1; then
90+
curl -fsSL "$RELEASE_BASE/wolfctl-$ARCH" -o "$INSTALL_DIR/target/release/wolfctl" 2>/dev/null \
91+
&& chmod +x "$INSTALL_DIR/target/release/wolfctl" || true
92+
GOT_BINARY=true
93+
echo "✓ Installed prebuilt binary ($("$INSTALL_DIR/target/release/wolfscale" --version 2>/dev/null))"
94+
else
95+
echo "⚠ Prebuilt binary not available for $ARCH — falling back to a source build"
96+
fi
97+
else
98+
echo "⚠ Unknown CPU architecture ($(uname -m)) — falling back to a source build"
99+
fi
100+
101+
if [ "$GOT_BINARY" = false ]; then
102+
echo ""
103+
echo "Building WolfScale from source (this may take a few minutes)..."
104+
if [ "$PKG_MANAGER" = "apt" ]; then
105+
sudo apt install -y build-essential pkg-config libssl-dev
106+
elif [ "$PKG_MANAGER" = "dnf" ]; then
107+
sudo dnf install -y gcc gcc-c++ make openssl-devel pkg-config
108+
else
109+
sudo yum install -y gcc gcc-c++ make openssl-devel pkgconfig
110+
fi
111+
if ! command -v rustc &> /dev/null; then
112+
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y
113+
source "$HOME/.cargo/env"
114+
fi
115+
export PATH="$HOME/.cargo/bin:$PATH"
116+
cd "$INSTALL_DIR"
117+
cargo build --release
118+
echo "✓ Build complete"
119+
fi
92120

93121
# Check if this is an upgrade (service already exists)
94122
IS_UPGRADE=false
@@ -102,24 +130,21 @@ if [ "$IS_UPGRADE" = true ]; then
102130
# Upgrade mode: just copy binary and restart service
103131
echo ""
104132
echo "Upgrading WolfScale..."
105-
106-
# Copy new binary
133+
107134
sudo cp "$INSTALL_DIR/target/release/wolfscale" /usr/local/bin/wolfscale
108135
sudo chmod +x /usr/local/bin/wolfscale
109136
echo "✓ Binary updated"
110-
111-
# Restart service
137+
112138
sudo systemctl daemon-reload
113139
sudo systemctl restart wolfscale
114140
echo "✓ Service restarted"
115-
116-
# Update wolfctl if present
141+
117142
if [ -f "$INSTALL_DIR/target/release/wolfctl" ]; then
118143
sudo cp "$INSTALL_DIR/target/release/wolfctl" /usr/local/bin/wolfctl
119144
sudo chmod +x /usr/local/bin/wolfctl
120145
echo "✓ wolfctl updated"
121146
fi
122-
147+
123148
echo ""
124149
echo ""
125150
echo " Upgrade Complete!"
@@ -131,25 +156,24 @@ else
131156
# New install: run interactive installer
132157
echo ""
133158
echo " $(printf '%0.s─' {1..50})"
134-
echo " Build complete! Starting service installer..."
159+
echo " Binary ready! Starting service installer..."
135160
echo " $(printf '%0.s─' {1..50})"
136161
echo ""
137-
162+
138163
# Run installer with TTY for interactive input
139164
# (Needed because stdin is consumed when script is piped via curl)
140165
sudo ./install_service.sh < /dev/tty
141-
142-
# Install wolfctl CLI tool to /usr/local/bin
166+
143167
echo ""
144168
echo "Installing wolfctl CLI tool..."
145169
if [ -f "$INSTALL_DIR/target/release/wolfctl" ]; then
146170
sudo cp "$INSTALL_DIR/target/release/wolfctl" /usr/local/bin/wolfctl
147171
sudo chmod +x /usr/local/bin/wolfctl
148172
echo "✓ wolfctl installed to /usr/local/bin/wolfctl"
149173
else
150-
echo "⚠ wolfctl binary not found (may not have been built)"
174+
echo "⚠ wolfctl binary not found"
151175
fi
152-
176+
153177
echo ""
154178
echo ""
155179
echo " Installation Complete!"

0 commit comments

Comments
 (0)