name: Rebuild & Deploy on: push: branches: [master] paths-ignore: ['**/*.md', 'ios/**', 'design/**', '.gitignore', '.dockerignore'] jobs: rebuild: runs-on: unraid steps: - name: Checkout uses: actions/checkout@v4 - name: Qualify offline account and chat contracts before building or deploying run: | # No NAS, speech SDK, model calls or legacy live-default conftest. # The socket-backed runner checkout path is not a host bind source. # Stream only tracked source; secrets/runtime files are never included. git archive HEAD | docker run --rm -i --user "$(id -u):$(id -g)" \ -e HOME=/tmp -e PYTHONDONTWRITEBYTECODE=1 \ python:3.12-slim-bookworm sh -eu -c ' mkdir -p /tmp/src tar -xf - -C /tmp/src cd /tmp/src python -m venv /tmp/offline-tests /tmp/offline-tests/bin/python -m pip install --no-cache-dir pytest pytest-asyncio -r control/requirements.txt /tmp/offline-tests/bin/python scripts/generate_hope_themes.py --check /tmp/offline-tests/bin/python -m pytest --noconftest -p no:cacheprovider \ tests/unit/test_accounts.py tests/unit/test_provisioner.py \ tests/unit/test_token_bootstrap.py tests/unit/test_deploy_rollback.py \ tests/unit/test_model_preferences_store.py tests/unit/test_model_settings_api.py \ tests/unit/test_chat_store.py tests/unit/test_chat_runs.py tests/unit/test_chat_runs_limits.py \ tests/unit/test_chat_api.py tests/unit/test_chat_exports.py \ tests/unit/test_chat_features.py tests/unit/test_chat_security_review.py \ tests/unit/test_chat_cross_client.py tests/unit/test_chat_packaging.py -q ' - name: Build images run: | docker build -t hope-voice-api-voice:latest . docker build -f control.Dockerfile -t hope-voice-control:latest . docker build -f hermes-webui.Dockerfile -t hope-hermes-webui:62e4d7b . - name: Deploy using protected persistent runtime configuration run: | # Credentials, account DB, certificates and per-user homes are outside # the CI checkout. This script never destroys or reinitializes them. test -f /mnt/user/appdata/hope-voice/runtime.env bash scripts/deploy-unraid.sh - name: Verify authenticated deployment run: | # CI runner loopback is not the Docker host's loopback. host_curl() { docker run --rm --network host --entrypoint curl hope-voice-api-voice:latest "$@" } host_curl -sf http://127.0.0.1:8092/health -o /dev/null host_curl -sfk https://127.0.0.1:9178/ -o /dev/null test "$(host_curl -sk -o /dev/null -w '%{http_code}' -X POST https://127.0.0.1:9178/token)" = 401