7a0da7932b
OSV-Scanner (Scheduled) / scan-scheduled (push) Failing after 0s
Create Release / test-gate (push) Has been cancelled
Create Release / release-gate (push) Has been cancelled
Create Release / ci-gate (push) Has been cancelled
Create Release / version-check (push) Has been cancelled
Create Release / e2e-test-gate (push) Has been cancelled
Create Release / responsive-test-gate (push) Has been cancelled
Create Release / compat-test-gate (push) Has been cancelled
Create Release / compose-integration-gate (push) Has been cancelled
Create Release / vulture-gate (push) Has been cancelled
Create Release / build (push) Has been cancelled
Create Release / provenance (push) Has been cancelled
Create Release / prerelease-docker (push) Has been cancelled
Create Release / publish-docker (push) Has been cancelled
Create Release / create-release (push) Has been cancelled
Create Release / cleanup-changelog (push) Has been cancelled
Create Release / trigger-pypi (push) Has been cancelled
Create Release / monitor-pypi (push) Has been cancelled
Create Release / Clean up orphan prerelease tags and signatures (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [research-form] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [research-metrics] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [research-workflow] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [settings-core] (push) Has been cancelled
CodeQL Advanced / Analyze (javascript-typescript) (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [history-news] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [library] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [link-analytics] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [chat-core] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [chat-lifecycle] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [error-benchmark] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [settings-pages] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) (push) Has been cancelled
Docker Tests (Consolidated) / Accessibility Tests (push) Has been cancelled
Docker Tests (Consolidated) / LLM Unit Tests (push) Has been cancelled
Docker Tests (Consolidated) / LLM Example Tests (push) Has been cancelled
Docker Tests (Consolidated) / Production Image Smoke Test (push) Has been cancelled
Docker Tests (Consolidated) / Infrastructure Tests (push) Has been cancelled
OSSF Scorecard / OSSF Security Scorecard Analysis (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [mobile] (push) Has been cancelled
Backwards Compatibility / Verify Encryption Constants (push) Has been cancelled
Backwards Compatibility / PyPI Version Compatibility (push) Has been cancelled
Backwards Compatibility / Database Migration Tests (push) Has been cancelled
CodeQL Advanced / Analyze (python) (push) Has been cancelled
Docker Tests (Consolidated) / detect-changes (push) Has been cancelled
Docker Tests (Consolidated) / Build Test Image (push) Has been cancelled
Docker Tests (Consolidated) / All Pytest Tests + Coverage (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [accessibility] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [api-crud] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [auth-login] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [auth-pages] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [auth-register] (push) Has been cancelled
308 lines
12 KiB
Markdown
308 lines
12 KiB
Markdown
# CI/CD and Infrastructure Documentation
|
|
|
|
This document describes the continuous integration, security scanning, and development infrastructure used by the Local Deep Research project.
|
|
|
|
## Overview
|
|
|
|
The project uses many GitHub Actions workflows and 20+ pre-commit hooks to ensure code quality, security, and reliability.
|
|
|
|
> **At-a-glance health**: see [`docs/ci/workflow-status.md`](ci/workflow-status.md) — an auto-generated dashboard with live badges for every workflow, surfacing disabled, manual-only, and stale (silently-failing) ones at the top. Regenerate with `pdm run python scripts/generate_workflow_status.py`.
|
|
|
|
```
|
|
┌─────────────────────────────────────────────────────────────────┐
|
|
│ Developer Workflow │
|
|
├─────────────────────────────────────────────────────────────────┤
|
|
│ Local Development │ Pull Request │ Main/Dev │
|
|
│ ───────────────── │ ──────────── │ ──────── │
|
|
│ • Pre-commit hooks │ • All tests │ • Deploy │
|
|
│ • Unit tests │ • Security scans │ • Publish │
|
|
│ • Linting │ • Code review │ • Release │
|
|
└─────────────────────────────────────────────────────────────────┘
|
|
```
|
|
|
|
## Pre-Commit Hooks
|
|
|
|
Pre-commit hooks run locally before each commit. Install with:
|
|
|
|
```bash
|
|
pre-commit install
|
|
pre-commit install-hooks
|
|
```
|
|
|
|
### Standard Hooks
|
|
|
|
| Hook | Purpose |
|
|
|------|---------|
|
|
| `check-yaml` | Validate YAML syntax |
|
|
| `end-of-file-fixer` | Ensure files end with newline |
|
|
| `trailing-whitespace` | Remove trailing whitespace |
|
|
| `check-added-large-files` | Block files >1MB |
|
|
| `check-case-conflict` | Prevent case-sensitivity issues |
|
|
| `forbid-new-submodules` | Prevent git submodules |
|
|
|
|
### Security Hooks
|
|
|
|
| Hook | Purpose |
|
|
|------|---------|
|
|
| `gitleaks` | Detect secrets, API keys, passwords in code |
|
|
| `check-sensitive-logging` | Prevent logging of passwords, tokens, keys |
|
|
| `check-safe-requests` | Enforce SSRF-safe HTTP functions (`safe_get`, `safe_post`) |
|
|
| `check-url-security` | Validate URL handling in JavaScript (XSS prevention) |
|
|
| `file-whitelist-check` | Only allow approved file types |
|
|
| `check-image-pinning` | Require SHA256 digests for Docker images |
|
|
|
|
### Code Quality Hooks
|
|
|
|
| Hook | Purpose |
|
|
|------|---------|
|
|
| `ruff` | Python linter (with auto-fix) |
|
|
| `ruff-format` | Python formatter (Black-compatible) |
|
|
| `eslint` | JavaScript linter |
|
|
| `shellcheck` | Shell script linter |
|
|
| `actionlint` | GitHub Actions workflow validator |
|
|
| `custom-code-checks` | Loguru usage, UTC datetime, raw SQL detection |
|
|
|
|
### Project-Specific Hooks
|
|
|
|
| Hook | Purpose |
|
|
|------|---------|
|
|
| `check-env-vars` | Environment variables must use `SettingsManager` |
|
|
| `check-deprecated-db-connection` | Enforce per-user database connections |
|
|
| `check-ldr-db-usage` | Prevent shared `ldr.db` usage |
|
|
| `check-research-id-type` | `research_id` must be string/UUID, not int |
|
|
| `check-datetime-timezone` | All DateTime columns (models and migrations) must use `UtcDateTime` from `sqlalchemy_utc` |
|
|
| `check-session-context-manager` | Require context managers for DB sessions |
|
|
| `check-pathlib-usage` | Use `pathlib.Path` instead of `os.path` |
|
|
| `check-no-external-resources` | No external CDN/resource references |
|
|
| `check-css-class-prefix` | CSS classes must have `ldr-` prefix |
|
|
|
|
---
|
|
|
|
## GitHub Actions Workflows
|
|
|
|
### Test Workflows
|
|
|
|
| Workflow | Trigger | Purpose |
|
|
|----------|---------|---------|
|
|
| `docker-tests.yml` | PR, push | Consolidated Docker tests: pytest + coverage, UI tests (51 Puppeteer tests), LLM tests, infrastructure tests (single Docker build shared across all jobs). Includes tests previously in critical-ui-tests, extended-ui-tests, metrics-analytics-tests, library-ui-tests, mobile-ui-tests, and news-tests workflows. |
|
|
| `e2e-research-test.yml` | PR, push | End-to-end research flow |
|
|
| `fuzz.yml` | Schedule | Fuzzing tests |
|
|
|
|
### Security Scanning
|
|
|
|
| Workflow | Trigger | Purpose |
|
|
|----------|---------|---------|
|
|
| `codeql.yml` | PR, push, schedule | GitHub CodeQL analysis |
|
|
| `semgrep.yml` | PR, push | Semgrep static analysis |
|
|
| `osv-scanner.yml` | PR, push, schedule | OSV vulnerability scanning (Python + npm) |
|
|
| `gitleaks.yml` | PR, push | Secret detection |
|
|
| `security-tests.yml` | PR, push | Security-focused test suite |
|
|
| `devskim.yml` | PR, push | Microsoft DevSkim analysis |
|
|
| `checkov.yml` | PR, push | Infrastructure-as-code scanning |
|
|
| `container-security.yml` | PR, push | Container vulnerability scanning |
|
|
| `hadolint.yml` | PR, push | Dockerfile linting |
|
|
| `owasp-zap-scan.yml` | Schedule | OWASP ZAP dynamic scanning |
|
|
| `retirejs.yml` | PR, push | JavaScript vulnerability scanning |
|
|
| `zizmor-security.yml` | PR, push | Additional security checks |
|
|
| `ossf-scorecard.yml` | Schedule | OpenSSF Scorecard |
|
|
| `security-headers-validation.yml` | PR, push | HTTP security headers |
|
|
| `security-file-write-check.yml` | PR, push | File write security |
|
|
| `npm-audit.yml` | PR, push | npm audit for JS dependencies |
|
|
|
|
### Dependency Management
|
|
|
|
| Workflow | Trigger | Purpose |
|
|
|----------|---------|---------|
|
|
| `dependency-review.yml` | PR | Review dependency changes |
|
|
| `update-dependencies.yml` | Schedule | Auto-update Python deps |
|
|
| `update-npm-dependencies.yml` | Schedule | Auto-update npm deps |
|
|
| `update-precommit-hooks.yml` | Schedule | Update pre-commit hooks |
|
|
| `validate-image-pinning.yml` | PR, push | Verify Docker image pins |
|
|
|
|
### UI/Accessibility
|
|
|
|
| Workflow | Trigger | Purpose |
|
|
|----------|---------|---------|
|
|
| `responsive-ui-tests-enhanced.yml` | PR, push | Responsive design tests |
|
|
|
|
### Build & Deploy
|
|
|
|
| Workflow | Trigger | Purpose |
|
|
|----------|---------|---------|
|
|
| `prerelease-docker.yml` | `workflow_call` from release.yml | Canonical multi-arch Docker build, cosign sign, SBOM/SLSA attestations. Jobs declare `environment: release` so the first `release` env approval gates the build (env-scoped Docker Hub secrets). |
|
|
| `docker-publish.yml` | `workflow_call` from release.yml | Retag prerelease manifest as `:1.6.9` / `:1.6` / `:latest` (gated by `release` env). No rebuild — registry-side metadata only. Inlined as a reusable workflow so its result is visible to downstream jobs in release.yml (lets create-release block on Docker success, lets cleanup-on-rejection safely scope cosign artifact deletion). |
|
|
| `docker-multiarch-test.yml` | PR, push | Multi-architecture build test |
|
|
| `publish.yml` | `repository_dispatch` from release.yml | Publish to PyPI. Stays on `repository_dispatch` (not `workflow_call`) because PyPI Trusted Publishing rejects OIDC claims from reusable workflows — `pypa/gh-action-pypi-publish#166`, `pypi/warehouse#11096`. |
|
|
| `release.yml` | Push to `main`, tag `v*.*.*`, manual | Orchestrate release: gates → build → provenance → prerelease-docker → publish-docker → trigger-pypi → monitor-pypi → create-release (last) |
|
|
|
|
### Code Quality
|
|
|
|
| Workflow | Trigger | Purpose |
|
|
|----------|---------|---------|
|
|
| `pre-commit.yml` | PR, push | Run pre-commit hooks in CI |
|
|
| `mypy-type-check.yml` | PR, push | Python type checking |
|
|
| `ai-code-reviewer.yml` | PR | AI-assisted code review |
|
|
| `claude-code-review.yml` | PR | Claude-based code review |
|
|
|
|
### Repository Management
|
|
|
|
| Workflow | Trigger | Purpose |
|
|
|----------|---------|---------|
|
|
| `sync-main-to-dev.yml` | Push to main | Sync main branch to dev |
|
|
| `label-fixed-in-dev.yml` | Push to dev | Auto-label fixed issues |
|
|
| `danger-zone-alert.yml` | PR | Alert on sensitive file changes |
|
|
| `check-env-vars.yml` | PR, push | Environment variable validation |
|
|
| `file-whitelist-check.yml` | PR, push | File type validation |
|
|
| `version_check.yml` | PR, push | Version consistency check |
|
|
|
|
---
|
|
|
|
## Dependabot Configuration
|
|
|
|
Dependabot automatically creates PRs for dependency updates:
|
|
|
|
| Ecosystem | Directories | Schedule |
|
|
|-----------|-------------|----------|
|
|
| Python (pip) | `/` | Weekly (Monday 04:00) |
|
|
| npm | `/`, `/tests/*` | Weekly/Daily |
|
|
| GitHub Actions | `/` | Weekly |
|
|
| Docker | `/` | Daily |
|
|
|
|
---
|
|
|
|
## Coverage Reporting
|
|
|
|
Coverage reports are generated by the `docker-tests.yml` workflow (pytest-tests job):
|
|
|
|
- **HTML Report**: Deployed to GitHub Pages at `https://learningcircuit.github.io/local-deep-research/coverage/`
|
|
- **PR Comments**: Each PR receives a comment with coverage percentage
|
|
- **Badge**: Coverage badge updated via GitHub Gist
|
|
|
|
Configuration in `pyproject.toml`:
|
|
```toml
|
|
[tool.coverage.run]
|
|
source = ["src"]
|
|
omit = ["*/tests/*", "*/migrations/*"]
|
|
|
|
[tool.coverage.report]
|
|
exclude_lines = ["pragma: no cover", "if TYPE_CHECKING:"]
|
|
```
|
|
|
|
---
|
|
|
|
## Security Architecture
|
|
|
|
### Supply Chain Security
|
|
|
|
1. **Dependency Pinning**: All GitHub Actions use SHA256 digests
|
|
2. **Docker Image Pinning**: All base images use SHA256 digests
|
|
3. **Lock Files**: `pdm.lock` and `package-lock.json` committed
|
|
4. **Vulnerability Scanning**: OSV-Scanner, npm audit, RetireJS
|
|
|
|
### Runtime Security
|
|
|
|
1. **SSRF Protection**: `safe_get()`, `safe_post()`, `SafeSession` wrappers
|
|
2. **XSS Prevention**: DOMPurify for HTML sanitization
|
|
3. **SQL Injection**: SQLAlchemy ORM (no raw SQL)
|
|
4. **Secret Management**: Environment variables via `SettingsManager`
|
|
|
|
### Container Security
|
|
|
|
1. **Non-root User**: Containers run as `ldruser:1000`
|
|
2. **Minimal Base Image**: Python slim images
|
|
3. **Health Checks**: Docker health check endpoints
|
|
4. **Read-only Where Possible**: Minimal write permissions
|
|
|
|
---
|
|
|
|
## Running Tests Locally
|
|
|
|
### Quick Test (Unit Tests Only)
|
|
```bash
|
|
pdm run pytest tests/test_settings_manager.py tests/test_utils.py -v
|
|
```
|
|
|
|
### Full Test Suite
|
|
```bash
|
|
pdm run pytest tests/ --ignore=tests/ui_tests --ignore=tests/fuzz -v
|
|
```
|
|
|
|
### With Coverage
|
|
```bash
|
|
pdm run pytest tests/ --cov=src --cov-report=html -v
|
|
open coverage/htmlcov/index.html
|
|
```
|
|
|
|
### UI Tests (Requires Server)
|
|
```bash
|
|
# Terminal 1: Start server
|
|
pdm run ldr-web
|
|
|
|
# Terminal 2: Run UI tests
|
|
cd tests/ui_tests && npm test
|
|
```
|
|
|
|
---
|
|
|
|
## Docker Testing
|
|
|
|
Build and run tests in Docker:
|
|
|
|
```bash
|
|
# Build test image
|
|
docker build --target ldr-test -t ldr-test .
|
|
|
|
# Run tests
|
|
docker run --rm -v "$PWD":/app -w /app ldr-test \
|
|
pytest tests/ --ignore=tests/ui_tests -v
|
|
```
|
|
|
|
---
|
|
|
|
## Environment Variables for CI
|
|
|
|
| Variable | Purpose |
|
|
|----------|---------|
|
|
| `CI=true` | Indicates CI environment |
|
|
| `LDR_TESTING_WITH_MOCKS=true` | Enable test mocks |
|
|
| `LDR_DISABLE_RATE_LIMITING=true` | Disable HTTP rate limits in tests (canonical name). The legacy `DISABLE_RATE_LIMITING=true` is still honored but emits a deprecation warning. Distinct from `LDR_RATE_LIMITING_ENABLED`, which controls the adaptive search-engine rate limiter — different subsystem. |
|
|
|
|
---
|
|
|
|
## Adding New Workflows
|
|
|
|
When adding a new workflow:
|
|
|
|
1. Use pinned action versions with SHA256 digests
|
|
2. Add `permissions: {}` at top level (minimal permissions)
|
|
3. Add job-level permissions as needed
|
|
4. Include `step-security/harden-runner` step
|
|
5. Add workflow to this documentation
|
|
|
|
Example template:
|
|
```yaml
|
|
name: New Workflow
|
|
|
|
on:
|
|
pull_request:
|
|
branches: [main]
|
|
|
|
permissions: {}
|
|
|
|
jobs:
|
|
example:
|
|
runs-on: ubuntu-latest
|
|
permissions:
|
|
contents: read
|
|
|
|
steps:
|
|
- name: Harden the runner
|
|
uses: step-security/harden-runner@... # pinned
|
|
with:
|
|
egress-policy: audit
|
|
|
|
- uses: actions/checkout@... # pinned
|
|
with:
|
|
persist-credentials: false
|
|
```
|