Add monorepo sync scaffolding and workflows

This commit is contained in:
Alexa Amundson
2025-11-19 15:37:20 -06:00
parent 2610c3a07f
commit ed2083434d
14 changed files with 393 additions and 0 deletions

96
.github/workflows/deploy-core-api.yml vendored Normal file
View File

@@ -0,0 +1,96 @@
name: Deploy core-api to Railway
on:
push:
branches:
- main
paths:
- 'services/core-api/**'
- '.github/workflows/deploy-core-api.yml'
workflow_dispatch:
jobs:
deploy:
runs-on: ubuntu-latest
env:
SERVICE_KEY: core-api
SYNC_CONFIG: infra/github/sync-config.yml
steps:
- name: Checkout monorepo
uses: actions/checkout@v4
- name: Load service config
id: cfg
shell: bash
run: |
python - <<'PY'
import yaml, os
key = os.environ['SERVICE_KEY']
with open(os.environ['SYNC_CONFIG'], 'r') as f:
cfg = yaml.safe_load(f)
for section in ('services', 'apps', 'docs'):
if section in cfg and key in cfg[section]:
data = cfg[section][key]
break
else:
raise SystemExit(f"Service {key} not found in config")
print(f"monorepo_path={data['monorepo_path']}")
PY | tee /tmp/svc_env
while IFS='=' read -r name value; do
echo "$name=$value" >> "$GITHUB_OUTPUT"
done < /tmp/svc_env
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.x'
- name: Install service dependencies (placeholder)
working-directory: ${{ steps.cfg.outputs.monorepo_path }}
run: |
if [ -f requirements.txt ]; then
python -m pip install --upgrade pip
pip install -r requirements.txt
else
echo "No requirements.txt; skipping install"
fi
- name: Run service tests (placeholder)
working-directory: ${{ steps.cfg.outputs.monorepo_path }}
run: |
if [ -d tests ]; then
pytest --maxfail=1 --disable-warnings -q
else
echo "No tests directory; skipping"
fi
- name: Deploy to Railway
working-directory: ${{ steps.cfg.outputs.monorepo_path }}
env:
RAILWAY_TOKEN: ${{ secrets.RAILWAY_TOKEN }}
run: |
if [ -z "$RAILWAY_TOKEN" ]; then
echo "RAILWAY_TOKEN is required" >&2
exit 1
fi
# Replace this with the service-specific Railway command
railway up --service core-api --yes
- name: Post-deploy healthcheck
env:
CORE_API_HEALTHCHECK_URL: ${{ secrets.CORE_API_HEALTHCHECK_URL }}
run: |
if [ -z "$CORE_API_HEALTHCHECK_URL" ]; then
echo "CORE_API_HEALTHCHECK_URL not provided; skipping check"
exit 0
fi
status=$(curl -s -o /dev/null -w "%{http_code}" "$CORE_API_HEALTHCHECK_URL/health")
if [ "$status" != "200" ]; then
echo "Healthcheck failed with status $status" >&2
exit 1
fi
- name: Document environment expectations
run: |
echo "Expected env vars: CORE_API_DATABASE_URL, CORE_API_SECRET_KEY, CORE_API_ALLOWED_ORIGINS" \
"(see infra/railway/ENVIRONMENT_GUIDE.md)"

118
.github/workflows/sync-core-api.yml vendored Normal file
View File

