mirror of
https://github.com/browseros-ai/BrowserOS.git
synced 2026-05-13 23:53:25 +00:00
* feat: upload CLI binaries to CDN during release and gate workflow to core team
- Extend scripts/build/cli/upload.ts with uploadCliRelease() that pushes
archives + checksums to R2 under versioned (cli/v{VERSION}/) and latest
(cli/latest/) paths, plus a version.txt for lightweight latest resolution
- Update scripts/build/cli.ts entry point with --release/--version/--binaries-dir
flags (existing no-args behavior preserved for upload:cli-installers)
- Rewrite install.sh and install.ps1 to fetch from cdn.browseros.com instead of
GitHub releases API — eliminates rate limits and API dependency
- Add environment: release-core to release-cli.yml for core-team gating via
GitHub environment protection rules
- Add Bun setup + CDN upload step to the workflow between build and GitHub release
* fix: address review feedback for PR #602
- Make loadProdEnv return empty map when .env.production is absent so
pickEnv falls through to process.env in CI (Greptile P1)
- Add semver format validation for version string in install.sh and
install.ps1 to guard against malformed CDN responses
- Pass inputs.version via env var instead of inline ${{ }} interpolation
to prevent command injection in workflow shell
152 lines
5.3 KiB
Bash
Executable File
152 lines
5.3 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
#
|
|
# Install browseros-cli — downloads the latest release binary for your platform.
|
|
#
|
|
# Usage:
|
|
# curl -fsSL https://cdn.browseros.com/cli/install.sh | bash
|
|
#
|
|
# # Or with options:
|
|
# curl -fsSL https://cdn.browseros.com/cli/install.sh | bash -s -- --version 0.1.0 --dir /usr/local/bin
|
|
|
|
set -euo pipefail
|
|
|
|
CDN_BASE="https://cdn.browseros.com/cli"
|
|
BINARY="browseros-cli"
|
|
INSTALL_DIR="${HOME}/.browseros/bin"
|
|
|
|
# ── Parse arguments ──────────────────────────────────────────────────────────
|
|
|
|
VERSION=""
|
|
CUSTOM_DIR=""
|
|
|
|
while [[ $# -gt 0 ]]; do
|
|
case "$1" in
|
|
--version)
|
|
[[ $# -lt 2 ]] && { echo "Error: --version requires a value" >&2; exit 1; }
|
|
VERSION="$2"; shift 2 ;;
|
|
--dir)
|
|
[[ $# -lt 2 ]] && { echo "Error: --dir requires a value" >&2; exit 1; }
|
|
CUSTOM_DIR="$2"; shift 2 ;;
|
|
--help)
|
|
echo "Usage: install.sh [--version VERSION] [--dir INSTALL_DIR]"
|
|
echo ""
|
|
echo " --version Install a specific version (default: latest)"
|
|
echo " --dir Install directory (default: ~/.browseros/bin)"
|
|
exit 0
|
|
;;
|
|
*) echo "Unknown option: $1" >&2; exit 1 ;;
|
|
esac
|
|
done
|
|
|
|
[[ -n "$CUSTOM_DIR" ]] && INSTALL_DIR="$CUSTOM_DIR"
|
|
|
|
# ── Resolve latest version ───────────────────────────────────────────────────
|
|
|
|
if [[ -z "$VERSION" ]]; then
|
|
VERSION=$(curl -fsSL "${CDN_BASE}/latest/version.txt" | tr -d '[:space:]')
|
|
|
|
if [[ -z "$VERSION" ]]; then
|
|
echo "Error: could not determine latest version." >&2
|
|
echo " Try: install.sh --version 0.1.0" >&2
|
|
exit 1
|
|
fi
|
|
fi
|
|
|
|
if [[ ! "$VERSION" =~ ^[0-9]+\.[0-9]+\.[0-9]+(-[a-zA-Z0-9.]+)?$ ]]; then
|
|
echo "Error: unexpected version format: '$VERSION'" >&2
|
|
exit 1
|
|
fi
|
|
|
|
echo "Installing browseros-cli v${VERSION}..."
|
|
|
|
# ── Detect platform ──────────────────────────────────────────────────────────
|
|
|
|
OS=$(uname -s | tr '[:upper:]' '[:lower:]')
|
|
ARCH=$(uname -m)
|
|
|
|
case "$OS" in
|
|
darwin) OS="darwin" ;;
|
|
linux) OS="linux" ;;
|
|
*) echo "Error: unsupported OS: $OS" >&2; exit 1 ;;
|
|
esac
|
|
|
|
case "$ARCH" in
|
|
x86_64|amd64) ARCH="amd64" ;;
|
|
arm64|aarch64) ARCH="arm64" ;;
|
|
*) echo "Error: unsupported architecture: $ARCH" >&2; exit 1 ;;
|
|
esac
|
|
|
|
# ── Download and extract ─────────────────────────────────────────────────────
|
|
|
|
FILENAME="${BINARY}_${VERSION}_${OS}_${ARCH}.tar.gz"
|
|
URL="${CDN_BASE}/v${VERSION}/${FILENAME}"
|
|
CHECKSUM_URL="${CDN_BASE}/v${VERSION}/checksums.txt"
|
|
|
|
TMPDIR_DL=$(mktemp -d)
|
|
trap 'rm -rf "$TMPDIR_DL"' EXIT
|
|
|
|
echo "Downloading ${URL}..."
|
|
curl -fSL --progress-bar -o "${TMPDIR_DL}/${FILENAME}" "$URL"
|
|
|
|
# Verify checksum if sha256sum/shasum is available
|
|
if curl -fsSL -o "${TMPDIR_DL}/checksums.txt" "$CHECKSUM_URL" 2>/dev/null; then
|
|
expected=$(awk -v filename="$FILENAME" '$2 == filename { print $1; exit }' "${TMPDIR_DL}/checksums.txt")
|
|
if [[ -n "$expected" ]]; then
|
|
if command -v sha256sum >/dev/null 2>&1; then
|
|
actual=$(sha256sum "${TMPDIR_DL}/${FILENAME}" | awk '{print $1}')
|
|
elif command -v shasum >/dev/null 2>&1; then
|
|
actual=$(shasum -a 256 "${TMPDIR_DL}/${FILENAME}" | awk '{print $1}')
|
|
else
|
|
actual=""
|
|
echo "Warning: no sha256sum/shasum found; skipping checksum verification." >&2
|
|
fi
|
|
if [[ -n "$actual" && "$actual" != "$expected" ]]; then
|
|
echo "Error: checksum mismatch (expected ${expected}, got ${actual})" >&2
|
|
exit 1
|
|
fi
|
|
[[ -n "$actual" ]] && echo "Checksum verified."
|
|
else
|
|
echo "Warning: checksum not found in checksums.txt; skipping verification." >&2
|
|
fi
|
|
else
|
|
echo "Warning: could not fetch checksums.txt; skipping checksum verification." >&2
|
|
fi
|
|
|
|
tar -xzf "${TMPDIR_DL}/${FILENAME}" -C "$TMPDIR_DL"
|
|
|
|
BINARY_PATH="${TMPDIR_DL}/${BINARY}"
|
|
if [[ ! -f "$BINARY_PATH" ]]; then
|
|
BINARY_PATH=$(find "$TMPDIR_DL" -type f -name "$BINARY" -print -quit)
|
|
fi
|
|
|
|
if [[ -z "$BINARY_PATH" || ! -f "$BINARY_PATH" ]]; then
|
|
echo "Error: binary not found in archive." >&2
|
|
exit 1
|
|
fi
|
|
|
|
# ── Install ──────────────────────────────────────────────────────────────────
|
|
|
|
mkdir -p "$INSTALL_DIR"
|
|
mv "$BINARY_PATH" "${INSTALL_DIR}/${BINARY}"
|
|
chmod +x "${INSTALL_DIR}/${BINARY}"
|
|
|
|
echo "Installed ${BINARY} to ${INSTALL_DIR}/${BINARY}"
|
|
|
|
# ── PATH hint ────────────────────────────────────────────────────────────────
|
|
|
|
if ! echo "$PATH" | tr ':' '\n' | grep -qx "$INSTALL_DIR"; then
|
|
echo ""
|
|
echo "Add browseros-cli to your PATH:"
|
|
echo ""
|
|
|
|
SHELL_NAME=$(basename "${SHELL:-/bin/bash}")
|
|
case "$SHELL_NAME" in
|
|
zsh) echo " echo 'export PATH=\"${INSTALL_DIR}:\$PATH\"' >> ~/.zshrc && source ~/.zshrc" ;;
|
|
fish) echo " fish_add_path ${INSTALL_DIR}" ;;
|
|
*) echo " echo 'export PATH=\"${INSTALL_DIR}:\$PATH\"' >> ~/.bashrc && source ~/.bashrc" ;;
|
|
esac
|
|
fi
|
|
|
|
echo ""
|
|
echo "Run 'browseros-cli --help' to get started."
|