diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..532ac7a --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,72 @@ +name: ci + +on: + push: + branches: [main] + pull_request: + +jobs: + hub: + name: hub (ruff + pytest) + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: astral-sh/setup-uv@v5 + with: + enable-cache: true + - name: Install the fake engine venv + # Its only dependency is the local SDK, so the hub's integration test + # can spawn a real worker instead of skipping itself. + run: uv sync --python 3.12 + working-directory: engines/fake + - name: Install the hub venv + run: uv sync --python 3.12 --group dev + working-directory: hub + - name: Lint + run: uv run ruff check ../hub ../sdk ../engines ../scripts --exclude ../engines/gpt_sovits/vendor + working-directory: hub + - name: Test + # Includes the docs/api drift guard (tests/test_openapi_export.py). + run: uv run pytest -q + working-directory: hub + + webui: + name: webui (node) + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-node@v4 + with: + node-version: "22" + - run: npm run test:web + working-directory: hub + + e2e: + name: e2e (playwright) + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-node@v4 + with: + node-version: "22" + - uses: astral-sh/setup-uv@v5 + with: + enable-cache: true + - name: Install the fake engine venv + run: uv sync --python 3.12 + working-directory: engines/fake + - name: Install the hub venv + run: uv sync --python 3.12 + working-directory: hub + - run: npm ci + working-directory: hub + - run: npx playwright install --with-deps chromium + working-directory: hub + - run: npm run test:e2e + working-directory: hub + - uses: actions/upload-artifact@v4 + if: failure() + with: + name: playwright-report + path: hub/playwright-report/ + retention-days: 7 diff --git a/.gitignore b/.gitignore index 4b95f20..3613e91 100644 --- a/.gitignore +++ b/.gitignore @@ -7,3 +7,6 @@ engines/*/vendor/ engines/indextts/model/ .playwright-mcp/ .impeccable/ +node_modules/ +hub/test-results/ +hub/playwright-report/ diff --git a/README.md b/README.md index fc384c6..4743d04 100644 --- a/README.md +++ b/README.md @@ -100,7 +100,23 @@ instructions are in the file's header comment. The default `config.toml` binds `0.0.0.0`, so other devices on your LAN (e.g. your iPhone) can open `http://:5050` — the WebUI is responsive and installable as a PWA. Bind `127.0.0.1` instead if you want it -local-only; there is no authentication. +local-only. + +**Securing the hub.** Access control is off by default. Anyone who can reach +the port can generate audio and change settings, so if the hub is exposed +beyond a trusted LAN, set a token: + +```toml +[hub] +auth_token = "a-long-random-string" # generate: openssl rand -hex 24 +``` + +Every `/api/*` call then needs `Authorization: Bearer `, and the WebUI +asks for it once per browser. Streams that cannot send a header (the SSE feed, +`