@@ -0,0 +1,118 @@
name: Sync core-api to mirror
on:
push:
branches:
- main
paths:
- 'services/core-api/**'
- 'infra/github/sync-config.yml'
workflow_dispatch:
jobs:
sync:
runs-on: ubuntu-latest
env:
SERVICE_KEY: core-api
SYNC_CONFIG: infra/github/sync-config.yml
SYNC_TOKEN: ${{ secrets.BR_OS_SYNC_TOKEN }}
steps:
- name: Checkout monorepo
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Load service config
id: cfg
shell: bash
run: |
python - <<'PY'
import json, yaml, os
key = os.environ['SERVICE_KEY']
with open(os.environ['SYNC_CONFIG'], 'r') as f:
cfg = yaml.safe_load(f)
# service can live under services/apps/docs namespaces; search all
for section in ('services', 'apps', 'docs'):
if section in cfg and key in cfg[section]:
data = cfg[section][key]
break
else:
raise SystemExit(f"Service {key} not found in config")
for output_key, output_value in (
('monorepo_path', data['monorepo_path']),
('target_repo', data['target_repo']),
('target_branch', data.get('target_branch', 'main')),
('force_push', str(data.get('force_push', True)).lower()),
):
print(f"{output_key}={output_value}")
PY | tee /tmp/svc_env
while IFS='=' read -r name value; do
echo "$name=$value" >> "$GITHUB_OUTPUT"
done < /tmp/svc_env
- name: Export service directory
run: |
mkdir -p /tmp/export
rsync -av --delete "${{ steps.cfg.outputs.monorepo_path }}/" /tmp/export/
- name: Clone target repository
env:
TOKEN: ${{ env.SYNC_TOKEN }}
run: |
if [ -z "$TOKEN" ]; then
echo "BR_OS_SYNC_TOKEN is required" >&2
exit 1
fi
git clone "https://${TOKEN}@github.com/${{ steps.cfg.outputs.target_repo }}.git" /tmp/target
- name: Prepare mirror working tree
working-directory: /tmp/target
run: |
shopt -s dotglob
rm -rf -- * .[!.]* ..?*
shopt -u dotglob
mkdir -p .
rsync -av --delete /tmp/export/ ./
- name: Write sync status
working-directory: /tmp/target
run: |
cat <<'STATUS' > sync-status.md
# Sync Status
- Source repo: blackboxprogramming/BlackRoad-Operating-System
- Source path: ${{ steps.cfg.outputs.monorepo_path }}
- Source commit: ${{ github.sha }}
- Workflow run: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
STATUS
- name: Commit changes
working-directory: /tmp/target
run: |
git status
if git status --porcelain | grep .; then
git config user.name "blackroad-os-bot"
git config user.email "blackroad-os-bot@users.noreply.github.com"
git add .
git commit -m "Sync from BlackRoad-Operating-System: ${{ env.SERVICE_KEY }} @ ${{ github.sha }}"
else
echo "No changes to sync"
echo "skip_push=true" >> $GITHUB_OUTPUT
fi
id: commit
- name: Push mirror
if: steps.commit.outputs.skip_push != 'true'
working-directory: /tmp/target
env:
FORCE_PUSH: ${{ steps.cfg.outputs.force_push }}
run: |
if [ "$FORCE_PUSH" = "true" ]; then
git push origin "HEAD:${{ steps.cfg.outputs.target_branch }}" --force
else
git pull --rebase origin "${{ steps.cfg.outputs.target_branch }}"
git push origin "HEAD:${{ steps.cfg.outputs.target_branch }}"
fi

View File

@@ -27,6 +27,21 @@ It unifies humans, agents, and infrastructure into a single operating system for
BlackRoad OS is a fully functional web-based operating system interface that brings together AI orchestration, blockchain technology, social media, video streaming, and gaming - all wrapped in a nostalgic Windows 95 aesthetic. BlackRoad OS is a fully functional web-based operating system interface that brings together AI orchestration, blockchain technology, social media, video streaming, and gaming - all wrapped in a nostalgic Windows 95 aesthetic.
## Monorepo as the Source of Truth
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.
### Canonical layout
- `services/core-api``BlackRoad-OS/blackroad-os-core`
- `services/public-api``BlackRoad-OS/blackroad-os-api`
- `services/operator``BlackRoad-OS/blackroad-os-operator`
- `apps/prism-console``BlackRoad-OS/blackroad-os-prism-console`
- `apps/web``BlackRoad-OS/blackroad-os-web`
- `docs/site``BlackRoad-OS/blackroad-os-docs`
The mapping is machine-readable at `infra/github/sync-config.yml`, and the sync process is documented in `docs/os/monorepo-sync.md`.
## Features ## Features
### 🤖 AI & Communication ### 🤖 AI & Communication

View File

