diff --git a/.github/workflows/build-openfang-full-arm.yml b/.github/workflows/build-openfang-full-arm.yml
new file mode 100644
index 000000000..01ebaff6e
--- /dev/null
+++ b/.github/workflows/build-openfang-full-arm.yml
@@ -0,0 +1,69 @@
+name: Build OpenFang Full (ARM Ubuntu)
+
+on:
+ workflow_dispatch:
+ push:
+ tags:
+ - "v*"
+
+permissions:
+ contents: write
+
+jobs:
+ build:
+ runs-on: ubuntu-24.04-arm
+
+ steps:
+ - name: Checkout
+ uses: actions/checkout@v4
+
+ - name: System deps (build)
+ run: |
+ sudo apt-get update
+ sudo apt-get install -y \
+ build-essential pkg-config clang cmake perl git curl \
+ libssl-dev libsqlite3-dev \
+ libgtk-3-dev libayatana-appindicator3-dev libwebkit2gtk-4.1-dev
+
+ - name: Rust toolchain
+ uses: dtolnay/rust-toolchain@stable
+
+ - uses: Swatinem/rust-cache@v2
+ with:
+ key: arm-ubuntu24
+
+ - name: Build full workspace
+ env:
+ CARGO_BUILD_JOBS: "2"
+ RUSTFLAGS: "-C debuginfo=0"
+ run: |
+ cargo build --release --workspace --locked
+
+ - name: Collect release binaries
+ run: |
+ mkdir -p out/bin
+ find target/release -maxdepth 1 -type f -executable \
+ ! -name "*.d" ! -name "build-script-*" -exec cp {} out/bin/ \;
+ ls -lah out/bin
+
+ - name: Package
+ run: |
+ tar -C out -czf openfang-aarch64-unknown-linux-gnu-native.tar.gz bin
+ sha256sum openfang-aarch64-unknown-linux-gnu-native.tar.gz > openfang-aarch64-unknown-linux-gnu-native.tar.gz.sha256
+
+ - name: Upload artifact (manual run)
+ if: github.event_name == 'workflow_dispatch'
+ uses: actions/upload-artifact@v4
+ with:
+ name: openfang-aarch64-unknown-linux-gnu-native
+ path: openfang-aarch64-unknown-linux-gnu-native.tar.gz
+
+ - name: Upload to GitHub Release (tag run)
+ if: startsWith(github.ref, 'refs/tags/')
+ uses: softprops/action-gh-release@v2
+ with:
+ files: |
+ openfang-aarch64-unknown-linux-gnu-native.tar.gz
+ openfang-aarch64-unknown-linux-gnu-native.tar.gz.sha256
+ env:
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
diff --git a/README.md b/README.md
index 746b84277..cbe0819b0 100644
--- a/README.md
+++ b/README.md
@@ -2,7 +2,7 @@
diff --git a/install.sh b/install.sh new file mode 100644 index 000000000..925626bc5 --- /dev/null +++ b/install.sh @@ -0,0 +1,147 @@ +#!/bin/sh +set -eu + +# OpenFang Installer (1BigBear fork - proot-distro ARM64 support) +# https://raw.githubusercontent.com/1BigBear/openfang/main/install.sh + +REPO="1BigBear/openfang" +INSTALL_DIR="$HOME/.openfang" +BIN_DIR="$HOME/.openfang/bin" +BINARY="openfang" + +main() { + need_cmd curl + need_cmd tar + need_cmd uname + + _os="$(uname -s)" + _arch="$(uname -m)" + + case "$_os" in + Linux) + case "$_arch" in + x86_64|amd64) + _target="x86_64-unknown-linux-gnu" + ;; + aarch64|arm64) + _target="aarch64-unknown-linux-gnu-native" + ;; + *) + err "Unsupported architecture: $_arch" + ;; + esac + ;; + Darwin) + case "$_arch" in + x86_64|amd64) _target="x86_64-apple-darwin" ;; + aarch64|arm64) _target="aarch64-apple-darwin" ;; + *) err "Unsupported architecture: $_arch" ;; + esac + ;; + *) + err "Unsupported OS: $_os" + ;; + esac + + _url="https://github.com/${REPO}/releases/latest/download/openfang-${_target}.tar.gz" + + say "Detected: $_os $_arch -> $_target" + say "Downloading from: $_url" + + _tmpdir="$(mktemp -d 2>/dev/null || mktemp -d -t openfang)" + trap 'rm -rf "$_tmpdir"' EXIT + + _code=$(curl -fsSL -w "%{http_code}" "$_url" -o "${_tmpdir}/openfang.tar.gz") || true + if [ "$_code" = "404" ]; then + err "Release not found. Check https://github.com/${REPO}/releases" + fi + if [ ! -f "${_tmpdir}/openfang.tar.gz" ] || [ "$(wc -c < "${_tmpdir}/openfang.tar.gz")" -lt 1000 ]; then + err "Download failed (HTTP ${_code}). Check https://github.com/${REPO}/releases" + fi + + say "Extracting..." + tar -xzf "${_tmpdir}/openfang.tar.gz" -C "$_tmpdir" + + _bin="$(find "$_tmpdir" -name "$BINARY" -type f -perm +111 2>/dev/null | head -1)" + if [ -z "$_bin" ]; then + _bin="$(find "$_tmpdir" -name "$BINARY" -type f | head -1)" + fi + if [ -z "$_bin" ]; then + err "Could not find openfang binary in archive" + fi + + mkdir -p "$BIN_DIR" + cp "$_bin" "${BIN_DIR}/${BINARY}" + chmod +x "${BIN_DIR}/${BINARY}" + + if "${BIN_DIR}/${BINARY}" --version >/dev/null 2>&1; then + _ver=$("${BIN_DIR}/${BINARY}" --version 2>/dev/null || echo "unknown") + say "Installed: $_ver" + else + say "Installed to: ${BIN_DIR}/${BINARY}" + fi + + add_to_path + + say "" + say "OpenFang installed successfully!" + say "" + say " Run: openfang init" + say " Docs: https://github.com/${REPO}" + say "" + + if ! command -v openfang >/dev/null 2>&1; then + say "Note: restart your shell or run:" + say " export PATH=\"${BIN_DIR}:\$PATH\"" + say "" + fi +} + +add_to_path() { + case ":$PATH:" in + *":${BIN_DIR}:"*) return ;; + esac + + _line="export PATH=\"${BIN_DIR}:\$PATH\"" + + _profile="" + if [ -n "${SHELL:-}" ]; then + case "$SHELL" in + */zsh) _profile="$HOME/.zshrc" ;; + */bash) + if [ -f "$HOME/.bashrc" ]; then + _profile="$HOME/.bashrc" + else + _profile="$HOME/.bash_profile" + fi ;; + */fish) _profile="$HOME/.config/fish/config.fish" ;; + *) _profile="$HOME/.profile" ;; + esac + else + _profile="$HOME/.profile" + fi + + if [ -n "$_profile" ] && [ -f "$_profile" ]; then + if ! grep -q "/.openfang/bin" "$_profile" 2>/dev/null; then + printf "\n# OpenFang\n%s\n" "$_line" >> "$_profile" + say "Added to PATH via $_profile" + fi + fi +} + +say() { + printf " \033[1;36mopenfang\033[0m %s\n" "$1" +} + +err() { + printf " \033[1;36mopenfang\033[0m \033[1;31merror:\033[0m %s\n" "$1" >&2 + exit 1 +} + +need_cmd() { + if ! command -v "$1" >/dev/null 2>&1; then + err "need '$1' (command not found)" + fi +} + +main