feat(host-agent): release_agent.sh — Binaries als Gitea-Assets, nicht im Tree

release_agent.sh <version> (wie die App-release.sh): setzt Version
(host_agent.py AGENT_VERSION + Android versionName/Code), baut Linux-Binary +
Android-APK per Docker, taggt agent-v<version> (eigener Namespace, keine
Kollision mit App-Tags v<version>), legt Gitea-Release an und laedt Assets hoch.
mac/win optional falls in dist/ vorgebaut. Agent meldet AGENT_VERSION jetzt in
host_hello + info. README-Release-Sektion aktualisiert.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-09-24 20:32:11 +02:00
co-authored by Claude Opus 4.8
parent a2605a2802
commit 4f8e65b76b
3 changed files with 165 additions and 7 deletions
+26 -6
View File
@@ -164,11 +164,31 @@ Gradle-Cache im Image). Häufige Stolperer:
Bis es `release.sh` gibt, wird die Version in `app/build.gradle` gepflegt
(`versionCode` / `versionName`). Aktuell `1` / `0.2.0` (M1+M2).
## Release (geplant — Meilenstein 4)
## Release
`release.sh <version>` — wie die `release.sh` der Haupt-App: nimmt die
Versionsnummer als Parameter, baut das APK, taggt und lädt es als
**Gitea-Release-Asset** hoch, damit der Download einfach ist. Noch nicht gebaut.
Das APK ist **kein** Teil des Git-Trees (blaeht sonst die History dauerhaft auf) —
es wird als **Release-Asset** an einen Tag gehaengt. Das macht `release_agent.sh`
(liegt eine Ebene hoeher, in `host-agent/`):
> Status: **M1 + M2 fertig** (verbinden, `info`, `screenshot`, `ui_dump`).
> Als Nächstes Meilenstein 3 (Steuern), Release-Skript in M4.
```bash
cd host-agent
./release_agent.sh 0.2.0
```
Das Skript (wie die `release.sh` der Haupt-App, Version als Parameter):
- setzt die Version (`host_agent.py` → `AGENT_VERSION`, `app/build.gradle` →
`versionName`/`versionCode`),
- baut **Linux-Binary + Android-APK** per Docker,
- committet den Version-Bump, taggt **`agent-v<version>`** (eigener Namespace,
kollidiert nicht mit den App-Tags `v<version>`) und pusht,
- legt ein Gitea-Release an und laedt die Assets hoch:
`aria-host-agent-linux-x64`, `aria-host-agent-android-agent-v<version>.apk`,
optional `-macos` / `-windows.exe` (falls in `host-agent/dist/` vorgebaut).
Gitea-Zugang (`GITEA_URL`, `GITEA_REPO`, `GITEA_USER`) kommt aus der Umgebung oder
einer `.env`; das Kennwort wird interaktiv abgefragt. **Binaries landen unter
„Releases", nie im Tree.**
> Status: **M1 + M2 fertig** (verbinden, `info`, `screenshot`, `ui_dump`),
> `release_agent.sh` vorhanden. Als Nächstes Meilenstein 3 (Steuern).
+5 -1
View File
@@ -155,6 +155,9 @@ OUT_MAX_CHARS_HARD = int(os.environ.get("OUT_MAX_CHARS_HARD", "200000") or "2000
# Datei-Transfer-Limit (Base64 durchs RVS).
FILE_MAX_BYTES = int(os.environ.get("FILE_MAX_BYTES", str(10 * 1024 * 1024)) or str(10 * 1024 * 1024))
# Version (wird von release_agent.sh beim Release gesetzt).
AGENT_VERSION = "0.2.0"
HEARTBEAT_SEC = 25
CAPS = ["exec", "read", "write", "info", "screenshot"]
@@ -291,6 +294,7 @@ def _do_write(params: dict) -> dict:
def _do_info(params: dict) -> dict:
info = {
"host": HOST_NAME, "hostname": socket.gethostname(),
"agent_version": AGENT_VERSION,
"os": platform.platform(), "kernel": platform.release(),
"arch": platform.machine(), "python": platform.python_version(),
"user": os.environ.get("USER") or os.environ.get("USERNAME") or "",
@@ -414,7 +418,7 @@ class HostAgent:
HOST_ID, HOST_NAME, ",".join(CAPS), CONTROL_ENABLED)
await self._send({"type": "host_hello", "payload": {
"hostId": HOST_ID, "name": HOST_NAME, "os": platform.platform(),
"caps": CAPS, "control": CONTROL_ENABLED,
"version": AGENT_VERSION, "caps": CAPS, "control": CONTROL_ENABLED,
}, "timestamp": int(time.time() * 1000)})
async def _heartbeat(self) -> None:
+134
View File
@@ -0,0 +1,134 @@
#!/bin/bash
# ════════════════════════════════════════════════════════════════════
# ARIA Host-Agent — Release Script
# Baut die auf Linux+Docker moeglichen Artefakte und haengt sie als
# Gitea-Release-Assets an einen Tag. NICHTS wandert in den Git-Tree —
# Binaries leben nur unter "Releases" (blaeht clone/History nicht auf).
#
# Verwendung: ./release_agent.sh <version> (z.B. ./release_agent.sh 0.2.0)
#
# Artefakte:
# - Linux-x64-Binary (Docker, PyInstaller) -> immer
# - Android-APK (Docker, Gradle) -> immer
# - macOS / Windows (falls in dist/ vorgebaut) -> optional
# (mac/win koennen auf Linux nicht cross-gebaut werden -> build-native.*
# auf dem jeweiligen OS laufen lassen, Ergebnis nach host-agent/dist/ legen)
#
# Eigener Tag-Namespace agent-v<version> (kollidiert NICHT mit den
# App-Tags v<version>).
#
# Gitea-Zugang (GITEA_URL, GITEA_REPO, GITEA_USER) wird aus der Umgebung
# oder aus host-agent/.env bzw. der Repo-Wurzel-.env gelesen; das Kennwort
# wird interaktiv abgefragt.
# ════════════════════════════════════════════════════════════════════
set -e
cd "$(dirname "$0")" # host-agent/
SCRIPT_DIR="$(pwd)"
ROOT_DIR="$(cd .. && pwd)"
# ── Farben ───────────────────────────────────────────────────────────
RED='\033[0;31m'; GREEN='\033[0;32m'; YELLOW='\033[1;33m'; CYAN='\033[0;36m'; NC='\033[0m'
# ── Parameter ────────────────────────────────────────────────────────
VERSION=${1:?"Usage: ./release_agent.sh <version> (z.B. 0.2.0)"}
TAG="agent-v$VERSION"
# ── Gitea-Konfiguration (env > host-agent/.env > Repo-Wurzel-.env) ────
[ -f "$SCRIPT_DIR/.env" ] && source "$SCRIPT_DIR/.env"
[ -f "$ROOT_DIR/.env" ] && source "$ROOT_DIR/.env"
GITEA_URL="${GITEA_URL:?"GITEA_URL nicht gesetzt (in .env oder als Umgebungsvariable)"}"
GITEA_REPO="${GITEA_REPO:?"GITEA_REPO nicht gesetzt (z.B. stefan/aria-agent)"}"
GITEA_USER="${GITEA_USER:-$(echo "$GITEA_REPO" | cut -d'/' -f1)}"
echo -e "${CYAN}╔═══════════════════════════════════════════╗${NC}"
echo -e "${CYAN}║ ARIA Host-Agent Release — ${TAG}$(printf '%*s' $((14 - ${#TAG})) '')║${NC}"
echo -e "${CYAN}╚═══════════════════════════════════════════╝${NC}\n"
# ── Kennwort ─────────────────────────────────────────────────────────
echo -e "${YELLOW}Gitea-Login: ${GITEA_USER}${NC}"
read -s -p "Gitea-Kennwort: " GITEA_PASS; echo ""
HTTP_CODE=$(curl -s -o /dev/null -w "%{http_code}" -u "${GITEA_USER}:${GITEA_PASS}" "$GITEA_URL/api/v1/user")
if [ "$HTTP_CODE" != "200" ]; then
echo -e "${RED}Login fehlgeschlagen (HTTP $HTTP_CODE). Kennwort korrekt?${NC}"; exit 1
fi
echo -e " ${GREEN}✓${NC} Login erfolgreich\n"
# ── Versionsnummern setzen ───────────────────────────────────────────
echo -e "${GREEN}[1/5] Version auf $VERSION setzen...${NC}"
# Desktop-Agent
sed -i "s/^AGENT_VERSION = \"[^\"]*\"/AGENT_VERSION = \"$VERSION\"/" host_agent.py
echo -e " ${GREEN}✓${NC} host_agent.py → AGENT_VERSION $VERSION"
# Android: versionName + versionCode (aus Version berechnen; 3- oder 4-stellig)
IFS='.' read -ra VP <<< "$VERSION"
V1=${VP[0]:-0}; V2=${VP[1]:-0}; V3=${VP[2]:-0}; V4=${VP[3]:-0}
VERSION_CODE=$((V1 * 1000000 + V2 * 10000 + V3 * 100 + V4)); [ "$VERSION_CODE" -lt 1 ] && VERSION_CODE=1
sed -i "s/versionName '[^']*'/versionName '$VERSION'/" android/app/build.gradle
sed -i "s/versionCode [0-9]*/versionCode $VERSION_CODE/" android/app/build.gradle
echo -e " ${GREEN}✓${NC} android/app/build.gradle → versionName $VERSION, versionCode $VERSION_CODE\n"
# ── Bauen (Docker) ───────────────────────────────────────────────────
echo -e "${GREEN}[2/5] Linux-Binary + Android-APK bauen (Docker)...${NC}"
./build.sh >/dev/null
LINUX_BIN="$SCRIPT_DIR/dist/aria-host-agent"
[ -f "$LINUX_BIN" ] || { echo -e "${RED}Linux-Binary fehlt: $LINUX_BIN${NC}"; exit 1; }
echo -e " ${GREEN}✓${NC} Linux-Binary ($(du -h "$LINUX_BIN" | cut -f1))"
( cd android && ./build.sh >/dev/null )
APK="$SCRIPT_DIR/android/dist/aria-android-agent.apk"
[ -f "$APK" ] || { echo -e "${RED}APK fehlt: $APK${NC}"; exit 1; }
echo -e " ${GREEN}✓${NC} Android-APK ($(du -h "$APK" | cut -f1))\n"
# Asset-Liste aufbauen: "lokaler_pfad::asset-name"
ASSETS=(
"$LINUX_BIN::aria-host-agent-linux-x64"
"$APK::aria-host-agent-android-$TAG.apk"
)
# Optionale, vorgebaute native Artefakte (nur wenn vorhanden):
[ -f "$SCRIPT_DIR/dist/aria-host-agent-macos" ] && ASSETS+=("$SCRIPT_DIR/dist/aria-host-agent-macos::aria-host-agent-macos")
[ -f "$SCRIPT_DIR/dist/aria-host-agent.exe" ] && ASSETS+=("$SCRIPT_DIR/dist/aria-host-agent.exe::aria-host-agent-windows.exe")
[ -f "$SCRIPT_DIR/dist/aria-host-agent-setup.exe" ] && ASSETS+=("$SCRIPT_DIR/dist/aria-host-agent-setup.exe::aria-host-agent-setup.exe")
# ── Git-Tag ──────────────────────────────────────────────────────────
echo -e "${GREEN}[3/5] Git-Tag $TAG...${NC}"
git add host_agent.py android/app/build.gradle
git commit -m "release(agent): bump to $VERSION" 2>/dev/null || echo -e " ${YELLOW}Keine Aenderungen zum Committen${NC}"
if git rev-parse "$TAG" &>/dev/null; then
echo -e " ${YELLOW}Tag $TAG existiert bereits — überspringe${NC}"
else
git tag "$TAG"; echo -e " ${GREEN}✓${NC} Tag $TAG erstellt"
fi
git push origin main "$TAG"
echo -e " ${GREEN}✓${NC} Tag gepusht\n"
# ── Gitea-Release ────────────────────────────────────────────────────
echo -e "${GREEN}[4/5] Gitea-Release anlegen...${NC}"
BODY="ARIA Host-Agent $TAG\n\nDesktop (Linux) + Android-APK. Auf das Zielgeraet kopieren, siehe README."
BODY_JSON=$(printf '%s' "$BODY" | python3 -c 'import sys,json; print(json.dumps(sys.stdin.read()))' 2>/dev/null || printf '"%s"' "$BODY")
RESP=$(curl -s -X POST "$GITEA_URL/api/v1/repos/$GITEA_REPO/releases" \
-u "${GITEA_USER}:${GITEA_PASS}" -H "Content-Type: application/json" \
-d "{\"tag_name\":\"$TAG\",\"name\":\"Host-Agent $TAG\",\"body\":$BODY_JSON,\"draft\":false,\"prerelease\":false}")
RELEASE_ID=$(echo "$RESP" | grep -o '"id":[0-9]*' | head -1 | cut -d: -f2)
if [ -z "$RELEASE_ID" ]; then echo -e "${RED}Release fehlgeschlagen:${NC}\n$RESP"; exit 1; fi
echo -e " ${GREEN}✓${NC} Release #$RELEASE_ID erstellt\n"
# ── Assets hochladen ─────────────────────────────────────────────────
echo -e "${GREEN}[5/5] Assets hochladen (${#ASSETS[@]})...${NC}"
for entry in "${ASSETS[@]}"; do
path="${entry%%::*}"; name="${entry##*::}"
UP=$(curl -s -X POST \
"$GITEA_URL/api/v1/repos/$GITEA_REPO/releases/$RELEASE_ID/assets?name=$name" \
-u "${GITEA_USER}:${GITEA_PASS}" -F "attachment=@${path}")
if echo "$UP" | grep -q '"name"'; then
echo -e " ${GREEN}✓${NC} $name"
else
echo -e " ${RED}✗ $name fehlgeschlagen:${NC} $UP"
fi
done
echo ""
echo -e "${GREEN}╔═══════════════════════════════════════════════════╗${NC}"
echo -e "${GREEN}║ Host-Agent $TAG ist live!${NC}"
echo -e "${GREEN}║${NC} $GITEA_URL/$GITEA_REPO/releases/tag/$TAG"
echo -e "${GREEN}╚═══════════════════════════════════════════════════╝${NC}"