Switch Lotus Cinny from nightly dev to stable-release fork workflow
- Replace nightly build script with daily upstream release checker (cinny/upstream-check.sh) — posts to Matrix as LotusBot when a new cinnyapp/cinny stable release is published - Add cinny/lotus-build.sh — merges latest release tag into the lotus branch, builds, deploys; triggered via !cinny-update webhook - Fork lives at code.lotusguild.org/LotusGuild/cinny (lotus branch, v4.11.1) - deploy/hooks-lxc106.json — adds cinny-build webhook endpoint (port 9000) - Update landing page: "dev branch / nightly" → "Lotus fork / stable releases" - Set LotusBot avatar on @hookshot_tinker-tickets Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -19,8 +19,9 @@ matrix/
|
||||
│ ├── uptime-kuma.js
|
||||
│ └── ... # One .js per webhook service
|
||||
├── cinny/
|
||||
│ ├── config.json # Cinny homeserver config (deployed to /var/www/html/config.json)
|
||||
│ └── dev-update.sh # Nightly build script for Cinny dev branch
|
||||
│ ├── config.json # Cinny homeserver config (deployed to /var/www/html/config.json)
|
||||
│ ├── upstream-check.sh # Daily script: checks if cinnyapp/cinny main has new commits, pings Matrix
|
||||
│ └── lotus-build.sh # Merge + build script: fetches upstream/main, merges, builds, deploys
|
||||
├── landing/
|
||||
│ └── index.html # matrix.lotusguild.org landing page
|
||||
├── draupnir/
|
||||
@@ -40,7 +41,7 @@ matrix/
|
||||
├── livekit-graceful-restart.service # oneshot — checks pending restart flag
|
||||
├── livekit-graceful-restart.timer # Runs every 5 min
|
||||
├── draupnir.service
|
||||
└── cinny-dev-update.cron # Installed to /etc/cron.d/ on LXC 106
|
||||
└── cinny-upstream-check.cron # Installed to /etc/cron.d/ on LXC 106 — runs daily at noon
|
||||
```
|
||||
|
||||
---
|
||||
@@ -51,7 +52,7 @@ matrix/
|
||||
|---------|----|-----|-----|------|----------|
|
||||
| Synapse | 10.10.10.29 | 151 | 8GB | 50GB | Synapse 1.149.0, LiveKit 1.9.11, hookshot 7.3.2, coturn latest |
|
||||
| PostgreSQL 17 | 10.10.10.44 | 109 | 6GB | 30GB | PostgreSQL 17.9 |
|
||||
| Cinny Web | 10.10.10.6 | 106 | 2GB | 8GB | Debian 12, nginx, Node 24, Cinny `dev` branch (nightly build) |
|
||||
| Cinny Web | 10.10.10.6 | 106 | 2GB | 8GB | Debian 12, nginx, Node 24, Lotus Cinny fork (custom, tracks `cinnyapp/cinny` main) |
|
||||
| Draupnir | 10.10.10.24 | 110 | 1GB | 10GB | Draupnir v2.9.0, Node.js v22 |
|
||||
| Prometheus | 10.10.10.48 | 118 | — | — | Prometheus — scrapes all Matrix services |
|
||||
| Grafana | 10.10.10.49 | 107 | — | — | Grafana 12.4.0 — dashboard.lotusguild.org |
|
||||
@@ -95,12 +96,18 @@ matrix/
|
||||
- Data directory: `/var/lib/postgresql/17/main`
|
||||
|
||||
**Key paths on Cinny LXC (106):**
|
||||
- Source: `/opt/cinny-dev/` (branch: `dev`, auto-updated nightly at 3am)
|
||||
- Lotus fork source: `/opt/lotus-cinny/` (fork of `cinnyapp/cinny` main, custom Lotus Guild branch)
|
||||
- Upstream remote: `https://github.com/cinnyapp/cinny.git` (added as `upstream`)
|
||||
- Built files: `/var/www/html/`
|
||||
- Cinny config: `/var/www/html/config.json`
|
||||
- Config backup (survives rebuilds): `/opt/cinny-dev/.cinny-config.json`
|
||||
- Dev update script: `/usr/local/bin/cinny-dev-update.sh`
|
||||
- Cron: `/etc/cron.d/cinny-dev-update` (runs at 3:00am daily)
|
||||
- Config backup (survives rebuilds): `/opt/lotus-cinny/.cinny-config.json`
|
||||
- Monitor env: `/etc/cinny-monitor.env` (MATRIX_TOKEN, MATRIX_SERVER, MATRIX_ROOM, MATRIX_PING_USER — not in git)
|
||||
- Upstream check script: `/usr/local/bin/cinny-upstream-check.sh`
|
||||
- Build/deploy script: `/usr/local/bin/cinny-build.sh` (triggered by webhook or manual run)
|
||||
- Cron: `/etc/cron.d/cinny-upstream-check` (runs at noon daily — checks only, does not auto-build)
|
||||
- Monitor state: `/var/lib/cinny-monitor/last-upstream-commit`
|
||||
- Monitor log: `/var/log/cinny-monitor.log`
|
||||
- Build log: `/var/log/cinny-build.log`
|
||||
- Nginx site config: `/etc/nginx/sites-available/cinny`
|
||||
|
||||
---
|
||||
@@ -122,7 +129,7 @@ Pushes to `main` on `LotusGuild/matrix` automatically deploy to the relevant LXC
|
||||
| LXC | Service | IP | Port | Deploys When Changed |
|
||||
|-----|---------|----|----|----------------------|
|
||||
| 151 | matrix/hookshot | 10.10.10.29 | **9500** | `hookshot/*.js`, `systemd/livekit-server.service` |
|
||||
| 106 | cinny | 10.10.10.6 | 9000 | `cinny/config.json`, `cinny/dev-update.sh` |
|
||||
| 106 | cinny | 10.10.10.6 | 9000 | `cinny/config.json`, `cinny/upstream-check.sh`, `cinny/lotus-build.sh`, `deploy/hooks-lxc106.json`, `systemd/cinny-upstream-check.cron` |
|
||||
| 139 | landing/NPM | 10.10.10.27 | 9000 | `landing/index.html` |
|
||||
| 110 | draupnir | 10.10.10.24 | 9000 | `draupnir/production.yaml` |
|
||||
|
||||
@@ -136,7 +143,10 @@ Pushes to `main` on `LotusGuild/matrix` automatically deploy to the relevant LXC
|
||||
|
||||
**LXC 106 — cinny:**
|
||||
- `cinny/config.json` → copies to `/var/www/html/config.json`
|
||||
- `cinny/dev-update.sh` → copies to `/usr/local/bin/cinny-dev-update.sh`, `chmod +x`
|
||||
- `cinny/upstream-check.sh` → copies to `/usr/local/bin/cinny-upstream-check.sh`, `chmod +x`
|
||||
- `cinny/lotus-build.sh` → copies to `/usr/local/bin/cinny-build.sh`, `chmod +x`
|
||||
- `deploy/hooks-lxc106.json` → copies to `/etc/webhook/hooks.json`, restarts `webhook` service
|
||||
- `systemd/cinny-upstream-check.cron` → copies to `/etc/cron.d/cinny-upstream-check`, `chmod 644`
|
||||
|
||||
**LXC 139 — landing page:**
|
||||
- `landing/index.html` → copies to `/var/www/matrix-landing/index.html`, `nginx -s reload`
|
||||
@@ -158,6 +168,13 @@ Pushes to `main` on `LotusGuild/matrix` automatically deploy to the relevant LXC
|
||||
- `/usr/local/bin/livekit-graceful-restart.sh`
|
||||
- `/etc/systemd/system/livekit-graceful-restart.service` + `.timer`
|
||||
|
||||
**LXC 106 additionally:**
|
||||
- `/etc/cinny-monitor.env` — `MATRIX_TOKEN`, `MATRIX_SERVER`, `MATRIX_ROOM`, `MATRIX_PING_USER` (not in git)
|
||||
- `/var/lib/cinny-monitor/last-upstream-commit` — state file (tracks last-seen upstream SHA)
|
||||
- `/opt/lotus-cinny/` — git clone of `code.lotusguild.org/LotusGuild/cinny` with `upstream` remote (`cinnyapp/cinny`)
|
||||
- `/root/.git-credentials` — Gitea token `lxc106-lotus-cinny` (write:repository scope, revocable via Gitea UI)
|
||||
- `/var/lib/cinny-monitor/last-upstream-tag` — last seen stable release tag (e.g. `v4.11.1`)
|
||||
|
||||
### Livekit Graceful Restart
|
||||
|
||||
Killing livekit-server while a call is active drops everyone. Instead:
|
||||
@@ -338,23 +355,57 @@ POST http://10.10.10.24:8080/_matrix/draupnir/1/report/{roomId}/{eventId}
|
||||
|
||||
---
|
||||
|
||||
## Cinny Dev Branch (chat.lotusguild.org)
|
||||
## Lotus Cinny (chat.lotusguild.org)
|
||||
|
||||
`chat.lotusguild.org` tracks the Cinny `dev` branch to test the latest beta features.
|
||||
`chat.lotusguild.org` serves a custom Lotus Guild fork of the official `cinnyapp/cinny` main branch. The fork lives at `code.lotusguild.org/LotusGuild/cinny` and tracks upstream via a `git remote add upstream https://github.com/cinnyapp/cinny.git` workflow.
|
||||
|
||||
**Nightly build process (`cinny-dev-update.sh`):**
|
||||
1. `git fetch origin dev` — checks for new commits; exits early if nothing changed
|
||||
2. Builds in `/opt/cinny-dev/` using Node 24 with `NODE_OPTIONS=--max_old_space_size=896`
|
||||
3. Validates `dist/index.html` exists before touching the live web root
|
||||
4. Copies `dist/` to `/var/www/html/`, restores `config.json` from `/opt/cinny-dev/.cinny-config.json`
|
||||
5. Runs at 3:00am daily via `/etc/cron.d/cinny-dev-update`
|
||||
**Upstream monitoring (daily at noon):**
|
||||
- `cinny-upstream-check.sh` hits the GitHub API and compares the latest `cinnyapp/cinny` main commit against the stored SHA in `/var/lib/cinny-monitor/last-upstream-commit`
|
||||
- If new commits exist, sends a Matrix message to Spam and Stuff with an `@jared:matrix.lotusguild.org` ping and a link to the commit
|
||||
- Does **not** auto-build — you review the diff and decide when to merge
|
||||
|
||||
**Manual rebuild:**
|
||||
**Merge + build workflow:**
|
||||
1. Receive upstream notification in Matrix
|
||||
2. Review the diff: `https://github.com/cinnyapp/cinny/compare/<old>...<new>`
|
||||
3. Send `!cinny-update` in any Matrix room — LotusBot POSTs to the cinny-build webhook on LXC 106
|
||||
4. `cinny-build.sh` runs: `git fetch upstream && git merge upstream/main`, `npm ci`, `npm run build`, deploys to `/var/www/html/`
|
||||
5. Build result (success or conflict) is posted back to Matrix
|
||||
|
||||
**Manual build (SSH):**
|
||||
```bash
|
||||
# On LXC 106
|
||||
/usr/local/bin/cinny-dev-update.sh
|
||||
/usr/local/bin/cinny-build.sh
|
||||
```
|
||||
|
||||
**Merge conflict recovery:**
|
||||
```bash
|
||||
# On LXC 106
|
||||
cd /opt/lotus-cinny
|
||||
git merge upstream/main # resolve conflicts in editor
|
||||
git add -A && git merge --continue
|
||||
/usr/local/bin/cinny-build.sh
|
||||
```
|
||||
|
||||
**LXC 106 one-time setup** (after forking `cinnyapp/cinny` to `code.lotusguild.org/LotusGuild/cinny`):
|
||||
```bash
|
||||
# On LXC 106
|
||||
git clone https://code.lotusguild.org/LotusGuild/cinny.git /opt/lotus-cinny
|
||||
cd /opt/lotus-cinny
|
||||
git remote add upstream https://github.com/cinnyapp/cinny.git
|
||||
git fetch upstream
|
||||
|
||||
# Create env file (fill in a valid Matrix token)
|
||||
cat > /etc/cinny-monitor.env << 'EOF'
|
||||
MATRIX_TOKEN=<jared_or_bot_token>
|
||||
MATRIX_SERVER=https://matrix.lotusguild.org
|
||||
MATRIX_ROOM=!GttT4QYd1wlGlkHU3qTmq_P3gbyYKKeSSN6R7TPcJHg
|
||||
MATRIX_PING_USER=@jared:matrix.lotusguild.org
|
||||
EOF
|
||||
chmod 600 /etc/cinny-monitor.env
|
||||
```
|
||||
|
||||
**Cinny-build webhook token** (for LotusBot `!cinny-update`): stored in `deploy/hooks-lxc106.json` (`cinny-build` hook, header `X-Build-Token`). LotusBot must POST to `http://10.10.10.6:9000/hooks/cinny-build` with this header.
|
||||
|
||||
**Why 2GB RAM:** Vite's build process OOM-killed at 1GB. 896MB Node heap + OS overhead requires at least 1.5GB; 2GB gives headroom.
|
||||
|
||||
---
|
||||
@@ -394,10 +445,10 @@ Periodic `TLS/TCP socket error: Connection reset by peer` in coturn logs. Normal
|
||||
- [x] Default room version v12, all rooms upgraded
|
||||
- [x] Landing page with client recommendations
|
||||
- [x] Synapse metrics endpoint (port 9000, Prometheus-compatible)
|
||||
- [x] Cinny `dev` branch — nightly auto-build, tracks latest beta features
|
||||
- [x] Lotus Cinny fork — custom fork of `cinnyapp/cinny` main, daily upstream check + Matrix notification
|
||||
- [x] Auto-deployment via Gitea webhooks (all 4 LXCs)
|
||||
- [ ] Push notifications gateway (Sygnal) — needs Apple/Google developer credentials
|
||||
- [ ] Cinny custom branding — Lotus Guild theme (colours, title, favicon, PWA name)
|
||||
- [ ] Lotus Cinny custom branding — Lotus Guild theme (colours, title, favicon, PWA name)
|
||||
|
||||
### Performance Tuning
|
||||
- [x] PostgreSQL `shared_buffers` → 1500MB, `effective_cache_size`, `work_mem`, checkpoint tuning
|
||||
@@ -461,7 +512,7 @@ Periodic `TLS/TCP socket error: Connection reset by peer` in coturn logs. Normal
|
||||
### Admin
|
||||
- [x] Synapse admin API dashboard (synapse-admin at http://10.10.10.29:8080)
|
||||
- [x] Draupnir moderation bot — LXC 110, v2.9.0, all rooms + space, 2 ban lists
|
||||
- [ ] Cinny custom branding
|
||||
- [ ] Lotus Cinny custom branding — fork live at code.lotusguild.org/LotusGuild/cinny
|
||||
|
||||
---
|
||||
|
||||
|
||||
@@ -1,59 +0,0 @@
|
||||
#!/bin/bash
|
||||
# Cinny dev branch nightly build and deploy
|
||||
set -e
|
||||
|
||||
REPO_DIR="/opt/cinny-dev"
|
||||
WEB_ROOT="/var/www/html"
|
||||
CONFIG_SAVED="/opt/cinny-dev/.cinny-config.json"
|
||||
BUILD_DIR="/opt/cinny-dev/dist"
|
||||
LOG="/var/log/cinny-dev-update.log"
|
||||
|
||||
exec >> "$LOG" 2>&1
|
||||
echo "=== $(date) === Starting Cinny dev update ==="
|
||||
|
||||
# Save config from live site (skip if web root is already broken)
|
||||
if [ -f "$WEB_ROOT/config.json" ]; then
|
||||
cp "$WEB_ROOT/config.json" "$CONFIG_SAVED"
|
||||
fi
|
||||
|
||||
# Pull latest dev
|
||||
cd "$REPO_DIR"
|
||||
git fetch --depth=1 origin dev
|
||||
PREV=$(git rev-parse HEAD)
|
||||
git reset --hard origin/dev
|
||||
NEW=$(git rev-parse HEAD)
|
||||
|
||||
if [ "$PREV" = "$NEW" ]; then
|
||||
echo "No changes since last build ($NEW), skipping."
|
||||
exit 0
|
||||
fi
|
||||
|
||||
echo "New commits since $PREV, building $NEW..."
|
||||
|
||||
# Clean previous dist so stale files don't get deployed on partial build
|
||||
rm -rf "$BUILD_DIR"
|
||||
|
||||
# Build — cap at 896MB to stay within 1GB RAM + swap headroom
|
||||
export NODE_OPTIONS='--max_old_space_size=896'
|
||||
npm ci 2>&1 | tail -5
|
||||
npm run build 2>&1 | tail -10
|
||||
|
||||
# Verify build actually produced output before touching web root
|
||||
if [ ! -f "$BUILD_DIR/index.html" ]; then
|
||||
echo "ERROR: Build failed — dist/index.html missing. Web root untouched."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Deploy only now that we know the build succeeded
|
||||
rm -rf "${WEB_ROOT:?}"/*
|
||||
cp -r "$BUILD_DIR"/* "$WEB_ROOT/"
|
||||
|
||||
# Restore config
|
||||
if [ -f "$CONFIG_SAVED" ]; then
|
||||
cp "$CONFIG_SAVED" "$WEB_ROOT/config.json"
|
||||
else
|
||||
echo "WARNING: No saved config found — default config from build will be used."
|
||||
fi
|
||||
|
||||
nginx -s reload
|
||||
echo "=== Deploy complete: $NEW ==="
|
||||
@@ -0,0 +1,119 @@
|
||||
#!/bin/bash
|
||||
# Merges the latest upstream stable release tag into the lotus branch, builds, and deploys.
|
||||
# Triggered via webhook by LotusBot !cinny-update command.
|
||||
# Requires:
|
||||
# /etc/cinny-monitor.env — MATRIX_TOKEN, MATRIX_SERVER, MATRIX_ROOM
|
||||
# /opt/lotus-cinny/ — git clone of code.lotusguild.org/LotusGuild/cinny
|
||||
# with upstream remote: https://github.com/cinnyapp/cinny.git
|
||||
set -euo pipefail
|
||||
|
||||
REPO_DIR="/opt/lotus-cinny"
|
||||
WEB_ROOT="/var/www/html"
|
||||
CONFIG_BACKUP="/opt/lotus-cinny/.cinny-config.json"
|
||||
BUILD_DIR="/opt/lotus-cinny/dist"
|
||||
STATE_FILE="/var/lib/cinny-monitor/last-upstream-tag"
|
||||
ENV_FILE="/etc/cinny-monitor.env"
|
||||
LOG="/var/log/cinny-build.log"
|
||||
|
||||
exec >> "$LOG" 2>&1
|
||||
echo "=== $(date) === Cinny build triggered ==="
|
||||
|
||||
[ -f "$ENV_FILE" ] || { echo "ERROR: $ENV_FILE missing"; exit 1; }
|
||||
set -a
|
||||
# shellcheck source=/dev/null
|
||||
source "$ENV_FILE"
|
||||
set +a
|
||||
|
||||
matrix_notify() {
|
||||
local msg="$1"
|
||||
echo "[notify] $msg"
|
||||
[ -z "${MATRIX_TOKEN:-}" ] && return
|
||||
export _NOTIFY_MSG="$msg"
|
||||
python3 << 'PYEOF'
|
||||
import urllib.request, urllib.parse, json, time, sys, os
|
||||
token = os.environ.get('MATRIX_TOKEN', '')
|
||||
server = os.environ.get('MATRIX_SERVER', '').rstrip('/')
|
||||
room = os.environ.get('MATRIX_ROOM', '')
|
||||
msg = os.environ.get('_NOTIFY_MSG', '')
|
||||
if not all([token, server, room, msg]):
|
||||
sys.exit(0)
|
||||
txn = str(int(time.time() * 1000))
|
||||
api = f"{server}/_matrix/client/v3/rooms/{urllib.parse.quote(room, safe='')}/send/m.room.message/{txn}"
|
||||
body = json.dumps({"msgtype": "m.text", "body": msg}).encode()
|
||||
req = urllib.request.Request(api, data=body, method="PUT", headers={
|
||||
"Authorization": f"Bearer {token}", "Content-Type": "application/json"
|
||||
})
|
||||
try:
|
||||
urllib.request.urlopen(req, timeout=10)
|
||||
except Exception as e:
|
||||
print(f"Notify failed: {e}", file=sys.stderr)
|
||||
PYEOF
|
||||
}
|
||||
|
||||
if [ ! -d "$REPO_DIR/.git" ]; then
|
||||
matrix_notify "cinny-build: FAILED — $REPO_DIR is not a git repo. Clone the lotus fork first."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
cd "$REPO_DIR"
|
||||
|
||||
if ! git remote | grep -q '^upstream$'; then
|
||||
matrix_notify "cinny-build: FAILED — upstream remote missing. Run: git remote add upstream https://github.com/cinnyapp/cinny.git"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
matrix_notify "cinny-build: fetching upstream tags..."
|
||||
|
||||
git fetch upstream --tags --no-recurse-submodules -q
|
||||
|
||||
# Get latest stable release tag from GitHub API
|
||||
LATEST_TAG=$(curl -sf \
|
||||
-H "Accept: application/vnd.github.v3+json" \
|
||||
-H "User-Agent: lotus-cinny-monitor/1.0" \
|
||||
"https://api.github.com/repos/cinnyapp/cinny/releases/latest" | python3 -c "import sys,json; print(json.load(sys.stdin)['tag_name'])")
|
||||
|
||||
CURRENT_TAG=$(git describe --tags --exact-match HEAD 2>/dev/null || git log -1 --format='%D' | grep -oP 'tag: \K[^,]+' | head -1 || echo "untagged")
|
||||
echo "Current: $CURRENT_TAG — Target: $LATEST_TAG"
|
||||
|
||||
if [ "$CURRENT_TAG" = "$LATEST_TAG" ]; then
|
||||
matrix_notify "cinny-build: already on $LATEST_TAG, nothing to do."
|
||||
exit 0
|
||||
fi
|
||||
|
||||
matrix_notify "cinny-build: merging $LATEST_TAG into lotus branch..."
|
||||
|
||||
# Back up live config before touching anything
|
||||
[ -f "$WEB_ROOT/config.json" ] && cp "$WEB_ROOT/config.json" "$CONFIG_BACKUP"
|
||||
|
||||
if ! git merge "$LATEST_TAG" --no-edit 2>&1; then
|
||||
git merge --abort 2>/dev/null || true
|
||||
matrix_notify "cinny-build: FAILED — merge conflict at $LATEST_TAG. SSH to LXC 106 and resolve manually. See /var/log/cinny-build.log"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "Running npm ci..."
|
||||
npm ci 2>&1 | tail -5
|
||||
|
||||
rm -rf "$BUILD_DIR"
|
||||
export NODE_OPTIONS='--max_old_space_size=896'
|
||||
echo "Building $LATEST_TAG..."
|
||||
npm run build 2>&1 | tail -10
|
||||
|
||||
if [ ! -f "$BUILD_DIR/index.html" ]; then
|
||||
matrix_notify "cinny-build: FAILED — build produced no output at $LATEST_TAG. See /var/log/cinny-build.log"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
rm -rf "${WEB_ROOT:?}"/*
|
||||
cp -r "$BUILD_DIR"/* "$WEB_ROOT/"
|
||||
[ -f "$CONFIG_BACKUP" ] && cp "$CONFIG_BACKUP" "$WEB_ROOT/config.json"
|
||||
nginx -s reload
|
||||
|
||||
# Push merged lotus branch to origin
|
||||
git push origin lotus
|
||||
|
||||
# Update state file so upstream-check knows we're on this tag
|
||||
echo "$LATEST_TAG" > "$STATE_FILE"
|
||||
|
||||
matrix_notify "cinny-build: deployed $LATEST_TAG — Lotus Cinny is live."
|
||||
echo "=== Build complete: $LATEST_TAG ==="
|
||||
@@ -0,0 +1,97 @@
|
||||
#!/bin/bash
|
||||
# Checks if cinnyapp/cinny has published a new stable release; notifies Matrix if so.
|
||||
# Runs daily at noon via /etc/cron.d/cinny-upstream-check
|
||||
# Requires /etc/cinny-monitor.env:
|
||||
# MATRIX_TOKEN, MATRIX_SERVER, MATRIX_ROOM, MATRIX_PING_USER
|
||||
set -euo pipefail
|
||||
|
||||
ENV_FILE="/etc/cinny-monitor.env"
|
||||
STATE_FILE="/var/lib/cinny-monitor/last-upstream-tag"
|
||||
LOG="/var/log/cinny-monitor.log"
|
||||
|
||||
exec >> "$LOG" 2>&1
|
||||
echo "=== $(date) === Cinny upstream release check ==="
|
||||
|
||||
[ -f "$ENV_FILE" ] || { echo "ERROR: $ENV_FILE missing"; exit 1; }
|
||||
set -a
|
||||
# shellcheck source=/dev/null
|
||||
source "$ENV_FILE"
|
||||
set +a
|
||||
|
||||
mkdir -p "$(dirname "$STATE_FILE")"
|
||||
|
||||
API_RESPONSE=$(curl -sf \
|
||||
-H "Accept: application/vnd.github.v3+json" \
|
||||
-H "User-Agent: lotus-cinny-monitor/1.0" \
|
||||
"https://api.github.com/repos/cinnyapp/cinny/releases/latest") || {
|
||||
echo "ERROR: GitHub API request failed"
|
||||
exit 1
|
||||
}
|
||||
|
||||
LATEST_TAG=$(echo "$API_RESPONSE" | jq -r '.tag_name')
|
||||
LATEST_NAME=$(echo "$API_RESPONSE" | jq -r '.name')
|
||||
RELEASE_URL=$(echo "$API_RESPONSE" | jq -r '.html_url')
|
||||
RELEASE_BODY=$(echo "$API_RESPONSE" | jq -r '.body | split("\n")[0:3] | join(" | ")')
|
||||
|
||||
LAST_TAG=""
|
||||
[ -f "$STATE_FILE" ] && LAST_TAG=$(cat "$STATE_FILE")
|
||||
|
||||
if [ "$LATEST_TAG" = "$LAST_TAG" ]; then
|
||||
echo "No new release (still at $LATEST_TAG), nothing to do."
|
||||
exit 0
|
||||
fi
|
||||
|
||||
echo "New release: $LATEST_TAG (was: ${LAST_TAG:-none})"
|
||||
|
||||
export _CM_LATEST_TAG="$LATEST_TAG"
|
||||
export _CM_LATEST_NAME="$LATEST_NAME"
|
||||
export _CM_RELEASE_URL="$RELEASE_URL"
|
||||
export _CM_RELEASE_BODY="$RELEASE_BODY"
|
||||
export _CM_LAST_TAG="$LAST_TAG"
|
||||
|
||||
python3 << 'PYEOF'
|
||||
import urllib.request, urllib.parse, json, time, sys, os
|
||||
|
||||
token = os.environ.get('MATRIX_TOKEN', '')
|
||||
server = os.environ.get('MATRIX_SERVER', '').rstrip('/')
|
||||
room = os.environ.get('MATRIX_ROOM', '')
|
||||
ping = os.environ.get('MATRIX_PING_USER', '')
|
||||
|
||||
if not all([token, server, room]):
|
||||
print("ERROR: MATRIX_TOKEN/MATRIX_SERVER/MATRIX_ROOM not set in env file")
|
||||
sys.exit(1)
|
||||
|
||||
tag = os.environ['_CM_LATEST_TAG']
|
||||
name = os.environ['_CM_LATEST_NAME']
|
||||
url = os.environ['_CM_RELEASE_URL']
|
||||
body = os.environ['_CM_RELEASE_BODY']
|
||||
last_tag = os.environ['_CM_LAST_TAG']
|
||||
from_str = f" (was {last_tag})" if last_tag else ""
|
||||
|
||||
ping_safe = urllib.parse.quote(ping, safe=":@")
|
||||
plain = (
|
||||
f"{ping}: Cinny {tag} released{from_str}.\n"
|
||||
f"{body}\n"
|
||||
f"Review release notes, then send !cinny-update to merge + rebuild.\n{url}"
|
||||
)
|
||||
html = (
|
||||
f"<a href='https://matrix.to/#/{ping_safe}'>{ping}</a>: "
|
||||
f"<strong>Cinny {tag} released</strong>{from_str}.<br>"
|
||||
f"<em>{body}</em><br>"
|
||||
f"<a href='{url}'>Release notes</a> · Send <code>!cinny-update</code> to merge + rebuild."
|
||||
)
|
||||
|
||||
txn = str(int(time.time() * 1000))
|
||||
api = f"{server}/_matrix/client/v3/rooms/{urllib.parse.quote(room, safe='')}/send/m.room.message/{txn}"
|
||||
body_json = json.dumps({"msgtype": "m.text", "body": plain,
|
||||
"format": "org.matrix.custom.html", "formatted_body": html}).encode()
|
||||
req = urllib.request.Request(api, data=body_json, method="PUT", headers={
|
||||
"Authorization": f"Bearer {token}",
|
||||
"Content-Type": "application/json",
|
||||
})
|
||||
urllib.request.urlopen(req, timeout=10)
|
||||
print(f"Notification sent for {tag}")
|
||||
PYEOF
|
||||
|
||||
echo "$LATEST_TAG" > "$STATE_FILE"
|
||||
echo "State updated to $LATEST_TAG"
|
||||
@@ -14,5 +14,21 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "cinny-build",
|
||||
"execute-command": "/usr/local/bin/cinny-build.sh",
|
||||
"command-working-directory": "/opt/lotus-cinny",
|
||||
"response-message": "Cinny merge + build triggered",
|
||||
"trigger-rule": {
|
||||
"match": {
|
||||
"type": "value",
|
||||
"value": "a82340fc2f07e6afda097494c34aa3a4877924932a0b063a76106fdab9816ec6",
|
||||
"parameter": {
|
||||
"source": "header",
|
||||
"name": "X-Build-Token"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
+29
-8
@@ -1,6 +1,7 @@
|
||||
#!/bin/bash
|
||||
# Auto-deploy script for LXC 106 (cinny)
|
||||
# Handles: cinny/config.json, cinny/dev-update.sh
|
||||
# Handles: cinny/config.json, cinny/upstream-check.sh, cinny/lotus-build.sh,
|
||||
# deploy/hooks-lxc106.json, systemd/cinny-upstream-check.cron
|
||||
# Triggered by: Gitea webhook on push to main
|
||||
set -euo pipefail
|
||||
|
||||
@@ -11,10 +12,9 @@ CLONE_URL="https://code.lotusguild.org/LotusGuild/matrix.git"
|
||||
exec >> "$LOG" 2>&1
|
||||
echo "=== $(date) === LXC106 deploy triggered ==="
|
||||
|
||||
# Clone or pull
|
||||
if [ ! -d "$REPO_DIR/.git" ]; then
|
||||
git clone "$CLONE_URL" "$REPO_DIR"
|
||||
CHANGED="cinny/config.json cinny/dev-update.sh"
|
||||
CHANGED="cinny/config.json cinny/upstream-check.sh cinny/lotus-build.sh deploy/hooks-lxc106.json systemd/cinny-upstream-check.cron"
|
||||
else
|
||||
cd "$REPO_DIR"
|
||||
git fetch --all
|
||||
@@ -31,11 +31,32 @@ if echo "$CHANGED" | grep -q '^cinny/config.json'; then
|
||||
echo "✓ config.json deployed"
|
||||
fi
|
||||
|
||||
if echo "$CHANGED" | grep -q '^cinny/dev-update.sh'; then
|
||||
echo "Deploying cinny dev-update.sh..."
|
||||
cp "$REPO_DIR/cinny/dev-update.sh" /usr/local/bin/cinny-dev-update.sh
|
||||
chmod +x /usr/local/bin/cinny-dev-update.sh
|
||||
echo "✓ dev-update.sh deployed"
|
||||
if echo "$CHANGED" | grep -q '^cinny/upstream-check.sh'; then
|
||||
echo "Deploying upstream-check.sh..."
|
||||
cp "$REPO_DIR/cinny/upstream-check.sh" /usr/local/bin/cinny-upstream-check.sh
|
||||
chmod +x /usr/local/bin/cinny-upstream-check.sh
|
||||
echo "✓ upstream-check.sh deployed"
|
||||
fi
|
||||
|
||||
if echo "$CHANGED" | grep -q '^cinny/lotus-build.sh'; then
|
||||
echo "Deploying lotus-build.sh..."
|
||||
cp "$REPO_DIR/cinny/lotus-build.sh" /usr/local/bin/cinny-build.sh
|
||||
chmod +x /usr/local/bin/cinny-build.sh
|
||||
echo "✓ lotus-build.sh deployed"
|
||||
fi
|
||||
|
||||
if echo "$CHANGED" | grep -q '^deploy/hooks-lxc106.json'; then
|
||||
echo "Deploying hooks-lxc106.json..."
|
||||
cp "$REPO_DIR/deploy/hooks-lxc106.json" /etc/webhook/hooks.json
|
||||
systemctl restart webhook
|
||||
echo "✓ hooks.json deployed, webhook restarted"
|
||||
fi
|
||||
|
||||
if echo "$CHANGED" | grep -q '^systemd/cinny-upstream-check.cron'; then
|
||||
echo "Deploying cinny-upstream-check.cron..."
|
||||
cp "$REPO_DIR/systemd/cinny-upstream-check.cron" /etc/cron.d/cinny-upstream-check
|
||||
chmod 644 /etc/cron.d/cinny-upstream-check
|
||||
echo "✓ cron deployed"
|
||||
fi
|
||||
|
||||
echo "=== $(date) === LXC106 deploy complete ==="
|
||||
|
||||
+4
-4
@@ -547,15 +547,15 @@
|
||||
<span class="client-desc">Hosted Cinny — homeserver pre-configured, no setup</span>
|
||||
<span class="tag-row">
|
||||
<span class="tag dim">Desktop & Web</span>
|
||||
<span class="tag dev">Dev Branch</span>
|
||||
<span class="tag dev">Lotus Fork</span>
|
||||
<span class="tag voice">Voice & Video Rooms</span>
|
||||
<span class="tag">Discord-like UI</span>
|
||||
</span>
|
||||
</a>
|
||||
</div>
|
||||
<p class="also-available">
|
||||
Runs the Cinny <strong>dev branch</strong> — latest beta features, updated nightly.
|
||||
Prefer stable? Use <a href="https://cinny.in" target="_blank" rel="noopener">cinny.in</a> and set homeserver to <code style="font-size:0.8em;color:#e88;">matrix.lotusguild.org</code>.
|
||||
A custom Lotus Guild fork of Cinny, based on stable releases.
|
||||
Prefer the official client? Use <a href="https://cinny.in" target="_blank" rel="noopener">cinny.in</a> and set homeserver to <code style="font-size:0.8em;color:#e88;">matrix.lotusguild.org</code>.
|
||||
</p>
|
||||
|
||||
<div class="space-join">
|
||||
@@ -665,7 +665,7 @@
|
||||
<thead>
|
||||
<tr>
|
||||
<th></th>
|
||||
<th class="ours">Cinny<small>chat.lotusguild.org<br>dev branch</small></th>
|
||||
<th class="ours">Cinny<small>chat.lotusguild.org<br>Lotus fork</small></th>
|
||||
<th>Element X<small>iOS & Android</small></th>
|
||||
<th>FluffyChat<small>All platforms</small></th>
|
||||
<th>Commet<small>Android / Win / Linux</small></th>
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
0 3 * * * root /usr/local/bin/cinny-dev-update.sh
|
||||
@@ -0,0 +1 @@
|
||||
0 12 * * * root /usr/local/bin/cinny-upstream-check.sh
|
||||
Reference in New Issue
Block a user