Files
peardata/docs/CI.md
T
Raven Scott 726dbdfd56
CI / test (push) Successful in 2m37s
Release rolling / release (push) Successful in 11m29s
Updates
2026-07-30 15:45:33 -04:00

130 lines
5.1 KiB
Markdown

# CI & pipelines
PearData mirrors the PearDock-style **cross-compile from one Linux runner** pipeline: Bare servers + Electron clients, published as rolling / tagged releases.
## Host matrix
| Product | Hosts |
|---------|-------|
| Server (Bare) | `linux-x64`, `linux-arm64` **only** |
| Client (Electron) | `linux-x64`, `linux-arm64`, `darwin-x64`, `darwin-arm64`, `win32-x64`, `win32-arm64` |
## Gitea Actions
| Workflow | Trigger | Job |
|----------|---------|-----|
| `.gitea/workflows/ci.yml` | push / PR / manual | install, `npm test` |
| `.gitea/workflows/release-rolling.yml` | **every** push to `main`/`master` + manual | test → build matrix → Gitea tag **`rolling`** |
Rolling job (ubuntu-latest, ~180m timeout):
1. System deps for Electron packaging
2. `npm ci --ignore-scripts` + esbuild install
3. `SKIP_INTEGRATION=1 npm test`
4. Install vendored `tools/rcodesign` (darwin client seal-sign)
5. `scripts/gitea-rolling-release.sh`
- `make.cjs server``peardata-server-*.tar.gz`
- `make.cjs client``peardata-client-*.tar.gz`
- upload to `rolling` prerelease
Manual inputs: `skip_client`, `server_hosts`, `client_hosts`, `dry_run`.
**Secret:** `RELEASE_TOKEN` (required to publish). Optional `GITEA_URL`.
## GitHub Actions
| Workflow | Trigger | Jobs |
|----------|---------|------|
| `.github/workflows/ci.yml` | push / PR / manual | **test** (Node 20+22), **lint-docs** |
| `.github/workflows/release.yml` | `v*` tags / manual | Same binary matrix → GitHub Release assets |
## Local parity
```bash
npm ci # includes @qvac/sdk for desktop LLM packaging
SKIP_INTEGRATION=1 npm test
# Server (Linux Bare)
npm run make:server:linux-x64
# Client (Electron) — ships QVAC Bare worker via @qvac/sdk/electron-forge
npm run make:client:linux-x64
# Tools-only client (skip native QVAC worker / larger natives)
PEARDATA_SKIP_QVAC=1 npm run make:client:linux-x64
# Full matrix (slow; QVAC raises client package time)
npm run make
# Stage release archives without upload
DRY_RUN=1 bash scripts/gitea-rolling-release.sh
```
## QVAC in release clients
| Item | Detail |
|------|--------|
| Dependency | `@qvac/sdk` in `package.json` **dependencies** (must install under this repo — not a parent hoist) |
| Forge plugin | `@qvac/sdk/electron-forge` + `@electron-forge/plugin-base` |
| Config | `qvac.config.json` — LLM plugin only |
| Asar | Forced **off** when QVAC packaging is enabled (Bare needs real paths) |
| Bare runtime | `bare-runtime` + `bare-runtime-<host>` must be **inside** the app `node_modules` |
| Skip | `PEARDATA_SKIP_QVAC=1` → tools-only client |
| Auto tools-only | `win32-arm64` (no `@qvac/llm-llamacpp` prebuild) — still ships client |
| Docs | [QVAC.md](./QVAC.md) · [Electron tutorial](https://docs.qvac.tether.io/tutorials/electron) |
### Cross-host Bare runtime (issue #1492)
CI runs on **Linux** but packages **darwin/win32** clients. `npm ci` skips optional
`bare-runtime-darwin-*` / `bare-runtime-win32-*` packages (os/cpu filters). Without them
the packaged app falls back to:
```text
Ready (tools-only: Could not load the Bare runtime binary for darwin-arm64 …
```
Release workflows and `make.cjs` install platform binaries via
`scripts/ensure-qvac-bare-runtimes.cjs`, which **`npm pack` + extracts** each
`bare-runtime-<host>` into `node_modules` (plain `npm install --force` is not
enough — npm's os/cpu filters drop foreign packages and can prune siblings).
```bash
# after npm ci on the Linux runner
node scripts/ensure-qvac-bare-runtimes.cjs --all
# or only hosts you will package
node scripts/ensure-qvac-bare-runtimes.cjs --hosts darwin-arm64,darwin-x64,linux-x64,win32-x64
```
`forge.config.cjs` also:
1. Runs the ensure script in `prePackage` for the target host
2. Copies `bare-runtime` + `bare-runtime-<host>` into the app if packager omitted them
3. **Fails the package** if the Bare binary is still missing when QVAC is enabled
Client package default timeout is **20 minutes** when QVAC is enabled (`PEARDATA_CLIENT_TIMEOUT_MS`).
## Key scripts
| Script | Role |
|--------|------|
| `scripts/install.sh` | End-user installer (server systemd + desktop client; journal + Docker socket when detected) |
| `scripts/hosts.cjs` | Host lists (`SERVER_LINUX`, `ALL_64`) |
| `scripts/make.cjs` | Orchestrate server/client builds |
| `scripts/bare-standalone.cjs` | Pack Bare `peardata-server` |
| `scripts/build-client-bundle.cjs` | esbuild GUI → `electron/app.bundle.cjs` |
| `scripts/build-qvac-worker.cjs` | Local `bundleSdk` for QVAC Bare worker |
| `scripts/ensure-qvac-bare-runtimes.cjs` | Force-install `bare-runtime-<host>` for cross-host QVAC clients |
| `scripts/predownload-electron.cjs` | Pre-fetch Electron zips for CI |
| `scripts/sign-macos-app.cjs` | Darwin client codesign |
| `scripts/gitea-rolling-release.sh` | Build + stage + Gitea upload |
| `forge.config.cjs` | Electron Forge + optional `QvacForgePlugin` |
## Integration tests in CI
Release workflows set `SKIP_INTEGRATION=1`. Unit CI may run integration when the runner allows DHT/UDP. See [TESTING.md](./TESTING.md).
## Related
- [RELEASE.md](./RELEASE.md)
- [TECH-CHOICES.md](./TECH-CHOICES.md) — Bare import maps