mirror of
https://github.com/storytold/artcraft.git
synced 2026-10-24 18:22:29 +00:00
07e9a35044
Brings up a fully local storyteller-web: portable MySQL 8.4 and Redis under a gitignored .devstack/ (plain user processes -- no admin, no services, no WSL, no Docker), all 281 migrations, role/badge seeds, and a demo login with credits. Windows and Linux variants, plus a doctor that reports what is and isn't healthy. Scripts and docs only. Nothing here is compiled into any binary, and no application behaviour changes: the backend it starts is the one that ships. Integrations that cannot be provided locally -- object storage, generation providers, email -- get placeholder credentials, so those endpoints fail when exercised. Swap in a real dev credential for the one you are working on. The doc records exactly which areas that leaves working. An earlier revision closed those gaps with development-only behaviour inside storyteller-web (DEV_FAKE_GENERATION, a filesystem bucket mode, a CDN_BASE_URL override). That is deliberately not here: a switch that exists in the shipped binary can be flipped. Frontend work that wants a populated, working stack should use frontend/apps/fake-storyteller-web instead.
116 lines
3.7 KiB
Bash
Executable File
116 lines
3.7 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# Shared helpers for the dev-stack bootstrap scripts.
|
|
#
|
|
# Usage (from a script that has set ${root_dir}):
|
|
#
|
|
# source "${root_dir}/script/bootstrap/common.sh"
|
|
#
|
|
# See _docs/dev_setup_local_stack.md for the full picture.
|
|
|
|
# Canonical local-dev database identity. These match _docs/dev_setup_server.md,
|
|
# the diesel DATABASE_URL in the repo-root .env, and the server's MYSQL_URL
|
|
# default (crates/schema/config/shared_env_var_config/src/mysql.rs). Override
|
|
# via environment only if your local MySQL differs — most tooling assumes them.
|
|
DEV_MYSQL_DB="${DEV_MYSQL_DB:-storyteller}"
|
|
DEV_MYSQL_USER="${DEV_MYSQL_USER:-storyteller}"
|
|
DEV_MYSQL_PASSWORD="${DEV_MYSQL_PASSWORD:-password}"
|
|
DEV_MYSQL_HOST="${DEV_MYSQL_HOST:-localhost}"
|
|
|
|
# Where the backend listens (BIND_ADDRESS default in
|
|
# storyteller_web/src/startup/build_dependencies.rs).
|
|
DEV_BACKEND_URL="${DEV_BACKEND_URL:-http://localhost:12345}"
|
|
|
|
# Default demo account. The username must NOT be on the reserved-usernames list
|
|
# (includes/binary_includes/usernames/reserved_usernames.txt — "demo", "admin",
|
|
# "test", and "dev" are all reserved) and must match ^[A-Za-z0-9_\-]{3,16}$.
|
|
DEMO_USERNAME="${DEMO_USERNAME:-localdev1}"
|
|
DEMO_PASSWORD="${DEMO_PASSWORD:-localdev1pass}"
|
|
DEMO_EMAIL="${DEMO_EMAIL:-localdev1@example.com}"
|
|
|
|
# Banked credits the demo user's artcraft wallet is seeded/topped-up to.
|
|
# Generation submits are gated on wallet balance, so 0 credits means the
|
|
# generate button silently refuses in the webapp.
|
|
DEMO_CREDITS="${DEMO_CREDITS:-100000}"
|
|
|
|
log() { echo "[bootstrap] $*"; }
|
|
warn() { echo "[bootstrap] WARNING: $*" >&2; }
|
|
die() { echo "[bootstrap] ERROR: $*" >&2; exit 1; }
|
|
|
|
step() {
|
|
echo ""
|
|
echo "=== $* ==="
|
|
}
|
|
|
|
# sudo unless we already are root (CI containers often run as root without sudo).
|
|
maybe_sudo() {
|
|
if [ "$(id -u)" -eq 0 ]; then
|
|
"$@"
|
|
else
|
|
sudo "$@"
|
|
fi
|
|
}
|
|
|
|
confirm() {
|
|
local prompt="$1"
|
|
if [ "${ASSUME_YES:-false}" = "true" ]; then
|
|
return 0
|
|
fi
|
|
local reply
|
|
read -r -p "${prompt} [y/N] " reply
|
|
[[ "${reply}" =~ ^[Yy] ]]
|
|
}
|
|
|
|
# Generate a token in the backend's format: {prefix}{crockford-lower entropy}
|
|
# padded to the same TOTAL length the Rust generators use (tokens crate,
|
|
# impl_crockford_generator!). Alphabet excludes i/l/o/u like Crockford base32.
|
|
new_dev_token() {
|
|
local prefix="$1" total_length="$2"
|
|
local charset="0123456789abcdefghjkmnpqrstvwxyz"
|
|
local count=$((total_length - ${#prefix}))
|
|
local entropy=""
|
|
local i
|
|
for ((i = 0; i < count; i++)); do
|
|
entropy+="${charset:RANDOM%32:1}"
|
|
done
|
|
echo "${prefix}${entropy}"
|
|
}
|
|
|
|
# Run a statement (or stdin) as the storyteller app user against the dev DB.
|
|
# MYSQL_PWD keeps the password off the process list.
|
|
mysql_app() {
|
|
MYSQL_PWD="${DEV_MYSQL_PASSWORD}" mysql \
|
|
-u "${DEV_MYSQL_USER}" -h "${DEV_MYSQL_HOST}" -D "${DEV_MYSQL_DB}" "$@"
|
|
}
|
|
|
|
# Run a statement as an administrator, for provisioning the DB and user.
|
|
# On a fresh Ubuntu/WSL install, root uses auth_socket, so `sudo mysql` works.
|
|
# On GitHub Actions runners the preinstalled MySQL root password is "root" —
|
|
# export MYSQL_ROOT_PASSWORD to use password auth instead.
|
|
mysql_admin() {
|
|
if [ -n "${MYSQL_ROOT_PASSWORD:-}" ]; then
|
|
MYSQL_PWD="${MYSQL_ROOT_PASSWORD}" mysql -u root -h "${DEV_MYSQL_HOST}" "$@"
|
|
else
|
|
maybe_sudo mysql "$@"
|
|
fi
|
|
}
|
|
|
|
mysql_app_reachable() {
|
|
mysql_app -e "SELECT 1" >/dev/null 2>&1
|
|
}
|
|
|
|
redis_reachable() {
|
|
redis-cli ping 2>/dev/null | grep -q PONG
|
|
}
|
|
|
|
backend_reachable() {
|
|
curl -sf -o /dev/null --max-time 3 "${DEV_BACKEND_URL}/_status"
|
|
}
|
|
|
|
# Make ~/.cargo/bin visible when rustup was installed but the shell profile
|
|
# hasn't been re-sourced (fresh installs, CI).
|
|
ensure_cargo_on_path() {
|
|
if ! command -v cargo >/dev/null 2>&1 && [ -x "${HOME}/.cargo/bin/cargo" ]; then
|
|
export PATH="${HOME}/.cargo/bin:${PATH}"
|
|
fi
|
|
}
|