File size: 6,777 Bytes
ff7a361
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
# Development Commands

## Build & Development

- **`docker compose up`**: Start development server (main app on 7860, HMR on 7861)
- **`docker compose up --build`**: Compile for production
- **`docker compose exec development-server npm run start`**: Preview production build
- **`docker compose exec development-server npm run lint`**: Check code quality (Biome, TypeScript, knip, jscpd, architectural linter, documentation validator)
- **`docker compose exec development-server npm run format`**: Auto-format code with Biome

## Docker

- **`docker compose up`**: Development environment with SearXNG and Node.js
- **`docker compose -f docker-compose.production.yml up --build`**: Production deployment

## Testing

- **`docker compose exec development-server npm run test`**: Run Vitest tests
- **`docker compose exec development-server npm run test:watch`**: Run tests in watch mode
- **`docker compose exec development-server npm run test:coverage`**: Run tests with coverage report

Failure-injection cases (dependency down, empty results, aborted stream) are catalogued in `docs/failure-injection.md`.

## Offline eval

`eval/` is an offline eval that gives a regression signal for changes to the
reranker, the system prompt, the search-results formatting, or the model. See
`eval/README.md` for details and the LLM-judge environment variables.

- **`npm run eval`**: Run the full eval (retrieval + answer)
- **`npm run eval:retrieval`**: Retrieval eval (real ONNX reranker; local only, needs the model in `server/models/`)
- **`npm run eval:answer`**: Answer eval (LLM judge; gated on `EVAL_LLM_API_KEY`, skips without one)

### Coverage Reports for AI Analysis

After running `test:coverage`, AI agents can analyze these JSON files:

- **`coverage/coverage-summary.json`**: Quick metrics view - overall percentages per file
  ```json
  {
    "total": {
      "lines": { "total": 100, "covered": 85, "pct": 85 },
      "statements": { "total": 120, "covered": 100, "pct": 83.33 },
      "functions": { "total": 30, "covered": 25, "pct": 83.33 },
      "branches": { "total": 50, "covered": 40, "pct": 80 }
    },
    "/path/to/file.ts": { ... }
  }
  ```

- **`coverage/coverage-final.json`**: Detailed per-file coverage with line-by-line mapping
  - Use this to identify specific uncovered lines, branches, and functions
  - Maps statement/branch/function IDs to source locations

AI agents can parse these to identify:
- Files with coverage below thresholds
- Uncovered lines and branches
- Functions without tests
- Coverage gaps across the codebase

## CI/CD Pipeline

The repository uses nine GitHub Actions workflows for continuous integration, deployment, release management, security scanning, and issue triage:

### Workflow Files

| Workflow | Trigger | Purpose |
|---|---|---|
| `ci.yml` | Push/PR to `main` or `master` | Full lint (`npm run lint`), format check (`npm run format`), and Vitest test suite |
| `security.yml` | Push/PR to `main` or `master` | Secret scanning (Gitleaks) and license compliance check (`npm run license-check`) with artifact upload |
| `on-push-to-main.yml` | Push to `main` | Delegates to `reusable-check-docker.yml` |
| `on-pull-request-to-main.yml` | PR opened/synced/reopened to `main` | Delegates to `reusable-check-docker.yml`; skippable via `skip-check-docker` label |
| `publish-docker-image.yml` | Manual (`workflow_dispatch`), `main` only | Cuts a CalVer release: validates the optional `version` input (empty auto-computes today's date in UTC plus the next free same-day sequence), builds the multi-platform Docker image (linux/amd64, linux/arm64) and pushes it to `ghcr.io` as that version plus `latest` (build job, `contents: read` + `packages: write`), then a second job holding `contents: write` pushes the git tag and publishes the GitHub Release. The release job is idempotent: when a run pushed the tag but failed before publishing the Release, re-running that job alone finishes it without rebuilding |
| `scan-docker-image.yml` | Weekly (Monday 06:00 UTC) or manual | Trivy scan of the published image, reporting fixable HIGH/CRITICAL findings to code scanning |
| `deploy-to-hugging-face.yml` | Manual (`workflow_dispatch`) | Syncs the repository to a Hugging Face Space with the `hf` CLI over OIDC Trusted Publishers |
| `stale.yml` | Daily (01:30 UTC) or manual | Marks and closes inactive issues and labels stale pull requests |
| `reusable-check-docker.yml` | Called by other workflows | Docker compose production build + health check via `curl localhost:7860` (lint/format/test are covered by `ci.yml`) |

### Reusable Workflow (`reusable-check-docker.yml`)

Used by both `on-push-to-main` and `on-pull-request-to-main` to run the production container smoke test:

1. **check-docker-container** - Builds and starts the production container with `docker compose -f docker-compose.production.yml up -d`, then verifies the main page returns HTTP 200 within 60 seconds

### Docker Image Builds

The Docker image uses a single runtime stage:
The image installs Python/SearXNG, builds the Vite frontend, and runs SearXNG and Node.js in a single container via shell process composition. No compilation step is required: the reranker's ONNX Runtime binaries ship prebuilt with the npm dependency.

The production image is published to `ghcr.io` with multi-platform support (linux/amd64, linux/arm64). Labels are auto-generated from Git metadata via `docker/metadata-action`, and each release is published as `latest` and as its CalVer version tag; to pin a build, users reference the version tag or the image digest. Weekly, `scan-docker-image.yml` runs Trivy against the published `latest` and reports fixable HIGH/CRITICAL findings to code scanning.

### Manual Deployments

- **Publish Docker Image**: Triggered via GitHub UI from `main`, with an optional CalVer `version` input (leave it empty to auto-compute today's date in UTC and the next free same-day sequence) β€” builds and pushes the image to GitHub Container Registry, then pushes the git tag and publishes the GitHub Release
- **Deploy to Hugging Face**: Triggered via GitHub UI β€” syncs the repository to a Hugging Face Space using configuration from `.github/hf-space-config.yml`

## Quality Assurance

- **`docker compose exec development-server npm run lint`**: Biome linting, TypeScript checking, dependency validation, copy-paste detection, architectural validation, and documentation checks
- **`docker compose exec development-server npm run format`**: Format code with Biome (enforced via pre-commit hooks)

## Related Topics

- **Quick Start**: `docs/quick-start.md` - Installation and first run
- **Configuration**: `docs/configuration.md` - Environment variables
- **Pull Requests**: `docs/pull-requests.md` - Contribution workflow