AkurAI Build
Menu

Public repository / 655e1bde70b69d9670a06f2dd4a515651c694f8e

AkurAI-Framework / deploy.sh

Latest change 4052fe38094b95ffabeaa0959c653900e383f343 - feat: markdown engine + authentic framework site (landing/docs/changelog/components) by Ólafur Búi Ólafsson

#!/usr/bin/env bash
# deploy.sh — AkurAI-Framework release engine.
#
#   ./deploy.sh [patch|minor|major]   (default: patch)
#
# Runs the quality gate, bumps the version lockstep, cuts the CHANGELOG,
# tags, and pushes — creating the GitHub repo on first run if it is missing.
set -euo pipefail

REPO="olibuijr/AkurAI-Framework"
ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
cd "$ROOT"

say() { printf '\033[1;34m▸ %s\033[0m\n' "$*"; }
die() { printf '\033[1;31m✗ %s\033[0m\n' "$*" >&2; exit 1; }

# ── EC2 deploy mode ────────────────────────────────────────────────────────
# `./deploy.sh ec2` builds the static binary and ships the running site to the
# AkurAI AWS box behind nginx, using the reusable `akurai-ec2` ops CLI. Idempotent.
if [ "${1:-}" = "ec2" ]; then
  command -v akurai-ec2 >/dev/null || die "akurai-ec2 not on PATH (see ~/.local/bin/akurai-ec2)"
  DOMAIN="akurai-framework.olibuijr.com"; PORT=8094; NAME="akurai-framework"
  MUSL=target/x86_64-unknown-linux-musl/release/akurai

  say "Build: static musl binary"
  rustup target add x86_64-unknown-linux-musl >/dev/null 2>&1 || true
  cargo build --release --target x86_64-unknown-linux-musl -p akurai || die "musl build failed"

  # Deploy the framework's own site/ (landing + docs + changelog + components),
  # which the framework serves itself — not a scaffolded starter.
  [ -d site/frontend ] || die "site/ not found"
  akurai-ec2 deploy-binary "$NAME" "$MUSL" "$PORT" site
  akurai-ec2 nginx-proxy "$DOMAIN" "$PORT"
  say "TLS: requesting cert (skips gracefully if DNS hasn't propagated)"
  akurai-ec2 tls "$DOMAIN" || say "  TLS deferred — run 'akurai-ec2 tls $DOMAIN' once DNS resolves"
  say "EC2 deploy complete → https://$DOMAIN"
  exit 0
fi

BUMP="${1:-patch}"
case "$BUMP" in patch|minor|major) ;; *) echo "usage: $0 [patch|minor|major|ec2]" >&2; exit 2 ;; esac

# ── 1. Quality gate ────────────────────────────────────────────────────────
say "Gate: rustfmt"
cargo fmt --all -- --check || die "formatting failed (run: cargo fmt --all)"

say "Gate: clippy (-D warnings)"
cargo clippy --all-targets --all-features -- -D warnings || die "clippy failed"

say "Gate: tests"
cargo test --all || die "tests failed"

if [ -f tests/e2e/package.json ]; then
  say "Gate: Playwright e2e"
  ( cd tests/e2e && npx playwright test ) || die "e2e failed"
fi

if [ -d bench ]; then
  say "Gate: performance budgets"
  cargo bench --bench budgets 2>/dev/null || say "  (no budget bench yet — skipping)"
fi

# ── 2. Version bump (lockstep) ─────────────────────────────────────────────
CUR="$(tr -d '[:space:]' < VERSION)"
IFS='.' read -r MA MI PA <<< "$CUR"
case "$BUMP" in
  major) MA=$((MA+1)); MI=0; PA=0 ;;
  minor) MI=$((MI+1)); PA=0 ;;
  patch) PA=$((PA+1)) ;;
esac
NEW="$MA.$MI.$PA"
say "Version: $CUR → $NEW ($BUMP)"
printf '%s\n' "$NEW" > VERSION
# workspace.package.version is the single source crates inherit via version.workspace = true
sed -i -E "s/^version = \"$CUR\"/version = \"$NEW\"/" Cargo.toml

# ── 3. CHANGELOG ───────────────────────────────────────────────────────────
say "CHANGELOG: cutting [$NEW]"
DATE="$(date +%Y-%m-%d)"
# Replace the "## [Unreleased]" line with a fresh Unreleased + the dated release.
awk -v new="$NEW" -v date="$DATE" '
  /^## \[Unreleased\]/ {
    print "## [Unreleased]"; print "";
    print "## [" new "] - " date;
    next
  }
  { print }
' CHANGELOG.md > CHANGELOG.md.tmp && mv CHANGELOG.md.tmp CHANGELOG.md

# ── 4. Commit, tag, push ───────────────────────────────────────────────────
say "Git: commit + tag v$NEW"
git add -A
git commit -q -m "release: v$NEW"
git tag -a "v$NEW" -m "v$NEW"

if ! git remote get-url origin >/dev/null 2>&1; then
  if gh repo view "$REPO" >/dev/null 2>&1; then
    git remote add origin "https://github.com/$REPO.git"
  else
    say "Creating GitHub repo $REPO (private)"
    gh repo create "$REPO" --private --source=. --remote=origin
  fi
fi

say "Git: push"
git push -u origin HEAD
git push origin "v$NEW"

say "Released v$NEW ✓"