Add update.sh, release-channel tagging, mobile settings page
Nightly Build / build (push) Successful in 6m28s
Nightly Build / build (push) Successful in 6m28s
install.sh / install-nightly.sh:
- Write .release-channel file ('release' or 'nightly') for future updates
- install.sh also writes .release-version (for update --check)
update.sh (new):
- Reads .release-channel to determine which channel to pull from
- Release: checks releases/LATEST vs .release-version, skips if current
- Nightly: always downloads latest
- Stops service before extraction, restarts after
- Rebuilds Python venv on update
ci/package.sh:
- Include update.sh in distribution tarball
Web / mobile:
- Add settings-page component for mobile
- Wire settings page into mobile-app navigation
- Chat page: load current user (/api/auth/me) for sender identity
- Full mobile.css redesign
- i18n: add mobile settings strings (en/fr/it)
This commit is contained in:
@@ -0,0 +1,217 @@
|
||||
#!/usr/bin/env sh
|
||||
# update.sh — update Skald Circle to the latest version on the same channel
|
||||
#
|
||||
# Usage:
|
||||
# ~/.local/share/skald-circle/update.sh
|
||||
#
|
||||
# Reads the .release-channel file written by the installer to determine
|
||||
# whether to pull from the release or nightly channel. On release, checks
|
||||
# the remote LATEST version first and skips the download if already current.
|
||||
#
|
||||
# Stops the service before extracting, then restarts it afterwards.
|
||||
|
||||
set -eu
|
||||
|
||||
# ── Determine install directory ───────────────────────────────────────────────
|
||||
if [ -n "${SKALD_DIR:-}" ]; then
|
||||
INSTALL_DIR="$SKALD_DIR"
|
||||
else
|
||||
INSTALL_DIR="$(cd "$(dirname "$0")" && pwd)"
|
||||
fi
|
||||
|
||||
CHANNEL_FILE="${INSTALL_DIR}/.release-channel"
|
||||
if [ ! -f "$CHANNEL_FILE" ]; then
|
||||
echo "✖ .release-channel not found in ${INSTALL_DIR}" >&2
|
||||
echo " This installation was not created by an installer or is too old." >&2
|
||||
echo " Please reinstall with:" >&2
|
||||
echo " curl -fsSL https://builds.skaldagent.net/install.sh | bash" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
CHANNEL="$(cat "$CHANNEL_FILE" | tr -d '[:space:]')"
|
||||
|
||||
# ── Colours (if terminal) ─────────────────────────────────────────────────────
|
||||
if [ -t 1 ]; then
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
CYAN='\033[0;36m'
|
||||
BOLD='\033[1m'
|
||||
NC='\033[0m'
|
||||
else
|
||||
RED=''; GREEN=''; YELLOW=''; CYAN=''; BOLD=''; NC=''
|
||||
fi
|
||||
|
||||
info() { printf "${GREEN}%s${NC}\n" "$*"; }
|
||||
warn() { printf "${YELLOW}⚠ %s${NC}\n" "$*"; }
|
||||
err() { printf "${RED}✖ %s${NC}\n" "$*"; }
|
||||
header(){ printf "\n${BOLD}%s${NC}\n" "$*"; }
|
||||
banner(){ printf "\n${CYAN}${BOLD}%s${NC}\n" "$*"; }
|
||||
|
||||
# ── Platform detection ────────────────────────────────────────────────────────
|
||||
OS="$(uname -s)"
|
||||
ARCH="$(uname -m)"
|
||||
|
||||
case "$OS" in
|
||||
Linux) OS="linux" ;;
|
||||
Darwin) OS="darwin" ;;
|
||||
*) err "Unsupported OS: $OS"; exit 1 ;;
|
||||
esac
|
||||
|
||||
case "$ARCH" in
|
||||
x86_64)
|
||||
ARCH="amd64"
|
||||
if [ "$OS" = "darwin" ]; then
|
||||
err "Intel Macs are not supported. Apple Silicon (M1+) only."
|
||||
exit 1
|
||||
fi
|
||||
;;
|
||||
aarch64|arm64)
|
||||
ARCH="arm64"
|
||||
;;
|
||||
*) err "Unsupported architecture: $ARCH"; exit 1 ;;
|
||||
esac
|
||||
|
||||
command -v curl >/dev/null 2>&1 || { err "curl is required but not installed."; exit 1; }
|
||||
|
||||
# ── Determine download URL ────────────────────────────────────────────────────
|
||||
BASE_URL="https://builds.skaldagent.net"
|
||||
|
||||
case "$CHANNEL" in
|
||||
release)
|
||||
LATEST="$(curl -fsSL "${BASE_URL}/releases/LATEST" | head -1 | tr -d '[:space:]')"
|
||||
if [ -z "$LATEST" ]; then
|
||||
err "Could not fetch latest release version from ${BASE_URL}/releases/LATEST"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
VERSION_FILE="${INSTALL_DIR}/.release-version"
|
||||
if [ -f "$VERSION_FILE" ]; then
|
||||
CURRENT="$(cat "$VERSION_FILE" | tr -d '[:space:]')"
|
||||
if [ "$CURRENT" = "$LATEST" ]; then
|
||||
info "✔ Already up to date (${CURRENT})."
|
||||
exit 0
|
||||
fi
|
||||
info "🚀 Update available: ${CURRENT} → ${LATEST}"
|
||||
else
|
||||
info "🚀 Installing latest release: ${LATEST}"
|
||||
fi
|
||||
|
||||
VERSION="$LATEST"
|
||||
TARBALL_URL="${BASE_URL}/releases/${VERSION}/skald-circle-${VERSION}-${OS}-${ARCH}.tar.gz"
|
||||
DISPLAY_VERSION="$VERSION"
|
||||
;;
|
||||
|
||||
nightly)
|
||||
TARBALL_URL="${BASE_URL}/nightly/skald-circle-nightly-${OS}-${ARCH}.tar.gz"
|
||||
DISPLAY_VERSION="nightly"
|
||||
info "🚀 Updating to latest nightly build …"
|
||||
;;
|
||||
|
||||
*)
|
||||
err "Unknown channel in ${CHANNEL_FILE}: '${CHANNEL}'"
|
||||
err "Expected 'release' or 'nightly'."
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
# ── Stop service ──────────────────────────────────────────────────────────────
|
||||
stop_service() {
|
||||
case "$OS" in
|
||||
Linux)
|
||||
if command -v systemctl >/dev/null 2>&1; then
|
||||
if systemctl --user is-active skald-circle.service >/dev/null 2>&1; then
|
||||
info "⏹️ Stopping service …"
|
||||
systemctl --user stop skald-circle.service
|
||||
fi
|
||||
fi
|
||||
;;
|
||||
Darwin)
|
||||
if command -v launchctl >/dev/null 2>&1; then
|
||||
if launchctl list com.skald.circle >/dev/null 2>&1; then
|
||||
info "⏹️ Stopping agent …"
|
||||
launchctl unload "$HOME/Library/LaunchAgents/com.skald.circle.plist" 2>/dev/null || true
|
||||
fi
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
# ── Start service ─────────────────────────────────────────────────────────────
|
||||
start_service() {
|
||||
case "$OS" in
|
||||
Linux)
|
||||
if command -v systemctl >/dev/null 2>&1; then
|
||||
info "▶ Starting service …"
|
||||
systemctl --user start skald-circle.service
|
||||
fi
|
||||
;;
|
||||
Darwin)
|
||||
if command -v launchctl >/dev/null 2>&1; then
|
||||
info "▶ Starting agent …"
|
||||
launchctl load "$HOME/Library/LaunchAgents/com.skald.circle.plist" 2>/dev/null || true
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
# ── Main ──────────────────────────────────────────────────────────────────────
|
||||
banner "╔══════════════════════════════════════════╗"
|
||||
banner "║ Skald Circle — Updater (${DISPLAY_VERSION}) ║"
|
||||
banner "╚══════════════════════════════════════════╝"
|
||||
echo ""
|
||||
echo " Channel : ${CHANNEL}"
|
||||
echo " Platform : ${OS}/${ARCH}"
|
||||
echo " Install : ${INSTALL_DIR}"
|
||||
echo ""
|
||||
|
||||
stop_service
|
||||
|
||||
# Download & extract
|
||||
TMP_TARBALL="$(mktemp -t skald-update.XXXXXX.tar.gz)"
|
||||
trap 'rm -f "$TMP_TARBALL"' EXIT
|
||||
|
||||
info "↓ Downloading Skald Circle (${DISPLAY_VERSION}) …"
|
||||
curl -fsSL -o "$TMP_TARBALL" "$TARBALL_URL"
|
||||
|
||||
info "📦 Extracting …"
|
||||
tar xzf "$TMP_TARBALL" -C "$INSTALL_DIR" --strip-components=1
|
||||
|
||||
if [ ! -x "$INSTALL_DIR/bin/skald" ]; then
|
||||
err "Extraction failed — skald binary not found."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Update version file for release channel
|
||||
if [ "$CHANNEL" = "release" ]; then
|
||||
echo "$VERSION" > "$INSTALL_DIR/.release-version"
|
||||
fi
|
||||
|
||||
# Rebuild Python venv (best effort — new deps may have appeared)
|
||||
info "🔧 Rebuilding Python virtual environment …"
|
||||
VENV_DIR="${INSTALL_DIR}/.venv"
|
||||
REQUIREMENTS="${INSTALL_DIR}/requirements.txt"
|
||||
|
||||
rm -rf "$VENV_DIR"
|
||||
if command -v uv >/dev/null 2>&1; then
|
||||
uv venv --seed "$VENV_DIR" && uv pip install -r "$REQUIREMENTS" \
|
||||
&& info "✔ Python venv ready (uv)" \
|
||||
|| warn "Python venv setup failed — Python MCP servers will be unavailable."
|
||||
elif command -v python3 >/dev/null 2>&1; then
|
||||
python3 -m venv "$VENV_DIR" && "$VENV_DIR/bin/pip" install -r "$REQUIREMENTS" \
|
||||
&& info "✔ Python venv ready (pip)" \
|
||||
|| warn "Python venv setup failed — Python MCP servers will be unavailable."
|
||||
else
|
||||
warn "python3 not found — Python MCP servers will be unavailable."
|
||||
fi
|
||||
|
||||
start_service
|
||||
|
||||
# ── Done ──────────────────────────────────────────────────────────────────────
|
||||
echo ""
|
||||
info "✅ Skald Circle updated to ${DISPLAY_VERSION}!"
|
||||
echo ""
|
||||
echo " Status: $( [ "$OS" = "linux" ] && echo "systemctl --user status skald-circle" || echo "launchctl list com.skald.circle" )"
|
||||
echo " Logs: $( [ "$OS" = "linux" ] && echo "journalctl --user -u skald-circle -f" || echo "tail -f ${INSTALL_DIR}/logs/stdout.log" )"
|
||||
echo " Update: ${INSTALL_DIR}/update.sh"
|
||||
echo ""
|
||||
Reference in New Issue
Block a user