@@ -0,0 +1,7 @@
# Prism Console (monorepo-owned)
- **Canonical path:** `apps/prism-console`
- **Mirror:** `BlackRoad-OS/blackroad-os-prism-console`
- **Branch:** `main`
Front-end console code for Prism lives here. Automation syncs changes to the mirror repository.

7
apps/web/README.md Normal file
View File

@@ -0,0 +1,7 @@
# Web App (monorepo-owned)
- **Canonical path:** `apps/web`
- **Mirror:** `BlackRoad-OS/blackroad-os-web`
- **Branch:** `main`
This is the canonical source for the public web app. Edits here are mirrored automatically.

47
docs/os/monorepo-sync.md Normal file
View File

@@ -0,0 +1,47 @@
# BlackRoad OS Monorepo Sync
BlackRoad-Operating-System is the **single source of truth** for every service, app, and docs site under the BlackRoad OS umbrella. All satellite repositories are read-only mirrors. If it cannot be automated from this monorepo, it does not exist.
## Philosophy
- Edit code **only** in this repository.
- Each satellite repository maps to exactly one directory in the monorepo (see the mapping table below).
- GitHub Actions sync the relevant directory to its target repository after every change—no manual merges.
## Layout and Ownership
- `services/core-api``BlackRoad-OS/blackroad-os-core`
- `services/public-api``BlackRoad-OS/blackroad-os-api`
- `services/operator``BlackRoad-OS/blackroad-os-operator`
- `apps/prism-console``BlackRoad-OS/blackroad-os-prism-console`
- `apps/web``BlackRoad-OS/blackroad-os-web`
- `docs/site``BlackRoad-OS/blackroad-os-docs`
The authoritative mapping is codified in `infra/github/sync-config.yml`.
## How Sync Works
1. A push to `main` that touches a mapped path triggers its sync workflow.
2. The workflow checks out the monorepo, exports only the mapped directory, and clones the target repository using `${{ secrets.BR_OS_SYNC_TOKEN }}`.
3. The target repository is wiped (except `.git`), refreshed with the exported files, committed with the source SHA, and pushed (default is a force-push because the satellite is a mirror).
4. A `sync-status.md` file in the satellite captures the source SHA and workflow URL for traceability.
5. If there are no changes, the workflow exits cleanly.
## Onboarding a New Service
1. Add an entry to `infra/github/sync-config.yml` with `monorepo_path`, `target_repo`, `target_branch`, and optionally `force_push`.
2. Create the corresponding directory (for example `services/new-service/`) and populate it with code.
3. Add a new workflow in `.github/workflows/` (copy an existing sync workflow) that sets `SERVICE_KEY` to the new entry and sets the path filter to the new directory.
4. (Optional) Add a deploy workflow for the service that builds, tests, and deploys to Railway. Reference `infra/railway/ENVIRONMENT_GUIDE.md` for required env vars.
## Troubleshooting
- **Non-fast-forward errors:** set `force_push: true` for the service (default) or configure branch protection to allow the automation user to force-push.
- **Missing secrets:** ensure `${{ secrets.BR_OS_SYNC_TOKEN }}` is available to sync workflows and `${{ secrets.RAILWAY_TOKEN }}` to deploy workflows.
- **Path not syncing:** confirm the workflow `on.push.paths` matches the directory and that the `monorepo_path` in `sync-config.yml` is correct.
## Repository Guards for Mirrors
- Each mirror README should include a “Managed by Monorepo” banner (see `docs/os/satellite-readmes/README.blackroad-os-core.md`).
- Recommended branch protection on mirrors:
- Require the automation user to be the only actor allowed to force-push to `main`.
- Optionally block direct pushes and auto-close PRs with a comment pointing contributors to the monorepo path that owns the code.
## See Also
- `infra/github/sync-config.yml` for the canonical mapping.
- `docs/os/satellite-readmes/README.blackroad-os-core.md` for the managed-by-monorepo banner template.
- `infra/railway/ENVIRONMENT_GUIDE.md` for deployment expectations.

View File

