mirror of
https://github.com/blackboxprogramming/BlackRoad-Operating-System.git
synced 2026-03-17 07:57:19 -05:00
Prevent BlackRoad-Operating-System monorepo from being added to Railway services
CRITICAL CHANGES: - Add comprehensive deployment architecture documentation - Prevent misconfiguration where monorepo is deployed instead of satellites - Clarify monorepo-to-satellite sync model across all docs CHANGES: 1. railway.toml - Add critical warning banner at top of file - Mark config as local development/testing only - Explain correct deployment model (satellites, not monorepo) 2. DEPLOYMENT_ARCHITECTURE.md (NEW) - Complete 500+ line deployment guide - Monorepo vs satellite model explained in detail - Critical rules: NEVER add monorepo to Railway - Service-to-repository mapping - Environment configuration guide - Cloudflare DNS configuration - Common mistakes and troubleshooting 3. README.md - Add prominent deployment warning box - Clarify monorepo is source of truth, not deployable - List satellite repos that should be deployed - Reference DEPLOYMENT_ARCHITECTURE.md 4. CLAUDE.md - Add critical deployment model section - Clarify Railway deployment is satellite-only - Update deployment workflow explanation - Add key rules for deployment 5. backend/.env.example - Fix ALLOWED_ORIGINS to reference satellites - Remove monorepo Railway URL reference - Add correct satellite service URLs 6. ops/domains.yaml - Fix os.blackroad.systems DNS target - Point to blackroad-os-core-production (satellite) - Remove incorrect monorepo Railway URL 7. scripts/validate_deployment_config.py (NEW) - Automated validation script - Checks for monorepo references in configs - Validates railway.toml, env files, DNS configs - Ensures DEPLOYMENT_ARCHITECTURE.md exists - Exit code 0 = pass, 1 = fail WHY THIS MATTERS: - Adding monorepo to Railway creates circular deploy loops - Environment variables break (wrong service URLs) - Cloudflare routing fails - Service dependencies misconfigured - Prevents production outages from misconfiguration CORRECT MODEL: - Monorepo = source of truth (orchestration only) - Satellites = deployable services (Railway deployment) - Code flows: monorepo → sync → satellite → Railway See: DEPLOYMENT_ARCHITECTURE.md for complete details
This commit is contained in:
69
CLAUDE.md
69
CLAUDE.md
@@ -578,29 +578,55 @@ async def test_create_user(client: AsyncClient):
|
|||||||
|
|
||||||
## Deployment
|
## Deployment
|
||||||
|
|
||||||
### Railway (Backend)
|
### ⚠️ CRITICAL: Monorepo vs Satellite Deployment Model
|
||||||
|
|
||||||
**Configuration** (`railway.toml`):
|
**This repository (`BlackRoad-Operating-System`) is NOT deployed to production.**
|
||||||
```toml
|
|
||||||
[build]
|
|
||||||
builder = "DOCKERFILE"
|
|
||||||
dockerfilePath = "backend/Dockerfile"
|
|
||||||
|
|
||||||
[deploy]
|
BlackRoad OS uses a **monorepo-to-satellite sync architecture**:
|
||||||
startCommand = "cd backend && uvicorn app.main:app --host 0.0.0.0 --port $PORT"
|
|
||||||
healthcheck.path = "/health"
|
|
||||||
```
|
|
||||||
|
|
||||||
**Deployment Steps**:
|
**Monorepo Role** (`BlackRoad-Operating-System`):
|
||||||
1. Push to main branch
|
- ❌ **NOT deployed** to Railway or any production environment
|
||||||
2. GitHub Action triggers Railway deploy
|
- ✅ Source of truth for all service code
|
||||||
3. Railway builds Docker image
|
- ✅ Syncs code to satellite repos via GitHub Actions
|
||||||
4. Runs Alembic migrations
|
- ✅ Orchestration, prompts, and infrastructure configs
|
||||||
5. Starts FastAPI server
|
|
||||||
6. Health check validation
|
|
||||||
7. Traffic cutover
|
|
||||||
|
|
||||||
**Manual Deploy**:
|
**Satellite Role** (Deployable Services):
|
||||||
|
- ✅ **ONLY satellites are deployed** to Railway
|
||||||
|
- Each satellite = one deployable service
|
||||||
|
- Satellites: `blackroad-os-core`, `blackroad-os-api`, `blackroad-os-operator`, `blackroad-os-prism-console`, `blackroad-os-docs`, `blackroad-os-web`
|
||||||
|
|
||||||
|
**Key Rules**:
|
||||||
|
1. ❌ **NEVER** add `BlackRoad-Operating-System` as a Railway service
|
||||||
|
2. ❌ **NEVER** reference monorepo in env vars or service configs
|
||||||
|
3. ❌ **NEVER** point Cloudflare to monorepo URLs
|
||||||
|
4. ✅ **ALWAYS** deploy satellite repos individually
|
||||||
|
5. ✅ **ALWAYS** edit code in monorepo (syncs to satellites automatically)
|
||||||
|
|
||||||
|
**See**: `DEPLOYMENT_ARCHITECTURE.md` for complete deployment model and troubleshooting.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Railway (Satellite Deployment)
|
||||||
|
|
||||||
|
**IMPORTANT**: The `railway.toml` in this repo is for **local development/testing only**.
|
||||||
|
|
||||||
|
**Production deployment** is done via satellite repositories:
|
||||||
|
- `BlackRoad-OS/blackroad-os-core` → `blackroad-os-core-production` (Railway service)
|
||||||
|
- `BlackRoad-OS/blackroad-os-api` → `blackroad-os-api-production` (Railway service)
|
||||||
|
- `BlackRoad-OS/blackroad-os-operator` → `blackroad-os-operator-production` (Railway service)
|
||||||
|
- `BlackRoad-OS/blackroad-os-prism-console` → `blackroad-os-prism-console-production` (Railway service)
|
||||||
|
- `BlackRoad-OS/blackroad-os-docs` → `blackroad-os-docs-production` (Railway service)
|
||||||
|
|
||||||
|
**Deployment Flow**:
|
||||||
|
1. Edit code in monorepo (e.g., `services/core-api/`)
|
||||||
|
2. Commit and push to `main`
|
||||||
|
3. GitHub Action syncs to satellite (e.g., `BlackRoad-OS/blackroad-os-core`)
|
||||||
|
4. Satellite triggers Railway deployment
|
||||||
|
5. Railway builds Docker image
|
||||||
|
6. Runs migrations
|
||||||
|
7. Deploys to production
|
||||||
|
|
||||||
|
**Local Railway Testing** (monorepo only):
|
||||||
```bash
|
```bash
|
||||||
# Install Railway CLI
|
# Install Railway CLI
|
||||||
curl -fsSL https://railway.app/install.sh | sh
|
curl -fsSL https://railway.app/install.sh | sh
|
||||||
@@ -608,10 +634,13 @@ curl -fsSL https://railway.app/install.sh | sh
|
|||||||
# Login
|
# Login
|
||||||
railway login
|
railway login
|
||||||
|
|
||||||
# Deploy
|
# Deploy locally (NOT for production)
|
||||||
railway up
|
railway up
|
||||||
```
|
```
|
||||||
|
|
||||||
|
**Production Railway Deploy** (satellites):
|
||||||
|
Done automatically via GitHub Actions when satellite repos update.
|
||||||
|
|
||||||
### GitHub Pages (Frontend)
|
### GitHub Pages (Frontend)
|
||||||
|
|
||||||
**Deployment**:
|
**Deployment**:
|
||||||
|
|||||||
523
DEPLOYMENT_ARCHITECTURE.md
Normal file
523
DEPLOYMENT_ARCHITECTURE.md
Normal file
@@ -0,0 +1,523 @@
|
|||||||
|
# BlackRoad OS Deployment Architecture
|
||||||
|
|
||||||
|
> **Last Updated**: 2025-11-19
|
||||||
|
> **Status**: Canonical deployment model for all BlackRoad OS services
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Table of Contents
|
||||||
|
|
||||||
|
1. [Overview](#overview)
|
||||||
|
2. [The Monorepo vs Satellite Model](#the-monorepo-vs-satellite-model)
|
||||||
|
3. [Critical Rules](#critical-rules)
|
||||||
|
4. [Deployment Topology](#deployment-topology)
|
||||||
|
5. [Service-to-Repository Mapping](#service-to-repository-mapping)
|
||||||
|
6. [Environment Configuration](#environment-configuration)
|
||||||
|
7. [Cloudflare DNS Configuration](#cloudflare-dns-configuration)
|
||||||
|
8. [Common Mistakes to Avoid](#common-mistakes-to-avoid)
|
||||||
|
9. [Troubleshooting](#troubleshooting)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Overview
|
||||||
|
|
||||||
|
BlackRoad OS uses a **monorepo-to-satellite sync architecture** where:
|
||||||
|
|
||||||
|
- **`BlackRoad-Operating-System`** (this repo) = Source of truth, orchestration, sync logic
|
||||||
|
- **Satellite repos** (`blackroad-os-core`, `blackroad-os-api`, etc.) = Deployable services
|
||||||
|
|
||||||
|
This document establishes the canonical deployment model to prevent misconfiguration.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## The Monorepo vs Satellite Model
|
||||||
|
|
||||||
|
### BlackRoad-Operating-System (Monorepo)
|
||||||
|
|
||||||
|
**Purpose**: Control plane and source of truth
|
||||||
|
|
||||||
|
**Role**:
|
||||||
|
- Houses all service code in `services/`, `apps/`, `docs/`
|
||||||
|
- Syncs code to satellite repos via GitHub Actions
|
||||||
|
- Stores orchestration logic, prompts, and infrastructure configs
|
||||||
|
- Serves as the "brain" - NOT the compute
|
||||||
|
|
||||||
|
**Deployment Status**: ❌ **NEVER DEPLOYED TO PRODUCTION**
|
||||||
|
|
||||||
|
**Why NOT deployable**:
|
||||||
|
- No single entry point (contains multiple services)
|
||||||
|
- Would create circular deployment dependencies
|
||||||
|
- Not designed for runtime execution
|
||||||
|
- Would break service discovery and routing
|
||||||
|
|
||||||
|
### Satellite Repositories
|
||||||
|
|
||||||
|
**Purpose**: Deployable, runtime services
|
||||||
|
|
||||||
|
**Satellites**:
|
||||||
|
| Repository | Purpose | Railway Service | Cloudflare Domain |
|
||||||
|
|------------|---------|-----------------|-------------------|
|
||||||
|
| `blackroad-os-core` | Core API & business logic | `blackroad-os-core-production` | `core.blackroad.systems` |
|
||||||
|
| `blackroad-os-api` | Public API gateway | `blackroad-os-api-production` | `api.blackroad.systems` |
|
||||||
|
| `blackroad-os-operator` | Agent runtime & orchestrator | `blackroad-os-operator-production` | `operator.blackroad.systems` |
|
||||||
|
| `blackroad-os-prism-console` | Status console frontend | `blackroad-os-prism-console-production` | `prism.blackroad.systems` |
|
||||||
|
| `blackroad-os-docs` | Documentation site | `blackroad-os-docs-production` | `docs.blackroad.systems` |
|
||||||
|
| `blackroad-os-web` | Public website | `blackroad-os-web-production` | `blackroad.systems` |
|
||||||
|
|
||||||
|
**Deployment Status**: ✅ **EACH DEPLOYED INDEPENDENTLY TO RAILWAY**
|
||||||
|
|
||||||
|
**Sync Process**:
|
||||||
|
1. Developer edits code in monorepo (e.g., `services/core-api/`)
|
||||||
|
2. GitHub Action syncs changes to satellite (`BlackRoad-OS/blackroad-os-core`)
|
||||||
|
3. Satellite triggers Railway deployment
|
||||||
|
4. Railway deploys to production
|
||||||
|
|
||||||
|
**See**: `docs/os/monorepo-sync.md` for sync details
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Critical Rules
|
||||||
|
|
||||||
|
### ❌ NEVER DO THIS
|
||||||
|
|
||||||
|
1. **Never add `BlackRoad-Operating-System` to Railway as a service**
|
||||||
|
- Not in production environments
|
||||||
|
- Not in staging environments
|
||||||
|
- Not in development environments (unless explicitly testing locally)
|
||||||
|
|
||||||
|
2. **Never reference the monorepo in service configurations**
|
||||||
|
- Don't add it to env vars (e.g., `MONOREPO_URL`)
|
||||||
|
- Don't add it as a dependency in other services
|
||||||
|
- Don't point Cloudflare to the monorepo
|
||||||
|
|
||||||
|
3. **Never deploy the monorepo to production**
|
||||||
|
- It's not designed to run as a service
|
||||||
|
- It will break everything
|
||||||
|
|
||||||
|
### ✅ ALWAYS DO THIS
|
||||||
|
|
||||||
|
1. **Deploy ONLY satellite repos to Railway**
|
||||||
|
- Each satellite = one Railway service
|
||||||
|
- Each service = one environment (dev, staging, production)
|
||||||
|
|
||||||
|
2. **Edit code ONLY in the monorepo**
|
||||||
|
- Satellites are read-only mirrors
|
||||||
|
- All changes flow: monorepo → sync → satellite → deploy
|
||||||
|
|
||||||
|
3. **Point Cloudflare ONLY to satellite Railway URLs**
|
||||||
|
- `core.blackroad.systems` → `blackroad-os-core-production.up.railway.app`
|
||||||
|
- `api.blackroad.systems` → `blackroad-os-api-production.up.railway.app`
|
||||||
|
- etc.
|
||||||
|
|
||||||
|
4. **Create production environments for ALL satellites**
|
||||||
|
- Each satellite needs: dev, staging, production
|
||||||
|
- Example: `blackroad-os-core-dev`, `blackroad-os-core-staging`, `blackroad-os-core-production`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Deployment Topology
|
||||||
|
|
||||||
|
```
|
||||||
|
┌─────────────────────────────────────────────────────────────┐
|
||||||
|
│ BlackRoad-Operating-System (Monorepo) │
|
||||||
|
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
|
||||||
|
│ │ services/ │ │ apps/ │ │ docs/ │ │
|
||||||
|
│ │ core-api/ │ │ prism-console│ │ site/ │ │
|
||||||
|
│ │ public-api/ │ │ web/ │ │ │ │
|
||||||
|
│ │ operator/ │ │ │ │ │ │
|
||||||
|
│ └──────────────┘ └──────────────┘ └──────────────┘ │
|
||||||
|
│ │ │ │ │
|
||||||
|
│ └──────────────────┴──────────────────┘ │
|
||||||
|
│ GitHub Actions Sync │
|
||||||
|
└─────────────────────────────────────────────────────────────┘
|
||||||
|
↓
|
||||||
|
┌─────────────────────────────────────────────────────────────┐
|
||||||
|
│ Satellite Repositories (Deployable) │
|
||||||
|
│ ┌────────────────┐ ┌────────────────┐ ┌────────────────┐│
|
||||||
|
│ │ blackroad-os- │ │ blackroad-os- │ │ blackroad-os- ││
|
||||||
|
│ │ core │ │ api │ │ operator ││
|
||||||
|
│ └────────────────┘ └────────────────┘ └────────────────┘│
|
||||||
|
│ ┌────────────────┐ ┌────────────────┐ ┌────────────────┐│
|
||||||
|
│ │ blackroad-os- │ │ blackroad-os- │ │ blackroad-os- ││
|
||||||
|
│ │ prism-console │ │ web │ │ docs ││
|
||||||
|
│ └────────────────┘ └────────────────┘ └────────────────┘│
|
||||||
|
└─────────────────────────────────────────────────────────────┘
|
||||||
|
↓
|
||||||
|
┌─────────────────────────────────────────────────────────────┐
|
||||||
|
│ Railway (Deployment Platform) │
|
||||||
|
│ ┌────────────────┐ ┌────────────────┐ ┌────────────────┐│
|
||||||
|
│ │ core-production│ │ api-production │ │ operator-prod ││
|
||||||
|
│ │ .up.railway.app│ │ .up.railway.app│ │ .up.railway.app││
|
||||||
|
│ └────────────────┘ └────────────────┘ └────────────────┘│
|
||||||
|
└─────────────────────────────────────────────────────────────┘
|
||||||
|
↓
|
||||||
|
┌─────────────────────────────────────────────────────────────┐
|
||||||
|
│ Cloudflare (DNS & Routing) │
|
||||||
|
│ core.blackroad.systems → blackroad-os-core-production │
|
||||||
|
│ api.blackroad.systems → blackroad-os-api-production │
|
||||||
|
│ operator.blackroad.systems → blackroad-os-operator-production│
|
||||||
|
└─────────────────────────────────────────────────────────────┘
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Service-to-Repository Mapping
|
||||||
|
|
||||||
|
### Canonical Mapping
|
||||||
|
|
||||||
|
Defined in `infra/github/sync-config.yml`:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
services:
|
||||||
|
core-api:
|
||||||
|
monorepo_path: "services/core-api"
|
||||||
|
target_repo: "BlackRoad-OS/blackroad-os-core"
|
||||||
|
target_branch: "main"
|
||||||
|
public-api:
|
||||||
|
monorepo_path: "services/public-api"
|
||||||
|
target_repo: "BlackRoad-OS/blackroad-os-api"
|
||||||
|
target_branch: "main"
|
||||||
|
operator:
|
||||||
|
monorepo_path: "services/operator"
|
||||||
|
target_repo: "BlackRoad-OS/blackroad-os-operator"
|
||||||
|
target_branch: "main"
|
||||||
|
|
||||||
|
apps:
|
||||||
|
prism-console:
|
||||||
|
monorepo_path: "apps/prism-console"
|
||||||
|
target_repo: "BlackRoad-OS/blackroad-os-prism-console"
|
||||||
|
target_branch: "main"
|
||||||
|
web:
|
||||||
|
monorepo_path: "apps/web"
|
||||||
|
target_repo: "BlackRoad-OS/blackroad-os-web"
|
||||||
|
target_branch: "main"
|
||||||
|
|
||||||
|
docs:
|
||||||
|
site:
|
||||||
|
monorepo_path: "docs/site"
|
||||||
|
target_repo: "BlackRoad-OS/blackroad-os-docs"
|
||||||
|
target_branch: "main"
|
||||||
|
```
|
||||||
|
|
||||||
|
### Development Workflow
|
||||||
|
|
||||||
|
1. **Edit in monorepo**: `services/core-api/app/main.py`
|
||||||
|
2. **Commit to monorepo**: `git commit -m "Add health endpoint"`
|
||||||
|
3. **Push to monorepo**: `git push origin main`
|
||||||
|
4. **GitHub Action syncs**: Copies `services/core-api/` → `BlackRoad-OS/blackroad-os-core`
|
||||||
|
5. **Railway deploys**: Deploys `blackroad-os-core` to production
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Environment Configuration
|
||||||
|
|
||||||
|
### Required Railway Environments
|
||||||
|
|
||||||
|
Each satellite repository needs THREE environments:
|
||||||
|
|
||||||
|
1. **Development** (`-dev`)
|
||||||
|
- Connected to: `dev` or `develop` branch
|
||||||
|
- Example: `blackroad-os-core-dev.up.railway.app`
|
||||||
|
|
||||||
|
2. **Staging** (`-staging`)
|
||||||
|
- Connected to: `staging` branch
|
||||||
|
- Example: `blackroad-os-core-staging.up.railway.app`
|
||||||
|
|
||||||
|
3. **Production** (`-production`)
|
||||||
|
- Connected to: `main` branch
|
||||||
|
- Example: `blackroad-os-core-production.up.railway.app`
|
||||||
|
|
||||||
|
### Environment Variables by Service
|
||||||
|
|
||||||
|
#### Core API (`blackroad-os-core`)
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Database
|
||||||
|
DATABASE_URL=postgresql+asyncpg://...
|
||||||
|
REDIS_URL=redis://...
|
||||||
|
|
||||||
|
# Auth
|
||||||
|
SECRET_KEY=...
|
||||||
|
ACCESS_TOKEN_EXPIRE_MINUTES=30
|
||||||
|
|
||||||
|
# Service URLs
|
||||||
|
API_URL=https://api.blackroad.systems
|
||||||
|
OPERATOR_URL=https://operator.blackroad.systems
|
||||||
|
PRISM_URL=https://prism.blackroad.systems
|
||||||
|
|
||||||
|
# Environment
|
||||||
|
ENVIRONMENT=production
|
||||||
|
DEBUG=False
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Public API (`blackroad-os-api`)
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Core API reference
|
||||||
|
CORE_API_URL=https://core.blackroad.systems
|
||||||
|
|
||||||
|
# Auth
|
||||||
|
JWT_SECRET=...
|
||||||
|
|
||||||
|
# Environment
|
||||||
|
ENVIRONMENT=production
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Operator (`blackroad-os-operator`)
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Core API reference
|
||||||
|
CORE_API_URL=https://core.blackroad.systems
|
||||||
|
API_URL=https://api.blackroad.systems
|
||||||
|
|
||||||
|
# GitHub
|
||||||
|
GITHUB_TOKEN=...
|
||||||
|
GITHUB_APP_ID=...
|
||||||
|
|
||||||
|
# Environment
|
||||||
|
ENVIRONMENT=production
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Prism Console (`blackroad-os-prism-console`)
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Frontend env vars (Next.js)
|
||||||
|
NEXT_PUBLIC_CORE_API_URL=https://core.blackroad.systems
|
||||||
|
NEXT_PUBLIC_API_URL=https://api.blackroad.systems
|
||||||
|
NEXT_PUBLIC_OPERATOR_URL=https://operator.blackroad.systems
|
||||||
|
```
|
||||||
|
|
||||||
|
### ❌ NEVER Add These Vars
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# ❌ DO NOT ADD THESE - THEY WILL BREAK EVERYTHING
|
||||||
|
MONOREPO_URL=https://github.com/blackboxprogramming/BlackRoad-Operating-System
|
||||||
|
BLACKROAD_OS_REPO=BlackRoad-Operating-System
|
||||||
|
SOURCE_REPO=BlackRoad-Operating-System
|
||||||
|
```
|
||||||
|
|
||||||
|
**Why?** These vars reference the non-deployable monorepo, creating confusion and breaking service discovery.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Cloudflare DNS Configuration
|
||||||
|
|
||||||
|
### Canonical DNS Records
|
||||||
|
|
||||||
|
| Subdomain | Type | Target | Proxied |
|
||||||
|
|-----------|------|--------|---------|
|
||||||
|
| `blackroad.systems` | CNAME | `blackroad-os-web-production.up.railway.app` | ✅ Yes |
|
||||||
|
| `core.blackroad.systems` | CNAME | `blackroad-os-core-production.up.railway.app` | ✅ Yes |
|
||||||
|
| `api.blackroad.systems` | CNAME | `blackroad-os-api-production.up.railway.app` | ✅ Yes |
|
||||||
|
| `operator.blackroad.systems` | CNAME | `blackroad-os-operator-production.up.railway.app` | ✅ Yes |
|
||||||
|
| `prism.blackroad.systems` | CNAME | `blackroad-os-prism-console-production.up.railway.app` | ✅ Yes |
|
||||||
|
| `docs.blackroad.systems` | CNAME | `blackroad-os-docs-production.up.railway.app` | ✅ Yes |
|
||||||
|
| `os.blackroad.systems` | CNAME | `prism.blackroad.systems` | ✅ Yes |
|
||||||
|
|
||||||
|
### ❌ NEVER Point Cloudflare To
|
||||||
|
|
||||||
|
```
|
||||||
|
# ❌ WRONG - Monorepo is not deployed
|
||||||
|
core.blackroad.systems → blackroad-operating-system.up.railway.app
|
||||||
|
|
||||||
|
# ❌ WRONG - Monorepo doesn't exist on Railway
|
||||||
|
api.blackroad.systems → blackroad-os-monorepo-production.up.railway.app
|
||||||
|
```
|
||||||
|
|
||||||
|
**See**: `CLOUDFLARE_DNS_BLUEPRINT.md` for complete DNS configuration
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Common Mistakes to Avoid
|
||||||
|
|
||||||
|
### Mistake #1: Adding Monorepo to Railway
|
||||||
|
|
||||||
|
**Problem**:
|
||||||
|
```bash
|
||||||
|
# ❌ Creating Railway service for monorepo
|
||||||
|
railway link blackboxprogramming/BlackRoad-Operating-System
|
||||||
|
railway up
|
||||||
|
```
|
||||||
|
|
||||||
|
**Why it's wrong**:
|
||||||
|
- Monorepo contains multiple services (not a single deployable)
|
||||||
|
- No single entry point or health check
|
||||||
|
- Will create circular dependencies
|
||||||
|
|
||||||
|
**Solution**:
|
||||||
|
```bash
|
||||||
|
# ✅ Deploy satellite repos instead
|
||||||
|
railway link BlackRoad-OS/blackroad-os-core
|
||||||
|
railway up
|
||||||
|
```
|
||||||
|
|
||||||
|
### Mistake #2: Adding Monorepo to Service Env Vars
|
||||||
|
|
||||||
|
**Problem**:
|
||||||
|
```bash
|
||||||
|
# ❌ In blackroad-os-core environment
|
||||||
|
MONOREPO_URL=https://github.com/blackboxprogramming/BlackRoad-Operating-System
|
||||||
|
```
|
||||||
|
|
||||||
|
**Why it's wrong**:
|
||||||
|
- Services should reference other services, not the source repo
|
||||||
|
- Creates confusion between source code and runtime services
|
||||||
|
|
||||||
|
**Solution**:
|
||||||
|
```bash
|
||||||
|
# ✅ Reference other services instead
|
||||||
|
API_URL=https://api.blackroad.systems
|
||||||
|
OPERATOR_URL=https://operator.blackroad.systems
|
||||||
|
```
|
||||||
|
|
||||||
|
### Mistake #3: Pointing Cloudflare to Monorepo
|
||||||
|
|
||||||
|
**Problem**:
|
||||||
|
```
|
||||||
|
# ❌ Cloudflare DNS
|
||||||
|
core.blackroad.systems → blackroad-operating-system.up.railway.app
|
||||||
|
```
|
||||||
|
|
||||||
|
**Why it's wrong**:
|
||||||
|
- Monorepo is not deployed to Railway
|
||||||
|
- URL doesn't exist
|
||||||
|
- Will result in DNS failures
|
||||||
|
|
||||||
|
**Solution**:
|
||||||
|
```
|
||||||
|
# ✅ Point to satellite Railway URL
|
||||||
|
core.blackroad.systems → blackroad-os-core-production.up.railway.app
|
||||||
|
```
|
||||||
|
|
||||||
|
### Mistake #4: Editing Satellite Repos Directly
|
||||||
|
|
||||||
|
**Problem**:
|
||||||
|
```bash
|
||||||
|
# ❌ Editing blackroad-os-core directly
|
||||||
|
cd blackroad-os-core
|
||||||
|
git commit -m "Fix bug"
|
||||||
|
git push
|
||||||
|
```
|
||||||
|
|
||||||
|
**Why it's wrong**:
|
||||||
|
- Satellites are read-only mirrors
|
||||||
|
- Changes will be overwritten by next sync
|
||||||
|
- Creates drift between monorepo and satellite
|
||||||
|
|
||||||
|
**Solution**:
|
||||||
|
```bash
|
||||||
|
# ✅ Edit in monorepo
|
||||||
|
cd BlackRoad-Operating-System/services/core-api
|
||||||
|
# Make changes
|
||||||
|
git commit -m "Fix bug"
|
||||||
|
git push
|
||||||
|
# Sync workflow automatically updates satellite
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Troubleshooting
|
||||||
|
|
||||||
|
### Issue: "Service not deploying after code change"
|
||||||
|
|
||||||
|
**Diagnosis**:
|
||||||
|
1. Check if code was edited in monorepo (not satellite)
|
||||||
|
2. Verify sync workflow ran successfully
|
||||||
|
3. Check Railway deployment logs
|
||||||
|
|
||||||
|
**Solution**:
|
||||||
|
```bash
|
||||||
|
# 1. Verify sync workflow
|
||||||
|
gh workflow view sync-core-api
|
||||||
|
gh run list --workflow=sync-core-api
|
||||||
|
|
||||||
|
# 2. Manually trigger sync if needed
|
||||||
|
gh workflow run sync-core-api
|
||||||
|
|
||||||
|
# 3. Check Railway deployment
|
||||||
|
railway logs -s blackroad-os-core-production
|
||||||
|
```
|
||||||
|
|
||||||
|
### Issue: "Environment variables not resolving correctly"
|
||||||
|
|
||||||
|
**Diagnosis**:
|
||||||
|
1. Check if vars reference monorepo (wrong)
|
||||||
|
2. Verify service-to-service URLs are correct
|
||||||
|
3. Confirm Railway environment is set up properly
|
||||||
|
|
||||||
|
**Solution**:
|
||||||
|
```bash
|
||||||
|
# 1. List current env vars
|
||||||
|
railway variables
|
||||||
|
|
||||||
|
# 2. Remove monorepo references
|
||||||
|
railway variables delete MONOREPO_URL
|
||||||
|
|
||||||
|
# 3. Add correct service URLs
|
||||||
|
railway variables set CORE_API_URL=https://core.blackroad.systems
|
||||||
|
```
|
||||||
|
|
||||||
|
### Issue: "Cloudflare returning 522 errors"
|
||||||
|
|
||||||
|
**Diagnosis**:
|
||||||
|
1. Check if DNS points to correct Railway URL
|
||||||
|
2. Verify Railway service is running
|
||||||
|
3. Confirm health check is passing
|
||||||
|
|
||||||
|
**Solution**:
|
||||||
|
```bash
|
||||||
|
# 1. Check Railway service status
|
||||||
|
railway status
|
||||||
|
|
||||||
|
# 2. Verify health endpoint
|
||||||
|
curl https://blackroad-os-core-production.up.railway.app/health
|
||||||
|
|
||||||
|
# 3. Update Cloudflare DNS if needed
|
||||||
|
# (via Cloudflare dashboard: DNS → Edit CNAME)
|
||||||
|
```
|
||||||
|
|
||||||
|
### Issue: "Circular deployment loops"
|
||||||
|
|
||||||
|
**Diagnosis**:
|
||||||
|
- Monorepo may be configured as a dependency
|
||||||
|
- Service may be triggering its own deployment
|
||||||
|
|
||||||
|
**Solution**:
|
||||||
|
1. Remove monorepo from Railway services
|
||||||
|
2. Ensure satellites deploy independently
|
||||||
|
3. Check GitHub Actions triggers
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Summary
|
||||||
|
|
||||||
|
### The Golden Rules
|
||||||
|
|
||||||
|
1. **Monorepo = Source of Truth** (not deployed)
|
||||||
|
2. **Satellites = Deployable Services** (deployed to Railway)
|
||||||
|
3. **Edit in monorepo** → Sync to satellites → Deploy automatically
|
||||||
|
4. **Never add monorepo to Railway** or service configurations
|
||||||
|
5. **Cloudflare points to satellites**, not monorepo
|
||||||
|
|
||||||
|
### Quick Reference
|
||||||
|
|
||||||
|
**When you want to...**
|
||||||
|
|
||||||
|
- **Deploy a service**: Use satellite repo (`blackroad-os-core`), not monorepo
|
||||||
|
- **Edit code**: Edit in monorepo (`services/core-api`), not satellite
|
||||||
|
- **Configure DNS**: Point to satellite Railway URL, not monorepo
|
||||||
|
- **Set env vars**: Reference other services, not monorepo
|
||||||
|
- **Create new service**: Add to monorepo, create sync workflow, deploy satellite
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**For questions or issues**, see:
|
||||||
|
- `docs/os/monorepo-sync.md` - Sync process details
|
||||||
|
- `CLOUDFLARE_DNS_BLUEPRINT.md` - DNS configuration
|
||||||
|
- `infra/railway/ENVIRONMENT_GUIDE.md` - Railway setup
|
||||||
|
- `CLAUDE.md` - Development guide
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
*Last updated: 2025-11-19*
|
||||||
|
*This document is canonical for all BlackRoad OS deployments.*
|
||||||
20
README.md
20
README.md
@@ -31,6 +31,26 @@ BlackRoad OS is a fully functional web-based operating system interface that bri
|
|||||||
|
|
||||||
All BlackRoad services, apps, and docs now live in this monorepo and sync out automatically to their mirror repositories under the `BlackRoad-OS` GitHub organization. Edit here; automation mirrors to the satellites.
|
All BlackRoad services, apps, and docs now live in this monorepo and sync out automatically to their mirror repositories under the `BlackRoad-OS` GitHub organization. Edit here; automation mirrors to the satellites.
|
||||||
|
|
||||||
|
> ### ⚠️ CRITICAL DEPLOYMENT WARNING ⚠️
|
||||||
|
>
|
||||||
|
> **This repository is NOT deployed to production.**
|
||||||
|
>
|
||||||
|
> - ❌ **DO NOT** add `BlackRoad-Operating-System` to Railway as a service
|
||||||
|
> - ❌ **DO NOT** deploy this monorepo to any production environment
|
||||||
|
> - ❌ **DO NOT** reference this repo in service configurations or env vars
|
||||||
|
>
|
||||||
|
> **Deploy ONLY the satellite repositories:**
|
||||||
|
> - `blackroad-os-core` (Core API)
|
||||||
|
> - `blackroad-os-api` (Public API)
|
||||||
|
> - `blackroad-os-operator` (Agent Runtime)
|
||||||
|
> - `blackroad-os-prism-console` (Status Console)
|
||||||
|
> - `blackroad-os-docs` (Documentation)
|
||||||
|
> - `blackroad-os-web` (Public Website)
|
||||||
|
>
|
||||||
|
> **This repo is the source of truth for code**, but **satellites are the deployable services**.
|
||||||
|
>
|
||||||
|
> **See**: `DEPLOYMENT_ARCHITECTURE.md` for complete deployment model.
|
||||||
|
|
||||||
### Canonical layout
|
### Canonical layout
|
||||||
|
|
||||||
- `services/core-api` → `BlackRoad-OS/blackroad-os-core`
|
- `services/core-api` → `BlackRoad-OS/blackroad-os-core`
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ ALGORITHM=HS256
|
|||||||
ACCESS_TOKEN_EXPIRE_MINUTES=30
|
ACCESS_TOKEN_EXPIRE_MINUTES=30
|
||||||
REFRESH_TOKEN_EXPIRE_DAYS=7
|
REFRESH_TOKEN_EXPIRE_DAYS=7
|
||||||
WALLET_MASTER_KEY=changeme-wallet-master-key
|
WALLET_MASTER_KEY=changeme-wallet-master-key
|
||||||
ALLOWED_ORIGINS=https://blackroad.systems,https://www.blackroad.systems,https://os.blackroad.systems,https://blackroad-operating-system-production.up.railway.app,http://localhost:3000,http://localhost:8000
|
ALLOWED_ORIGINS=https://blackroad.systems,https://www.blackroad.systems,https://os.blackroad.systems,https://core.blackroad.systems,https://api.blackroad.systems,https://blackroad-os-core-production.up.railway.app,http://localhost:3000,http://localhost:8000
|
||||||
JWT_SECRET=changeme-jwt-secret
|
JWT_SECRET=changeme-jwt-secret
|
||||||
SESSION_SECRET=changeme-session-secret
|
SESSION_SECRET=changeme-session-secret
|
||||||
NEXTAUTH_SECRET=changeme-nextauth-secret
|
NEXTAUTH_SECRET=changeme-nextauth-secret
|
||||||
|
|||||||
@@ -32,9 +32,8 @@ domains:
|
|||||||
mode: "dns"
|
mode: "dns"
|
||||||
record:
|
record:
|
||||||
type: "CNAME"
|
type: "CNAME"
|
||||||
value: "blackroad-operating-system-production.up.railway.app"
|
value: "blackroad-os-core-production.up.railway.app" # Core API satellite service
|
||||||
value: "YOUR-PROD-RAILWAY-APP.up.railway.app" # replace with your Railway host
|
notes: "Alternative subdomain alias for the OS application - points to Core API satellite"
|
||||||
notes: "Alternative subdomain alias for the OS application"
|
|
||||||
|
|
||||||
- name: "blackroad.ai"
|
- name: "blackroad.ai"
|
||||||
type: "root"
|
type: "root"
|
||||||
|
|||||||
30
railway.toml
30
railway.toml
@@ -1,5 +1,33 @@
|
|||||||
|
# ==============================================================================
|
||||||
|
# ⚠️ CRITICAL WARNING - DO NOT USE THIS CONFIG IN PRODUCTION RAILWAY ⚠️
|
||||||
|
# ==============================================================================
|
||||||
|
#
|
||||||
|
# This railway.toml is for LOCAL DEVELOPMENT AND TESTING ONLY.
|
||||||
|
#
|
||||||
|
# ❌ DO NOT add "BlackRoad-Operating-System" as a Railway service
|
||||||
|
# ❌ DO NOT deploy this monorepo to production Railway environments
|
||||||
|
# ❌ DO NOT add this repo to service configurations or env vars
|
||||||
|
#
|
||||||
|
# ✅ CORRECT DEPLOYMENT MODEL:
|
||||||
|
# - This repo is the SOURCE OF TRUTH (orchestration/sync only)
|
||||||
|
# - Deploy ONLY the satellite repos to Railway:
|
||||||
|
# • blackroad-os-core (from BlackRoad-OS/blackroad-os-core)
|
||||||
|
# • blackroad-os-api (from BlackRoad-OS/blackroad-os-api)
|
||||||
|
# • blackroad-os-operator (from BlackRoad-OS/blackroad-os-operator)
|
||||||
|
# • blackroad-os-prism-console (from BlackRoad-OS/blackroad-os-prism-console)
|
||||||
|
# • blackroad-os-docs (from BlackRoad-OS/blackroad-os-docs)
|
||||||
|
#
|
||||||
|
# WHY THIS MATTERS:
|
||||||
|
# - Adding the monorepo to Railway will create circular deploy loops
|
||||||
|
# - Environment variables will break (wrong service URLs)
|
||||||
|
# - Cloudflare routing will fail
|
||||||
|
# - Service dependencies will be misconfigured
|
||||||
|
#
|
||||||
|
# See: docs/os/monorepo-sync.md and DEPLOYMENT_ARCHITECTURE.md
|
||||||
|
# ==============================================================================
|
||||||
|
|
||||||
# BlackRoad OS Monorepo - Railway Configuration
|
# BlackRoad OS Monorepo - Railway Configuration
|
||||||
# This configures multiple services from a single repository
|
# This configures multiple services from a single repository FOR LOCAL DEV ONLY
|
||||||
|
|
||||||
# Backend (Core API)
|
# Backend (Core API)
|
||||||
[[services]]
|
[[services]]
|
||||||
|
|||||||
373
scripts/validate_deployment_config.py
Executable file
373
scripts/validate_deployment_config.py
Executable file
@@ -0,0 +1,373 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
"""
|
||||||
|
Deployment Configuration Validator
|
||||||
|
|
||||||
|
This script validates that the BlackRoad-Operating-System monorepo
|
||||||
|
is NOT being incorrectly added to Railway configurations or service
|
||||||
|
environment variables.
|
||||||
|
|
||||||
|
Usage:
|
||||||
|
python scripts/validate_deployment_config.py
|
||||||
|
|
||||||
|
Exit codes:
|
||||||
|
0 - All validations passed
|
||||||
|
1 - Validation failures detected
|
||||||
|
|
||||||
|
Author: BlackRoad OS Team
|
||||||
|
Last Updated: 2025-11-19
|
||||||
|
"""
|
||||||
|
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
import re
|
||||||
|
import json
|
||||||
|
import yaml
|
||||||
|
from pathlib import Path
|
||||||
|
from typing import List, Tuple, Dict
|
||||||
|
|
||||||
|
# ANSI color codes
|
||||||
|
GREEN = "\033[92m"
|
||||||
|
RED = "\033[91m"
|
||||||
|
YELLOW = "\033[93m"
|
||||||
|
BLUE = "\033[94m"
|
||||||
|
RESET = "\033[0m"
|
||||||
|
BOLD = "\033[1m"
|
||||||
|
|
||||||
|
# Repository root
|
||||||
|
REPO_ROOT = Path(__file__).parent.parent
|
||||||
|
|
||||||
|
# Patterns that indicate monorepo is being incorrectly referenced
|
||||||
|
FORBIDDEN_PATTERNS = [
|
||||||
|
r"BlackRoad-Operating-System",
|
||||||
|
r"blackroad-operating-system",
|
||||||
|
r"BLACKROAD_OPERATING_SYSTEM",
|
||||||
|
r"monorepo\.up\.railway\.app",
|
||||||
|
r"blackroad-os-monorepo",
|
||||||
|
]
|
||||||
|
|
||||||
|
# Allowed contexts where monorepo reference is OK
|
||||||
|
ALLOWED_FILES = [
|
||||||
|
"README.md",
|
||||||
|
"DEPLOYMENT_ARCHITECTURE.md",
|
||||||
|
"CLAUDE.md",
|
||||||
|
"docs/",
|
||||||
|
".git/",
|
||||||
|
".github/",
|
||||||
|
"infra/github/",
|
||||||
|
"scripts/",
|
||||||
|
".md", # All markdown files (usually docs)
|
||||||
|
"IMPLEMENTATION", # Implementation plan docs
|
||||||
|
"PHASE", # Phase summary docs
|
||||||
|
"ORG_STRUCTURE.md",
|
||||||
|
"CODEBASE_STATUS.md",
|
||||||
|
]
|
||||||
|
|
||||||
|
# Files to check for forbidden patterns
|
||||||
|
CHECK_PATTERNS = [
|
||||||
|
"**/.env",
|
||||||
|
"**/.env.example",
|
||||||
|
"**/.env.production",
|
||||||
|
"**/.env.staging",
|
||||||
|
"**/.env.development",
|
||||||
|
"**/railway.json",
|
||||||
|
"**/vercel.json",
|
||||||
|
"**/netlify.toml",
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
class ValidationResult:
|
||||||
|
"""Stores validation results"""
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
self.errors: List[Tuple[str, str]] = []
|
||||||
|
self.warnings: List[Tuple[str, str]] = []
|
||||||
|
self.passed: List[str] = []
|
||||||
|
|
||||||
|
def add_error(self, check: str, message: str):
|
||||||
|
"""Add a validation error"""
|
||||||
|
self.errors.append((check, message))
|
||||||
|
|
||||||
|
def add_warning(self, check: str, message: str):
|
||||||
|
"""Add a validation warning"""
|
||||||
|
self.warnings.append((check, message))
|
||||||
|
|
||||||
|
def add_pass(self, check: str):
|
||||||
|
"""Add a passing check"""
|
||||||
|
self.passed.append(check)
|
||||||
|
|
||||||
|
def has_failures(self) -> bool:
|
||||||
|
"""Check if there are any failures"""
|
||||||
|
return len(self.errors) > 0
|
||||||
|
|
||||||
|
def print_summary(self):
|
||||||
|
"""Print validation summary"""
|
||||||
|
print(f"\n{BOLD}{'=' * 70}{RESET}")
|
||||||
|
print(f"{BOLD}Deployment Configuration Validation Results{RESET}")
|
||||||
|
print(f"{BOLD}{'=' * 70}{RESET}\n")
|
||||||
|
|
||||||
|
# Print errors
|
||||||
|
if self.errors:
|
||||||
|
print(f"{RED}{BOLD}❌ ERRORS ({len(self.errors)}):{RESET}")
|
||||||
|
for check, message in self.errors:
|
||||||
|
print(f"{RED} • {check}:{RESET} {message}")
|
||||||
|
print()
|
||||||
|
|
||||||
|
# Print warnings
|
||||||
|
if self.warnings:
|
||||||
|
print(f"{YELLOW}{BOLD}⚠️ WARNINGS ({len(self.warnings)}):{RESET}")
|
||||||
|
for check, message in self.warnings:
|
||||||
|
print(f"{YELLOW} • {check}:{RESET} {message}")
|
||||||
|
print()
|
||||||
|
|
||||||
|
# Print passed checks
|
||||||
|
if self.passed:
|
||||||
|
print(f"{GREEN}{BOLD}✅ PASSED ({len(self.passed)}):{RESET}")
|
||||||
|
for check in self.passed:
|
||||||
|
print(f"{GREEN} • {check}{RESET}")
|
||||||
|
print()
|
||||||
|
|
||||||
|
# Overall status
|
||||||
|
print(f"{BOLD}{'=' * 70}{RESET}")
|
||||||
|
if self.has_failures():
|
||||||
|
print(f"{RED}{BOLD}❌ VALIDATION FAILED{RESET}")
|
||||||
|
print(f"\nThe monorepo is being incorrectly referenced in deployment configs.")
|
||||||
|
print(f"See {BLUE}DEPLOYMENT_ARCHITECTURE.md{RESET} for correct deployment model.\n")
|
||||||
|
return 1
|
||||||
|
elif self.warnings:
|
||||||
|
print(f"{YELLOW}{BOLD}⚠️ VALIDATION PASSED WITH WARNINGS{RESET}\n")
|
||||||
|
return 0
|
||||||
|
else:
|
||||||
|
print(f"{GREEN}{BOLD}✅ ALL VALIDATIONS PASSED{RESET}\n")
|
||||||
|
return 0
|
||||||
|
|
||||||
|
|
||||||
|
def is_allowed_file(file_path: Path) -> bool:
|
||||||
|
"""Check if file is in allowed list for monorepo references"""
|
||||||
|
file_str = str(file_path)
|
||||||
|
for allowed in ALLOWED_FILES:
|
||||||
|
if allowed in file_str:
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
def check_railway_toml(result: ValidationResult):
|
||||||
|
"""Validate railway.toml is marked for local dev only"""
|
||||||
|
railway_toml = REPO_ROOT / "railway.toml"
|
||||||
|
|
||||||
|
if not railway_toml.exists():
|
||||||
|
result.add_warning("railway.toml", "File not found (OK if not using Railway)")
|
||||||
|
return
|
||||||
|
|
||||||
|
content = railway_toml.read_text()
|
||||||
|
|
||||||
|
# Check for warning banner
|
||||||
|
if "CRITICAL WARNING" not in content:
|
||||||
|
result.add_error(
|
||||||
|
"railway.toml",
|
||||||
|
"Missing CRITICAL WARNING banner at top of file"
|
||||||
|
)
|
||||||
|
|
||||||
|
# Check for "LOCAL DEV" or similar marker
|
||||||
|
if "LOCAL DEV" not in content and "DEVELOPMENT" not in content:
|
||||||
|
result.add_error(
|
||||||
|
"railway.toml",
|
||||||
|
"Not clearly marked as local development only"
|
||||||
|
)
|
||||||
|
|
||||||
|
if not result.errors:
|
||||||
|
result.add_pass("railway.toml has proper warnings")
|
||||||
|
|
||||||
|
|
||||||
|
def check_env_files(result: ValidationResult):
|
||||||
|
"""Check environment files for monorepo references"""
|
||||||
|
env_files = []
|
||||||
|
|
||||||
|
for pattern in CHECK_PATTERNS:
|
||||||
|
env_files.extend(REPO_ROOT.glob(pattern))
|
||||||
|
|
||||||
|
found_issues = False
|
||||||
|
checked_count = 0
|
||||||
|
|
||||||
|
for env_file in env_files:
|
||||||
|
if is_allowed_file(env_file):
|
||||||
|
continue
|
||||||
|
|
||||||
|
checked_count += 1
|
||||||
|
content = env_file.read_text()
|
||||||
|
|
||||||
|
for pattern in FORBIDDEN_PATTERNS:
|
||||||
|
matches = re.finditer(pattern, content, re.IGNORECASE)
|
||||||
|
for match in matches:
|
||||||
|
# Get line number
|
||||||
|
line_num = content[:match.start()].count('\n') + 1
|
||||||
|
result.add_error(
|
||||||
|
f"{env_file.name}:{line_num}",
|
||||||
|
f"Contains forbidden reference: '{match.group()}'"
|
||||||
|
)
|
||||||
|
found_issues = True
|
||||||
|
|
||||||
|
if checked_count == 0:
|
||||||
|
result.add_warning("env files", "No environment files found to check")
|
||||||
|
elif not found_issues:
|
||||||
|
result.add_pass(f"Environment files clean ({checked_count} checked)")
|
||||||
|
|
||||||
|
|
||||||
|
def check_satellite_configs(result: ValidationResult):
|
||||||
|
"""Check if satellites are properly configured"""
|
||||||
|
sync_config = REPO_ROOT / "infra/github/sync-config.yml"
|
||||||
|
|
||||||
|
if not sync_config.exists():
|
||||||
|
result.add_warning(
|
||||||
|
"sync-config.yml",
|
||||||
|
"Satellite sync config not found"
|
||||||
|
)
|
||||||
|
return
|
||||||
|
|
||||||
|
with open(sync_config) as f:
|
||||||
|
config = yaml.safe_load(f)
|
||||||
|
|
||||||
|
# Expected satellites
|
||||||
|
expected_services = ["core-api", "public-api", "operator"]
|
||||||
|
expected_apps = ["prism-console", "web"]
|
||||||
|
|
||||||
|
services = config.get("services", {})
|
||||||
|
apps = config.get("apps", {})
|
||||||
|
|
||||||
|
# Check all expected services are configured
|
||||||
|
missing_services = [s for s in expected_services if s not in services]
|
||||||
|
missing_apps = [a for a in expected_apps if a not in apps]
|
||||||
|
|
||||||
|
if missing_services:
|
||||||
|
result.add_warning(
|
||||||
|
"sync-config.yml",
|
||||||
|
f"Missing service configs: {', '.join(missing_services)}"
|
||||||
|
)
|
||||||
|
|
||||||
|
if missing_apps:
|
||||||
|
result.add_warning(
|
||||||
|
"sync-config.yml",
|
||||||
|
f"Missing app configs: {', '.join(missing_apps)}"
|
||||||
|
)
|
||||||
|
|
||||||
|
if not missing_services and not missing_apps:
|
||||||
|
result.add_pass("Satellite sync configuration complete")
|
||||||
|
|
||||||
|
|
||||||
|
def check_cloudflare_docs(result: ValidationResult):
|
||||||
|
"""Check Cloudflare documentation for correct DNS setup"""
|
||||||
|
cloudflare_doc = REPO_ROOT / "CLOUDFLARE_DNS_BLUEPRINT.md"
|
||||||
|
|
||||||
|
if not cloudflare_doc.exists():
|
||||||
|
result.add_warning(
|
||||||
|
"Cloudflare docs",
|
||||||
|
"CLOUDFLARE_DNS_BLUEPRINT.md not found"
|
||||||
|
)
|
||||||
|
return
|
||||||
|
|
||||||
|
content = cloudflare_doc.read_text()
|
||||||
|
|
||||||
|
# Check for incorrect monorepo references in DNS
|
||||||
|
forbidden_dns = [
|
||||||
|
"blackroad-operating-system.up.railway.app",
|
||||||
|
"monorepo.up.railway.app",
|
||||||
|
]
|
||||||
|
|
||||||
|
found_issues = False
|
||||||
|
for forbidden in forbidden_dns:
|
||||||
|
if forbidden in content.lower():
|
||||||
|
result.add_error(
|
||||||
|
"CLOUDFLARE_DNS_BLUEPRINT.md",
|
||||||
|
f"Contains forbidden DNS target: {forbidden}"
|
||||||
|
)
|
||||||
|
found_issues = True
|
||||||
|
|
||||||
|
if not found_issues:
|
||||||
|
result.add_pass("Cloudflare DNS documentation is correct")
|
||||||
|
|
||||||
|
|
||||||
|
def check_deployment_architecture_exists(result: ValidationResult):
|
||||||
|
"""Verify DEPLOYMENT_ARCHITECTURE.md exists"""
|
||||||
|
doc_path = REPO_ROOT / "DEPLOYMENT_ARCHITECTURE.md"
|
||||||
|
|
||||||
|
if not doc_path.exists():
|
||||||
|
result.add_error(
|
||||||
|
"DEPLOYMENT_ARCHITECTURE.md",
|
||||||
|
"Critical deployment documentation is missing"
|
||||||
|
)
|
||||||
|
return
|
||||||
|
|
||||||
|
content = doc_path.read_text()
|
||||||
|
|
||||||
|
# Check for key sections
|
||||||
|
required_sections = [
|
||||||
|
"Monorepo vs Satellite Model",
|
||||||
|
"Critical Rules",
|
||||||
|
"NEVER DO THIS",
|
||||||
|
"ALWAYS DO THIS",
|
||||||
|
]
|
||||||
|
|
||||||
|
missing_sections = []
|
||||||
|
for section in required_sections:
|
||||||
|
if section not in content:
|
||||||
|
missing_sections.append(section)
|
||||||
|
|
||||||
|
if missing_sections:
|
||||||
|
result.add_error(
|
||||||
|
"DEPLOYMENT_ARCHITECTURE.md",
|
||||||
|
f"Missing sections: {', '.join(missing_sections)}"
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
result.add_pass("DEPLOYMENT_ARCHITECTURE.md is complete")
|
||||||
|
|
||||||
|
|
||||||
|
def check_readme_warnings(result: ValidationResult):
|
||||||
|
"""Verify README.md has deployment warnings"""
|
||||||
|
readme = REPO_ROOT / "README.md"
|
||||||
|
|
||||||
|
if not readme.exists():
|
||||||
|
result.add_error("README.md", "README.md not found")
|
||||||
|
return
|
||||||
|
|
||||||
|
content = readme.read_text()
|
||||||
|
|
||||||
|
if "DEPLOYMENT WARNING" not in content:
|
||||||
|
result.add_error(
|
||||||
|
"README.md",
|
||||||
|
"Missing deployment warning section"
|
||||||
|
)
|
||||||
|
|
||||||
|
if "DO NOT" not in content or "satellite" not in content.lower():
|
||||||
|
result.add_error(
|
||||||
|
"README.md",
|
||||||
|
"Deployment warnings are not clear or comprehensive"
|
||||||
|
)
|
||||||
|
|
||||||
|
if not result.errors:
|
||||||
|
result.add_pass("README.md has proper deployment warnings")
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
"""Run all validation checks"""
|
||||||
|
print(f"\n{BOLD}{BLUE}BlackRoad OS Deployment Configuration Validator{RESET}")
|
||||||
|
print(f"{BLUE}{'=' * 70}{RESET}\n")
|
||||||
|
|
||||||
|
result = ValidationResult()
|
||||||
|
|
||||||
|
# Run all checks
|
||||||
|
print("Running validation checks...\n")
|
||||||
|
|
||||||
|
check_railway_toml(result)
|
||||||
|
check_env_files(result)
|
||||||
|
check_satellite_configs(result)
|
||||||
|
check_cloudflare_docs(result)
|
||||||
|
check_deployment_architecture_exists(result)
|
||||||
|
check_readme_warnings(result)
|
||||||
|
|
||||||
|
# Print results
|
||||||
|
exit_code = result.print_summary()
|
||||||
|
|
||||||
|
sys.exit(exit_code)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
Reference in New Issue
Block a user