#!/bin/sh # fiber CLI installer — https://cli.openvx.se/install.sh (ADR 0028 release channel). # # curl -fsSL https://cli.openvx.se/install.sh | sh # # Served from its own host (cli.openvx.se) by the nginx gateway, baked into the # gateway image (see nginx/Dockerfile + the cli.openvx.se server block in # nginx/nginx.conf). It used to live at openvx.se/install.sh on the old landing # page; when the marketplace SPA took the apex root, /install.sh fell through the # SPA fallback and returned index.html — hence the dedicated, decoupled host. # # The vx-next-gen repo is PRIVATE, so the binary download needs a GitHub token. # Auth is the consumer's own credential (ADR 0028 decision 7): `gh auth token` if # the GitHub CLI is installed + logged in, else the FIBER_GITHUB_TOKEN env var. # # Knobs (all optional, set them before the pipe — e.g. `FIBER_VERSION=0.1.0 sh`): # FIBER_VERSION pin a version: 0.1.0 or 0.1.0-rc.1 (default: latest stable) # FIBER_INSTALL_DIR install location (default: ~/.fiber/bin) # FIBER_GITHUB_TOKEN token used when `gh` is absent (CI) # # Dependencies: `curl` always; `gh` OR `FIBER_GITHUB_TOKEN` for auth. Without `gh`, # and when resolving the default `latest`, `python3` is also required (to parse the # Releases API) — pin FIBER_VERSION to skip that dependency. set -eu REPO="vxfiber/vx-next-gen" INSTALL_DIR="${FIBER_INSTALL_DIR:-$HOME/.fiber/bin}" VERSION="${FIBER_VERSION:-latest}" say() { printf 'fiber-install: %s\n' "$1" >&2; } die() { printf 'fiber-install: error: %s\n' "$1" >&2; exit 1; } have() { command -v "$1" >/dev/null 2>&1; } have curl || die "curl is required." # --- platform → release asset (ADR 0028 ships three RIDs) -------------------- os="$(uname -s)" arch="$(uname -m)" case "$os-$arch" in Linux-x86_64 | Linux-amd64) asset="fiber-linux-x64" ;; Darwin-arm64) asset="fiber-osx-arm64" ;; Darwin-x86_64) die "macOS Intel has no release binary — run on Apple Silicon, or build from a checkout." ;; *) die "unsupported platform '$os-$arch' — release binaries: linux-x64, osx-arm64, win-x64 (Windows: use a manual download)." ;; esac # --- GitHub token (gh first, then env) --------------------------------------- token="" if have gh; then token="$(gh auth token --hostname github.com 2>/dev/null || true)" fi [ -n "$token" ] || token="${FIBER_GITHUB_TOKEN:-}" [ -n "$token" ] || die "no GitHub token — run \`gh auth login\`, or set FIBER_GITHUB_TOKEN (the repo is private)." api() { # api curl -fsSL \ -H "Authorization: Bearer $token" \ -H "Accept: application/vnd.github+json" \ -H "X-GitHub-Api-Version: 2022-11-28" \ "https://api.github.com/repos/$REPO/$1" } # --- resolve the release tag ------------------------------------------------- if [ "$VERSION" = "latest" ]; then have python3 || die "resolving 'latest' needs python3 — pin FIBER_VERSION=X.Y.Z, or install python3 (or gh)." tag="$(api "releases?per_page=100" | python3 -c ' import sys, json picks = [] for r in json.load(sys.stdin): if r["draft"] or r["prerelease"] or not r["tag_name"].startswith("fiber-v"): continue core = r["tag_name"][len("fiber-v"):].split("-", 1)[0].split(".") if len(core) == 3 and all(c.isdigit() for c in core): # skip unparseable tags picks.append((tuple(int(c) for c in core), r["tag_name"])) print(sorted(picks)[-1][1] if picks else "") ')" [ -n "$tag" ] || die "no stable fiber release found on $REPO (for a prerelease, pin FIBER_VERSION=X.Y.Z-rc.N)." else tag="fiber-v${VERSION#fiber-v}" # accept 0.1.0 or fiber-v0.1.0 fi say "installing $tag ($asset)" # --- download ---------------------------------------------------------------- mkdir -p "$INSTALL_DIR" dest="$INSTALL_DIR/fiber" tmp="$dest.download.$$" trap 'rm -f "$tmp"' EXIT if have gh; then # Pass the resolved token so the gh path works even when gh is installed but # not logged in and the token came from FIBER_GITHUB_TOKEN. GH_TOKEN="$token" gh release download "$tag" --repo "$REPO" --pattern "$asset" --output "$tmp" --clobber \ || die "gh release download failed for $tag/$asset." else have python3 || die "without gh, the download needs python3 to resolve the asset — install gh or python3." aurl="$(api "releases/tags/$tag" | python3 -c " import sys, json urls = [a['url'] for a in json.load(sys.stdin)['assets'] if a['name'] == '$asset'] print(urls[0] if urls else '') ")" [ -n "$aurl" ] || die "release $tag has no asset '$asset'." curl -fsSL -H "Authorization: Bearer $token" -H "Accept: application/octet-stream" -o "$tmp" "$aurl" \ || die "asset download failed." fi chmod +x "$tmp" mv -f "$tmp" "$dest" trap - EXIT # --- mark the install as release-channel so `fiber update` self-updates ------ mkdir -p "$HOME/.fiber" printf '{"channel":"release"}\n' >"$HOME/.fiber/install.json" "$dest" version >/dev/null 2>&1 || die "installed binary at $dest does not run." say "installed fiber $tag → $dest" case ":$PATH:" in *":$INSTALL_DIR:"*) say "run: fiber" ;; *) say "add to PATH, then run \`fiber\`: export PATH=\"$INSTALL_DIR:\$PATH\" (append to ~/.bashrc or ~/.zshrc)" ;; esac