@@ -0,0 +1,10 @@
# Managed by Monorepo
This repository is a read-only mirror of `blackboxprogramming/BlackRoad-Operating-System`.
- **Source path:** `services/core-api`
- **Do NOT edit code directly here.**
- All changes must be made in the monorepo and will sync automatically.
If you opened this file inside the mirror, please submit your changes in the monorepo instead:
https://github.com/blackboxprogramming/BlackRoad-Operating-System/tree/main/services/core-api

0
docs/raw/.gitkeep Normal file
View File

0
docs/site/.gitkeep Normal file
View File

View File

@@ -0,0 +1,33 @@
services:
core-api:
monorepo_path: "services/core-api"
target_repo: "BlackRoad-OS/blackroad-os-core"
target_branch: "main"
force_push: true
public-api:
monorepo_path: "services/public-api"
target_repo: "BlackRoad-OS/blackroad-os-api"
target_branch: "main"
force_push: true
operator:
monorepo_path: "services/operator"
target_repo: "BlackRoad-OS/blackroad-os-operator"
target_branch: "main"
force_push: true
apps:
prism-console:
monorepo_path: "apps/prism-console"
target_repo: "BlackRoad-OS/blackroad-os-prism-console"
target_branch: "main"
force_push: true
web:
monorepo_path: "apps/web"
target_repo: "BlackRoad-OS/blackroad-os-web"
target_branch: "main"
force_push: true
docs:
site:
monorepo_path: "docs/site"
target_repo: "BlackRoad-OS/blackroad-os-docs"
target_branch: "main"
force_push: true

View File

@@ -0,0 +1,39 @@
# Railway Environment Guide
Railway deployments are driven from the monorepo. Each service declares its own variables here so workflows can validate and operators can provision them consistently.
## Core API (`services/core-api`)
- `CORE_API_DATABASE_URL`
- `CORE_API_SECRET_KEY`
- `CORE_API_ALLOWED_ORIGINS`
- `CORE_API_HEALTHCHECK_URL` (defaults to deployed `/health` endpoint)
## Public API (`services/public-api`)
- `PUBLIC_API_DATABASE_URL`
- `PUBLIC_API_SECRET_KEY`
- `PUBLIC_API_ALLOWED_ORIGINS`
- `PUBLIC_API_HEALTHCHECK_URL`
## Operator (`services/operator`)
- `OPERATOR_API_URL`
- `OPERATOR_SECRET_KEY`
- `OPERATOR_ALLOWED_ORIGINS`
- `OPERATOR_HEALTHCHECK_URL`
## Prism Console (`apps/prism-console`)
- `PRISM_API_URL`
- `PRISM_CONSOLE_PUBLIC_URL`
- `PRISM_CONSOLE_AUTH_TOKEN`
## Web (`apps/web`)
- `WEB_PUBLIC_URL`
- `WEB_API_URL`
- `WEB_BUILD_ENV`
## Docs (`docs/site`)
- `DOCS_PUBLIC_URL`
## Deployment Notes
- Secrets are injected via `${{ secrets.RAILWAY_TOKEN }}` in GitHub Actions; do not commit credentials.
- Healthchecks should respond on `/health` and `/version` for every deployed service.
- Update this guide when adding a new service so deployment workflows remain aligned.

View File

@@ -0,0 +1,7 @@
# Core API (monorepo-owned)
- **Canonical path:** `services/core-api`
- **Mirror:** `BlackRoad-OS/blackroad-os-core`
- **Branch:** `main`
This directory contains the core API service for BlackRoad OS. All changes must originate here and will be synced automatically to the mirror repository via `.github/workflows/sync-core-api.yml`.

View File

@@ -0,0 +1,7 @@
# Operator (monorepo-owned)
- **Canonical path:** `services/operator`
- **Mirror:** `BlackRoad-OS/blackroad-os-operator`
- **Branch:** `main`
This directory is the source of truth for operator automation. Edits sync to the `blackroad-os-operator` mirror repository.

View File

@@ -0,0 +1,7 @@
# Public API (monorepo-owned)
- **Canonical path:** `services/public-api`
- **Mirror:** `BlackRoad-OS/blackroad-os-api`
- **Branch:** `main`
The public-facing API surface for BlackRoad OS lives here. Make changes in this directory; the sync workflow will mirror them to `blackroad-os-api`.