Compare commits
No commits in common. "e5e82f30852bf6358a336d923a974627280a04a0" and "7935469776795ae5b149cc8f80fbe2d322887476" have entirely different histories.
e5e82f3085
...
7935469776
43
CLAUDE.md
43
CLAUDE.md
|
|
@ -23,36 +23,12 @@ Personal web appliance that auto-discovers and runs multiple web apps on your ho
|
||||||
## Running
|
## Running
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
bun run dev # Hot reload (rebuilds client bundle on change)
|
bun run dev # Hot reload (deletes pub/client/index.js first)
|
||||||
bun run start # Production (generates templates, then runs server)
|
bun run start # Production
|
||||||
bun run check # Type check
|
bun run check # Type check
|
||||||
bun run test # Tests
|
bun run test # Tests
|
||||||
bun run build # Build client JS bundle (pub/client/index.js)
|
|
||||||
bun run release # Build release tarball for the Pi
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## Building & Releasing
|
|
||||||
|
|
||||||
`bun run release` (runs `scripts/release.sh`) produces a self-contained tarball the Pi can install without building anything:
|
|
||||||
|
|
||||||
1. Client JS bundle → `pub/client/index.js`
|
|
||||||
2. Embedded templates → `src/lib/templates.data.ts` (generated from `templates/` by `scripts/embed-templates.ts`)
|
|
||||||
3. Pre-built bare git repos for bundled apps → `dist/repos/*.git` (built by `scripts/build-repos.sh`)
|
|
||||||
4. Cross-compiled CLI binary → `dist/toes` (linux-arm64, built by `scripts/build.ts`)
|
|
||||||
5. Everything staged and packed into `dist/toes-<version>.tar.gz`
|
|
||||||
|
|
||||||
The Pi installer (`install/install.sh`) downloads this tarball, runs `bun install` for the server and all bundled apps (in parallel), copies pre-built repos and CLI binary into place, and starts the systemd service. No git commands, no compilation on the Pi.
|
|
||||||
|
|
||||||
### Key scripts
|
|
||||||
|
|
||||||
- `scripts/build.sh` -- Builds client JS bundle only (used during dev)
|
|
||||||
- `scripts/build-repos.sh` -- Pre-builds bare git repos for bundled apps (excludes node_modules, snapshots, logs)
|
|
||||||
- `scripts/release.sh` -- Full release pipeline: client + templates + repos + CLI → tarball
|
|
||||||
- `scripts/build.ts` -- CLI binary compiler (current platform or `--all` for cross-compile)
|
|
||||||
- `scripts/embed-templates.ts` -- Generates `src/lib/templates.data.ts` from `templates/`
|
|
||||||
- `install/install.sh` -- Pi installer, downloads release tarball and sets everything up
|
|
||||||
- `scripts/remote-install.sh` -- Runs the installer on a remote Pi over SSH
|
|
||||||
|
|
||||||
## Project Structure
|
## Project Structure
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
@ -259,21 +235,6 @@ function start(app: App): void {
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
## Install & Deployment
|
|
||||||
|
|
||||||
The install script (`install/install.sh`) is designed to run on a fresh Pi or as an updater:
|
|
||||||
|
|
||||||
1. Installs system packages (git, fish, avahi-utils, etc.) via apt
|
|
||||||
2. Installs Bun and grants `cap_net_bind_service`
|
|
||||||
3. Downloads and extracts the release tarball into `~/toes`
|
|
||||||
4. Runs `bun install` for the server
|
|
||||||
5. Copies bundled apps to `~/apps/` and runs `bun install` for each (in parallel)
|
|
||||||
6. Copies pre-built bare repos to `~/data/repos/` (for git-based versioning)
|
|
||||||
7. Installs the pre-built CLI binary to `/usr/local/bin/toes`
|
|
||||||
8. Sets up SSH access and the systemd service
|
|
||||||
|
|
||||||
The release tarball URL is configured as `RELEASE_URL` at the top of `install/install.sh`.
|
|
||||||
|
|
||||||
## Writing Apps and Tools
|
## Writing Apps and Tools
|
||||||
|
|
||||||
See `docs/GUIDE.md` for the guide to writing toes apps and tools.
|
See `docs/GUIDE.md` for the guide to writing toes apps and tools.
|
||||||
|
|
|
||||||
85
README.md
85
README.md
|
|
@ -1,69 +1,42 @@
|
||||||
# 🐾 Toes
|
# 🐾 Toes
|
||||||
|
|
||||||
Personal web appliance you run on your home network.
|
Toes is a personal web appliance you run on your home network.
|
||||||
|
|
||||||
Plug it in, turn it on, and forget about the cloud.
|
Plug it in, turn it on, and forget about the cloud.
|
||||||
|
|
||||||
## Development
|
## setup
|
||||||
|
|
||||||
```bash
|
Toes runs on a Raspberry Pi. You'll need:
|
||||||
bun run dev # Hot reload (rebuilds client bundle on change)
|
|
||||||
bun run start # Production mode
|
|
||||||
bun run check # Type check
|
|
||||||
bun run test # Tests
|
|
||||||
bun run build # Build client JS bundle
|
|
||||||
bun run release # Build a release tarball for the Pi
|
|
||||||
```
|
|
||||||
|
|
||||||
### Releasing
|
- A Raspberry Pi 5 running the latest Raspberry Pi OS
|
||||||
|
- A `toes` user with passwordless sudo
|
||||||
|
|
||||||
`bun run release` builds everything the Pi needs into a single tarball:
|
SSH into your Pi as the `toes` user and run:
|
||||||
|
|
||||||
1. Client JS bundle (`pub/client/index.js`)
|
|
||||||
2. Embedded templates (`src/lib/templates.data.ts`)
|
|
||||||
3. Pre-built bare git repos for bundled apps (`dist/repos/`)
|
|
||||||
4. Cross-compiled CLI binary for linux-arm64 (`dist/toes`)
|
|
||||||
|
|
||||||
Output: `dist/toes-<version>.tar.gz`
|
|
||||||
|
|
||||||
The Pi does zero building — it untars, runs `bun install`, and starts. Upload the tarball to wherever `RELEASE_URL` in `install/install.sh` points (currently `https://toes.dev/release/latest.tar.gz`).
|
|
||||||
|
|
||||||
### Scripts
|
|
||||||
|
|
||||||
| Script | What it does |
|
|
||||||
|--------|-------------|
|
|
||||||
| `scripts/build.sh` | Builds the client JS bundle into `pub/client/index.js` |
|
|
||||||
| `scripts/build-repos.sh` | Pre-builds bare git repos for bundled apps in `dist/repos/` |
|
|
||||||
| `scripts/release.sh` | Full release: client + templates + repos + CLI → tarball |
|
|
||||||
| `scripts/build.ts` | Builds the CLI binary (current platform or cross-compile) |
|
|
||||||
| `scripts/embed-templates.ts` | Generates `src/lib/templates.data.ts` from `templates/` |
|
|
||||||
| `scripts/setup-ssh.sh` | Configures SSH access for the `cli` user on the Pi |
|
|
||||||
| `scripts/remote-install.sh` | Runs the installer on a remote Pi over SSH |
|
|
||||||
|
|
||||||
## Setup
|
|
||||||
|
|
||||||
Toes runs on a Raspberry Pi 5 with a `toes` user and passwordless sudo.
|
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
curl -fsSL https://toes.dev/install | bash
|
curl -fsSL https://toes.dev/install | bash
|
||||||
```
|
```
|
||||||
|
|
||||||
The installer downloads the release tarball, installs bun and system packages, runs `bun install` for the server and all bundled apps (in parallel), copies the pre-built CLI and git repos into place, and starts the systemd service.
|
This will:
|
||||||
|
|
||||||
Dashboard: `http://<hostname>.local`
|
1. Install system dependencies (git, fish shell, networking tools)
|
||||||
|
2. Install Bun and grant it network binding capabilities
|
||||||
|
3. Clone and build the toes server
|
||||||
|
4. Set up bundled apps and tools (clock, code, cron, env, stats)
|
||||||
|
5. Install and enable a systemd service for auto-start
|
||||||
|
|
||||||
## Features
|
Once complete, visit `http://<hostname>.local` on your local network.
|
||||||
|
|
||||||
- Hosts Bun/Hype webapps (SSR and SPA)
|
## features
|
||||||
- `git push` Heroku-style deploys
|
|
||||||
- Web dashboard with real-time status, logs, and tools
|
|
||||||
- `toes` CLI (local install or SSH)
|
|
||||||
- Per-app environment variables, cron jobs, metrics
|
|
||||||
- Public sharing via tunnels
|
|
||||||
|
|
||||||
## SSH CLI
|
- Effortlessly hosts bun/hype webapps - both SSR and SPA.
|
||||||
|
- `git push`, Heroku-style deploys
|
||||||
|
- https://toes.local web UI for managing your projects.
|
||||||
|
- `toes` CLI for managing your projects.
|
||||||
|
|
||||||
Manage your server from any machine on the network — no install required.
|
## ssh cli
|
||||||
|
|
||||||
|
You can manage your toes server from any machine on your network over SSH — no install required.
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
ssh cli@toes.local # interactive shell with tab completion
|
ssh cli@toes.local # interactive shell with tab completion
|
||||||
|
|
@ -71,12 +44,24 @@ ssh cli@toes.local list # run a single command
|
||||||
ssh cli@toes.local logs fog # stream logs for an app
|
ssh cli@toes.local logs fog # stream logs for an app
|
||||||
```
|
```
|
||||||
|
|
||||||
## CLI Configuration
|
The `cli` user's login shell is the `toes` binary itself. No password is needed. With no arguments, you get an interactive REPL. With arguments, it runs the command and exits.
|
||||||
|
|
||||||
By default, the CLI connects to `localhost:3000` in dev and `toes.local:80` in production.
|
## cli configuration
|
||||||
|
|
||||||
|
by default, the CLI connects to `localhost:3000` in dev and `toes.local:80` in production.
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
toes config # show current host
|
toes config # show current host
|
||||||
TOES_URL=http://192.168.1.50:3000 toes list # connect to IP
|
TOES_URL=http://192.168.1.50:3000 toes list # connect to IP
|
||||||
TOES_URL=http://mypi.local toes list # connect to hostname
|
TOES_URL=http://mypi.local toes list # connect to hostname
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## fun stuff
|
||||||
|
|
||||||
|
- textOS (TODO, more?)
|
||||||
|
- Claude that knows about all your toes APIS and your projects.
|
||||||
|
- non-webapps
|
||||||
|
|
||||||
|
## february goal
|
||||||
|
|
||||||
|
- [ ] Corey and Chris are running Toes servers on their home networks, hosting personal projects and games.
|
||||||
|
|
|
||||||
|
|
@ -1,81 +0,0 @@
|
||||||
# Rev Webhooks for Toes
|
|
||||||
|
|
||||||
Deploy Toes apps by saving to rev.host — no manual deploy step, no rsync scripts.
|
|
||||||
|
|
||||||
## How It Works
|
|
||||||
|
|
||||||
```
|
|
||||||
rev save "fix combat" → rev.host → relay (sneaker.toes.space) → toes.local pulls + deploys
|
|
||||||
```
|
|
||||||
|
|
||||||
toes.local can't receive inbound connections (home NAT), so it maintains an outbound connection to a relay — same tunnel infrastructure used by `toes share`.
|
|
||||||
|
|
||||||
## Setup Flow
|
|
||||||
|
|
||||||
1. In the Toes dashboard (or `toes` CLI via SSH), enable rev webhooks for an app
|
|
||||||
2. Toes connects to the relay and gets a stable webhook URL
|
|
||||||
3. Add that URL in rev.host project settings as a webhook endpoint
|
|
||||||
4. Done — `rev save` and `rev merge` now trigger deploys
|
|
||||||
|
|
||||||
## What Toes Does on Webhook
|
|
||||||
|
|
||||||
1. Receives event from relay (repo, ref, timestamp)
|
|
||||||
2. Pulls latest from rev.host (needs a rev auth token stored in Toes env)
|
|
||||||
3. Runs `scripts.predeploy` if defined in package.json (type-check, build, etc.)
|
|
||||||
4. Runs `bun install`
|
|
||||||
5. Restarts the app
|
|
||||||
|
|
||||||
## CLI
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Enable/disable rev webhooks
|
|
||||||
toes webhook enable [name] # Shows the relay URL to paste into rev.host
|
|
||||||
toes webhook disable [name]
|
|
||||||
|
|
||||||
# Manual trigger (pull latest and deploy now)
|
|
||||||
toes deploy [name]
|
|
||||||
|
|
||||||
# Check webhook status
|
|
||||||
toes webhook status [name]
|
|
||||||
```
|
|
||||||
|
|
||||||
## Settings UI
|
|
||||||
|
|
||||||
App settings page gets a "Rev Webhooks" section:
|
|
||||||
- Toggle to enable/disable
|
|
||||||
- Displays the relay URL (copy button)
|
|
||||||
- Field for rev.host auth token
|
|
||||||
- Last deploy timestamp + status
|
|
||||||
- "Deploy Now" button (manual trigger)
|
|
||||||
|
|
||||||
## Auth
|
|
||||||
|
|
||||||
Toes needs read access to pull from rev.host. Store a rev API token per-app (or globally):
|
|
||||||
|
|
||||||
```bash
|
|
||||||
toes env set -g REV_TOKEN rt_abc123
|
|
||||||
# or per-app
|
|
||||||
toes env set my-app REV_TOKEN rt_abc123
|
|
||||||
```
|
|
||||||
|
|
||||||
## Predeploy Scripts
|
|
||||||
|
|
||||||
Project-specific build steps go in package.json:
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"scripts": {
|
|
||||||
"toes": "bun run --watch index.tsx",
|
|
||||||
"predeploy": "bunx tsc --noEmit && bun build client/main.tsx --outdir dist --minify"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
Toes runs `predeploy` after pulling but before restarting. If it exits non-zero, the deploy is aborted and the previous version stays running.
|
|
||||||
|
|
||||||
## Open Questions
|
|
||||||
|
|
||||||
- Should the relay URL be per-app or per-Toes-instance? (Per-instance with app routing via path seems simpler: `https://sneaker.toes.space/hooks/<instance-id>/<app-name>`)
|
|
||||||
- Webhook secret/signature verification — rev.host should sign payloads so the relay can't be spoofed
|
|
||||||
- Should `toes deploy` work without webhooks enabled? (Just pull from rev.host on demand — useful as a migration path from deploy.sh)
|
|
||||||
- Rollback: `toes rollback [name]` to revert to previous rev version?
|
|
||||||
|
|
@ -8,7 +8,7 @@ set -euo pipefail
|
||||||
# Installs or updates toes on a Raspberry Pi.
|
# Installs or updates toes on a Raspberry Pi.
|
||||||
# Must be run as the 'toes' user with passwordless sudo.
|
# Must be run as the 'toes' user with passwordless sudo.
|
||||||
|
|
||||||
RELEASE_URL="https://toes.dev/release/latest.tar.gz"
|
REPO="https://git.nose.space/defunkt/toes"
|
||||||
DEST=~/toes
|
DEST=~/toes
|
||||||
APPS_DIR=~/apps
|
APPS_DIR=~/apps
|
||||||
DATA_DIR=~/data
|
DATA_DIR=~/data
|
||||||
|
|
@ -59,55 +59,68 @@ sudo ln -sf "$BUN" /usr/local/bin/bun
|
||||||
|
|
||||||
sudo setcap 'cap_net_bind_service=+ep' "$BUN"
|
sudo setcap 'cap_net_bind_service=+ep' "$BUN"
|
||||||
|
|
||||||
# ── Download ─────────────────────────────────────────────
|
# ── Clone or pull ────────────────────────────────────────
|
||||||
|
|
||||||
info "Downloading toes"
|
if [ -d "$DEST/.git" ]; then
|
||||||
mkdir -p "$DEST"
|
info "Pulling latest toes"
|
||||||
curl -fsSL "$RELEASE_URL" | tar xz --strip-components=1 -C "$DEST"
|
git -C "$DEST" fetch origin main
|
||||||
|
git -C "$DEST" reset --hard origin/main
|
||||||
|
else
|
||||||
|
info "Cloning toes"
|
||||||
|
git clone "$REPO" "$DEST"
|
||||||
|
fi
|
||||||
|
|
||||||
# ── Directories ──────────────────────────────────────────
|
# ── Directories ──────────────────────────────────────────
|
||||||
|
|
||||||
mkdir -p "$APPS_DIR" "$DATA_DIR" "$DATA_DIR/toes"
|
mkdir -p "$APPS_DIR" "$DATA_DIR" "$DATA_DIR/toes"
|
||||||
|
|
||||||
# ── Dependencies ─────────────────────────────────────────
|
# ── Dependencies & build ─────────────────────────────────
|
||||||
|
|
||||||
cd "$DEST"
|
cd "$DEST"
|
||||||
|
|
||||||
info "Installing dependencies"
|
info "Installing dependencies"
|
||||||
quiet bun install
|
quiet bun install
|
||||||
|
|
||||||
|
info "Building"
|
||||||
|
rm -rf "$DEST/dist"
|
||||||
|
quiet bun run build
|
||||||
|
|
||||||
# ── Bundled apps ─────────────────────────────────────────
|
# ── Bundled apps ─────────────────────────────────────────
|
||||||
|
|
||||||
REPOS_DIR="$DATA_DIR/repos"
|
REPOS_DIR="$DATA_DIR/repos"
|
||||||
mkdir -p "$REPOS_DIR"
|
mkdir -p "$REPOS_DIR"
|
||||||
|
|
||||||
info "Installing bundled apps"
|
info "Installing bundled apps"
|
||||||
pids=()
|
|
||||||
for app_dir in "$DEST"/apps/*/; do
|
for app_dir in "$DEST"/apps/*/; do
|
||||||
app=$(basename "$app_dir")
|
app=$(basename "$app_dir")
|
||||||
[ -f "$app_dir/package.json" ] || continue
|
[ -f "$app_dir/package.json" ] || continue
|
||||||
echo " $app"
|
echo " $app"
|
||||||
(
|
|
||||||
cp -a "$app_dir" "$APPS_DIR/$app"
|
cp -a "$app_dir" "$APPS_DIR/$app"
|
||||||
quiet bun install --frozen-lockfile --cwd "$APPS_DIR/$app" || quiet bun install --cwd "$APPS_DIR/$app"
|
quiet bun install --frozen-lockfile --cwd "$APPS_DIR/$app" || quiet bun install --cwd "$APPS_DIR/$app"
|
||||||
) &
|
|
||||||
pids+=("$!")
|
|
||||||
done
|
|
||||||
|
|
||||||
for pid in "${pids[@]}"; do
|
# Seed bare repo for git-based versioning
|
||||||
wait "$pid" || fail "A bundled app failed to install."
|
bare="$REPOS_DIR/$app.git"
|
||||||
|
quiet git -C "$APPS_DIR/$app" init -b main
|
||||||
|
quiet git -C "$APPS_DIR/$app" add -A
|
||||||
|
quiet git -C "$APPS_DIR/$app" -c user.name=toes -c user.email=toes@localhost commit -m "install"
|
||||||
|
if [ -d "$bare" ]; then
|
||||||
|
quiet git -C "$APPS_DIR/$app" push --force "$bare" main
|
||||||
|
else
|
||||||
|
quiet git clone --bare "$APPS_DIR/$app" "$bare"
|
||||||
|
quiet git -C "$bare" config http.receivepack true
|
||||||
|
fi
|
||||||
|
rm -rf "$APPS_DIR/$app/.git"
|
||||||
done
|
done
|
||||||
|
|
||||||
# Copy pre-built bare repos for git-based versioning
|
|
||||||
cp -a "$DEST"/dist/repos/*.git "$REPOS_DIR/"
|
|
||||||
|
|
||||||
# ── CLI + SSH ────────────────────────────────────────────
|
# ── CLI + SSH ────────────────────────────────────────────
|
||||||
|
|
||||||
info "Setting up SSH access"
|
info "Setting up SSH access"
|
||||||
sudo bash "$DEST/scripts/setup-ssh.sh"
|
sudo bash "$DEST/scripts/setup-ssh.sh"
|
||||||
|
|
||||||
info "Installing CLI"
|
info "Installing CLI"
|
||||||
sudo install -m 755 "$DEST/dist/toes" /usr/local/bin/toes
|
sudo rm -f /usr/local/bin/toes
|
||||||
|
bun run cli:build
|
||||||
|
sudo cp dist/toes /usr/local/bin/toes
|
||||||
|
|
||||||
# ── Systemd ──────────────────────────────────────────────
|
# ── Systemd ──────────────────────────────────────────────
|
||||||
|
|
||||||
|
|
@ -121,7 +134,7 @@ sudo systemctl restart toes
|
||||||
|
|
||||||
# ── Done ─────────────────────────────────────────────────
|
# ── Done ─────────────────────────────────────────────────
|
||||||
|
|
||||||
VERSION=$(grep '"version"' "$DEST/package.json" | head -1 | sed 's/.*"version": *"\(.*\)".*/\1/')
|
VERSION=$(git describe --tags --always 2>/dev/null || echo "unknown")
|
||||||
|
|
||||||
echo ""
|
echo ""
|
||||||
echo " ${b}${g}🐾 toes $VERSION is up!${r}"
|
echo " ${b}${g}🐾 toes $VERSION is up!${r}"
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,6 @@
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"check": "bun run templates && bunx tsc --noEmit",
|
"check": "bun run templates && bunx tsc --noEmit",
|
||||||
"build": "./scripts/build.sh",
|
"build": "./scripts/build.sh",
|
||||||
"release": "./scripts/release.sh",
|
|
||||||
"cli:build": "bun run scripts/build.ts",
|
"cli:build": "bun run scripts/build.ts",
|
||||||
"cli:build:all": "bun run scripts/build.ts --all",
|
"cli:build:all": "bun run scripts/build.ts --all",
|
||||||
"cli:install": "bun cli:build && sudo cp dist/toes /usr/local/bin",
|
"cli:install": "bun cli:build && sudo cp dist/toes /usr/local/bin",
|
||||||
|
|
|
||||||
|
|
@ -1,36 +0,0 @@
|
||||||
#!/usr/bin/env bash
|
|
||||||
# Pre-builds bare git repos for bundled apps so the install script
|
|
||||||
# doesn't need to run any git commands.
|
|
||||||
set -euo pipefail
|
|
||||||
|
|
||||||
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
|
||||||
ROOT="$SCRIPT_DIR/.."
|
|
||||||
APPS_DIR="$ROOT/apps"
|
|
||||||
OUT_DIR="$ROOT/dist/repos"
|
|
||||||
|
|
||||||
rm -rf "$OUT_DIR"
|
|
||||||
mkdir -p "$OUT_DIR"
|
|
||||||
|
|
||||||
for app_dir in "$APPS_DIR"/*/; do
|
|
||||||
app=$(basename "$app_dir")
|
|
||||||
[ -f "$app_dir/package.json" ] || continue
|
|
||||||
|
|
||||||
tmp=$(mktemp -d)
|
|
||||||
tar -C "$app_dir" \
|
|
||||||
--exclude='node_modules' \
|
|
||||||
--exclude='logs' \
|
|
||||||
--exclude='current' \
|
|
||||||
--exclude='[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]-[0-9][0-9][0-9][0-9][0-9][0-9]' \
|
|
||||||
-cf - . | tar -C "$tmp" -xf -
|
|
||||||
|
|
||||||
git -C "$tmp" init -b main -q
|
|
||||||
git -C "$tmp" add -A
|
|
||||||
git -C "$tmp" -c user.name=toes -c user.email=toes@localhost commit -q -m "install"
|
|
||||||
git clone --bare -q "$tmp" "$OUT_DIR/$app.git"
|
|
||||||
git -C "$OUT_DIR/$app.git" config http.receivepack true
|
|
||||||
|
|
||||||
rm -rf "$tmp"
|
|
||||||
echo " $app"
|
|
||||||
done
|
|
||||||
|
|
||||||
echo ">> Bare repos built in dist/repos/"
|
|
||||||
|
|
@ -16,4 +16,3 @@ bun build src/client/index.tsx \
|
||||||
|
|
||||||
echo ">> Client bundle created at pub/client/index.js"
|
echo ">> Client bundle created at pub/client/index.js"
|
||||||
ls -lh pub/client/index.js
|
ls -lh pub/client/index.js
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,85 +0,0 @@
|
||||||
#!/usr/bin/env bash
|
|
||||||
# Builds a release tarball with all artifacts pre-built.
|
|
||||||
# The Pi just untars, runs bun install, and starts.
|
|
||||||
#
|
|
||||||
# Usage: bun run release
|
|
||||||
# Output: dist/toes-<version>.tar.gz
|
|
||||||
set -euo pipefail
|
|
||||||
|
|
||||||
ROOT="$(cd "$(dirname "$0")/.." && pwd)"
|
|
||||||
cd "$ROOT"
|
|
||||||
|
|
||||||
VERSION=$(grep '"version"' package.json | head -1 | sed 's/.*"version": *"\(.*\)".*/\1/')
|
|
||||||
STAGING="$ROOT/dist/toes-$VERSION"
|
|
||||||
|
|
||||||
echo ">> Building toes $VERSION release"
|
|
||||||
|
|
||||||
# ── Clean ────────────────────────────────────────────────
|
|
||||||
|
|
||||||
rm -rf dist
|
|
||||||
mkdir -p dist
|
|
||||||
|
|
||||||
# ── Client bundle ────────────────────────────────────────
|
|
||||||
|
|
||||||
echo ">> Building client bundle"
|
|
||||||
rm -rf pub/client
|
|
||||||
mkdir -p pub/client
|
|
||||||
bun build src/client/index.tsx \
|
|
||||||
--outfile pub/client/index.js \
|
|
||||||
--target browser \
|
|
||||||
--minify
|
|
||||||
|
|
||||||
# ── Embedded templates ───────────────────────────────────
|
|
||||||
|
|
||||||
echo ">> Embedding templates"
|
|
||||||
bun run scripts/embed-templates.ts
|
|
||||||
|
|
||||||
# ── Bare repos ───────────────────────────────────────────
|
|
||||||
|
|
||||||
echo ">> Building bundled app repos"
|
|
||||||
bash scripts/build-repos.sh
|
|
||||||
|
|
||||||
# ── CLI binary (linux-arm64 for Pi) ──────────────────────
|
|
||||||
|
|
||||||
echo ">> Building CLI for linux-arm64"
|
|
||||||
bun build src/cli/index.ts \
|
|
||||||
--compile \
|
|
||||||
--target bun-linux-arm64 \
|
|
||||||
--minify \
|
|
||||||
--sourcemap=external \
|
|
||||||
--define="__GIT_SHA__=\"$VERSION\"" \
|
|
||||||
--outfile dist/toes-linux-arm64
|
|
||||||
|
|
||||||
# ── Stage release ────────────────────────────────────────
|
|
||||||
|
|
||||||
echo ">> Staging release"
|
|
||||||
mkdir -p "$STAGING"
|
|
||||||
|
|
||||||
# Source (excluding dev artifacts)
|
|
||||||
tar -C "$ROOT" \
|
|
||||||
--exclude='node_modules' \
|
|
||||||
--exclude='.git' \
|
|
||||||
--exclude='dist' \
|
|
||||||
--exclude='apps/*/node_modules' \
|
|
||||||
--exclude='apps/*/logs' \
|
|
||||||
--exclude='apps/*/current' \
|
|
||||||
--exclude='apps/*/[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]-[0-9][0-9][0-9][0-9][0-9][0-9]' \
|
|
||||||
-cf - . | tar -C "$STAGING" -xf -
|
|
||||||
|
|
||||||
# Pre-built artifacts
|
|
||||||
cp -a pub/client "$STAGING/pub/client"
|
|
||||||
cp -a dist/repos "$STAGING/dist/repos"
|
|
||||||
mkdir -p "$STAGING/dist"
|
|
||||||
cp dist/toes-linux-arm64 "$STAGING/dist/toes"
|
|
||||||
|
|
||||||
# Generated templates (so the server doesn't need to generate them)
|
|
||||||
cp src/lib/templates.data.ts "$STAGING/src/lib/templates.data.ts"
|
|
||||||
|
|
||||||
# ── Tarball ──────────────────────────────────────────────
|
|
||||||
|
|
||||||
echo ">> Creating tarball"
|
|
||||||
tar -C dist -czf "dist/toes-$VERSION.tar.gz" "toes-$VERSION"
|
|
||||||
rm -rf "$STAGING"
|
|
||||||
|
|
||||||
SIZE=$(du -h "dist/toes-$VERSION.tar.gz" | cut -f1)
|
|
||||||
echo ">> dist/toes-$VERSION.tar.gz ($SIZE)"
|
|
||||||
|
|
@ -11,5 +11,11 @@ source "$ROOT_DIR/scripts/config.sh"
|
||||||
# Run remote install on the target
|
# Run remote install on the target
|
||||||
ssh "$SSH_HOST" bash <<'SCRIPT'
|
ssh "$SSH_HOST" bash <<'SCRIPT'
|
||||||
set -e
|
set -e
|
||||||
curl -fsSL https://toes.dev/install | sh
|
DEST="${DEST:-$HOME/toes}"
|
||||||
|
if [ -d "$DEST/.git" ]; then
|
||||||
|
cd "$DEST" && git pull
|
||||||
|
else
|
||||||
|
git clone https://git.nose.space/defunkt/toes "$DEST" && cd "$DEST"
|
||||||
|
fi
|
||||||
|
./scripts/install.sh
|
||||||
SCRIPT
|
SCRIPT
|
||||||
|
|
|
||||||
|
|
@ -63,6 +63,7 @@ export async function proxySubdomain(subdomain: string, req: Request): Promise<R
|
||||||
headers.set('x-app-url', app.tunnelUrl ?? `${url.protocol}//${subdomain}.${url.hostname}`)
|
headers.set('x-app-url', app.tunnelUrl ?? `${url.protocol}//${subdomain}.${url.hostname}`)
|
||||||
}
|
}
|
||||||
headers.delete('connection')
|
headers.delete('connection')
|
||||||
|
headers.delete('content-length')
|
||||||
headers.delete('keep-alive')
|
headers.delete('keep-alive')
|
||||||
headers.delete('transfer-encoding')
|
headers.delete('transfer-encoding')
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user