Files
nextcraft/scripts/install.sh
T
CIAgent 2c68b44c1a merge: milestone/v0.4-distribution → main (v0.4 Distribution & Bootstrap CLI complete)
The nextcraft bootstrap CLI ships: doctor/bootstrap/verify/dev commands, a
one-liner install script with checksum + version integrity gates, and linux
x64 SEA binaries published on every release going forward (v0.3.2 onward).
Fresh-clone E2E proven; 34 CLI tests + full monorepo gates green.

Escalation note: merge_to_main hook — proceeding per full autonomy + founder
directive D-016 (streamlined install + bootstrap CLI + ongoing binaries,
recorded at P0 SPECIFY).

---ci---
phase: 4
milestone: v0.4
status: complete
requirements:
  covered: [REQ-4-001, REQ-4-002, REQ-4-003, REQ-4-004, REQ-4-005]
  partial: []
---/ci---
2026-09-12 23:17:43 +00:00

97 lines
4.0 KiB
Bash
Executable File

#!/bin/sh
# Nextcraft CLI installer — the one-liner:
# curl -fsSL https://git.coreci.dev/coreci/nextcraft/raw/main/scripts/install.sh | sh
# Resolves the latest release from the Gitea API, downloads the linux x64 binary
# + sha256 sidecar, verifies the checksum, installs to ~/.local/bin.
# Any failure degrades to printed source-bootstrap instructions (G-103) — never
# installs an unverified artifact. Checksum mismatch = hard stop (exit 1).
set -eu
FORGE_BASE="${NEXTCRAFT_FORGE_BASE:-https://git.coreci.dev}"
OWNER="coreci"
REPO="nextcraft"
DEST="${DEST:-$HOME/.local/bin}"
API="$FORGE_BASE/api/v1/repos/$OWNER/$REPO/releases/latest"
say() { printf '%s\n' "$*"; }
die() { printf '%s\n' "$*" >&2; exit 1; }
[ "$(uname -s)" = "Linux" ] && [ "$(uname -m)" = "x86_64" ] || {
say "nextcraft: no binary for $(uname -s)/$(uname -m) (linux x64 only for now)."
say "Source bootstrap instead:"
say " git clone $FORGE_BASE/$OWNER/$REPO.git && cd $REPO"
say " pnpm --filter @nextcraft/cli dev -- doctor # or scripts/bootstrap.sh path"
exit 0
}
command -v curl >/dev/null 2>&1 || {
say "nextcraft: curl is required. Install curl, or source bootstrap:"
say " git clone $FORGE_BASE/$OWNER/$REPO.git"
exit 0
}
RELEASE_JSON="$(curl -fsSL "$API" 2>/dev/null)" || {
say "nextcraft: could not reach $API."
say "Source bootstrap instead: git clone $FORGE_BASE/$OWNER/$REPO.git"
exit 0
}
TAG="$(printf '%s' "$RELEASE_JSON" | sed -n 's/.*"tag_name":"\([^"]*\)".*/\1/p' | head -1)"
BIN_URL="$(printf '%s' "$RELEASE_JSON" | sed -n 's/.*"browser_download_url":"\([^"]*nextcraft-linux-x64\)".*/\1/p' | head -1)"
SUM_URL="$(printf '%s' "$RELEASE_JSON" | sed -n 's/.*"browser_download_url":"\([^"]*nextcraft-linux-x64\.sha256\)".*/\1/p' | head -1)"
if [ -z "$TAG" ] || [ -z "$BIN_URL" ] || [ -z "$SUM_URL" ]; then
say "nextcraft: latest release ($TAG) has no linux x64 binary assets yet."
say "Source bootstrap instead:"
say " git clone $FORGE_BASE/$OWNER/$REPO.git && cd $REPO"
say " pnpm install && pnpm --filter @nextcraft/cli dev -- doctor"
exit 0
fi
TMP="$(mktemp -d)"
trap 'rm -rf "$TMP"' EXIT
say "nextcraft: downloading $TAG ..."
curl -fsSL "$BIN_URL" -o "$TMP/nextcraft-linux-x64" || {
say "nextcraft: download failed. Source bootstrap: git clone $FORGE_BASE/$OWNER/$REPO.git"
exit 0
}
curl -fsSL "$SUM_URL" -o "$TMP/nextcraft-linux-x64.sha256" || {
say "nextcraft: checksum download failed — refusing to install unverified binary."
say "Source bootstrap instead: git clone $FORGE_BASE/$OWNER/$REPO.git"
exit 0
}
EXPECTED="$(sed 's/ .*$//' "$TMP/nextcraft-linux-x64.sha256" | tr -d '[:space:]')"
if command -v sha256sum >/dev/null 2>&1; then
ACTUAL="$(sha256sum "$TMP/nextcraft-linux-x64" | sed 's/ .*$//')"
elif command -v shasum >/dev/null 2>&1; then
ACTUAL="$(shasum -a 256 "$TMP/nextcraft-linux-x64" | sed 's/ .*$//')"
else
die "nextcraft: no sha256 tool available — cannot verify. DO NOT install an unverified binary. Install sha256sum (coreutils) and retry."
fi
[ "$ACTUAL" = "$EXPECTED" ] || die "nextcraft: CHECKSUM MISMATCH for $TAG — do not run this binary. Aborting."
mkdir -p "$DEST"
mv "$TMP/nextcraft-linux-x64" "$DEST/nextcraft"
chmod +x "$DEST/nextcraft"
say "nextcraft: installed $DEST/nextcraft ($TAG)"
INSTALLED_VERSION="$("$DEST/nextcraft" --version 2>/dev/null || true)"
if [ -n "$INSTALLED_VERSION" ] && [ "$INSTALLED_VERSION" != "$TAG" ]; then
die "nextcraft: binary reports version $INSTALLED_VERSION but release is $TAG — integrity mismatch. Remove $DEST/nextcraft and re-run the installer."
fi
say "nextcraft: verified binary version: ${INSTALLED_VERSION:-$TAG}"
case ":$PATH:" in
*":$DEST:"*) ;;
*)
say ""
say "$DEST is not on your PATH. Add it:"
say " echo 'export PATH=\"$DEST:\$PATH\"' >> ~/.profile && source ~/.profile"
;;
esac
say ""
say "Next steps:"
say " nextcraft doctor # check prerequisites"
say " git clone $FORGE_BASE/$OWNER/$REPO.git && cd nextcraft"
say " nextcraft bootstrap # set up the monorepo"
say " nextcraft verify && nextcraft dev"