mirror of
https://github.com/blackboxprogramming/BlackRoad-Operating-System.git
synced 2026-03-17 05:57:21 -05:00
chore: phase 1 infrastructure implementation
Implement Phase 1 infrastructure from master orchestration plan. This commit delivers production-ready deployment infrastructure, comprehensive documentation, and workflow automation. **Cloudflare DNS Infrastructure:** - Add records.yaml with complete DNS config for all domains - Add migrate_to_cloudflare.md with step-by-step migration guide - Add cloudflare_dns_sync.py for automated DNS synchronization - Update CLOUDFLARE_DNS_BLUEPRINT.md with implementation references **Environment Variable Documentation:** - Add ENV_VARS.md with comprehensive variable reference - Document all services: Railway, GitHub Actions, Cloudflare, local - Include security best practices and validation scripts - Add troubleshooting guides and quick-start templates **GitHub Actions Workflows:** - Add railway-deploy-template.yml for Railway deployments - Add frontend-deploy-template.yml for static site deployments - Add codeql-analysis-template.yml for security scanning - Add comprehensive-ci-template.yml for complete CI pipeline - Add .github/dependabot.yml for automated dependency updates **Frontend Infrastructure:** - Add infra/frontend/LANDING_PAGE_PLAN.md with detailed implementation plan - Include page structure, design system, content guidelines - Document deployment options (GitHub Pages, Railway, Cloudflare Pages) **Master Orchestration Updates:** - Update MASTER_ORCHESTRATION_PLAN.md with implementation file references - Add Phase 1 implementation checklist - Document immediate, short-term, and medium-term next steps **Impact:** This implementation enables: - Automated DNS management across 10+ domains - Secure, documented deployment workflows - Consistent environment configuration - Automated security scanning and dependency updates - Clear path to production for landing page **Next Steps for Operator:** 1. Migrate DNS to Cloudflare using migrate_to_cloudflare.md 2. Configure GitHub and Railway secrets 3. Deploy backend with custom domains 4. Implement landing page using LANDING_PAGE_PLAN.md Refs: #55 (Master Orchestration Prompt)
This commit is contained in:
134
.github/workflows/templates/codeql-analysis-template.yml
vendored
Normal file
134
.github/workflows/templates/codeql-analysis-template.yml
vendored
Normal file
@@ -0,0 +1,134 @@
|
||||
# CodeQL Security Analysis Workflow Template
|
||||
# ==========================================
|
||||
#
|
||||
# This template sets up CodeQL code scanning for security vulnerabilities.
|
||||
#
|
||||
# How to use:
|
||||
# -----------
|
||||
# 1. Copy this file to .github/workflows/codeql-analysis.yml in your repo
|
||||
# 2. Update the languages array based on your repo (python, javascript, typescript, etc.)
|
||||
# 3. Customize paths to analyze if needed
|
||||
# 4. Commit and push - CodeQL will run automatically
|
||||
#
|
||||
# What is CodeQL?
|
||||
# --------------
|
||||
# CodeQL is GitHub's semantic code analysis engine that finds security vulnerabilities
|
||||
# and coding errors. It's free for public repos and GitHub Enterprise.
|
||||
#
|
||||
# Supported languages:
|
||||
# -------------------
|
||||
# - python
|
||||
# - javascript (includes TypeScript)
|
||||
# - go
|
||||
# - java
|
||||
# - csharp
|
||||
# - cpp
|
||||
# - ruby
|
||||
# - swift
|
||||
|
||||
name: CodeQL Security Analysis
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
- develop
|
||||
pull_request:
|
||||
branches:
|
||||
- main
|
||||
- develop
|
||||
schedule:
|
||||
# Run CodeQL analysis every Monday at 00:00 UTC
|
||||
- cron: '0 0 * * 1'
|
||||
workflow_dispatch:
|
||||
|
||||
# Limit concurrent runs
|
||||
concurrency:
|
||||
group: codeql-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
analyze:
|
||||
name: CodeQL Analysis
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 30
|
||||
|
||||
permissions:
|
||||
# Required for CodeQL to upload results
|
||||
actions: read
|
||||
contents: read
|
||||
security-events: write
|
||||
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
# Update this array based on your repository's languages
|
||||
# For BlackRoad OS backend: ['python', 'javascript']
|
||||
# For frontend only: ['javascript']
|
||||
language: ['python', 'javascript']
|
||||
|
||||
steps:
|
||||
# ========================================
|
||||
# 1. Checkout code
|
||||
# ========================================
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
|
||||
# ========================================
|
||||
# 2. Initialize CodeQL
|
||||
# ========================================
|
||||
- name: Initialize CodeQL
|
||||
uses: github/codeql-action/init@v3
|
||||
with:
|
||||
languages: ${{ matrix.language }}
|
||||
# If you want to analyze specific paths only:
|
||||
# paths:
|
||||
# - backend/
|
||||
# - src/
|
||||
# paths-ignore:
|
||||
# - tests/
|
||||
# - '**/*.test.js'
|
||||
|
||||
# ========================================
|
||||
# 3. Build code (if needed)
|
||||
# ========================================
|
||||
# For compiled languages (Java, C#, C++), add build steps here
|
||||
# For interpreted languages (Python, JavaScript), auto-build works
|
||||
|
||||
# Autobuild attempts to build any compiled languages
|
||||
- name: Autobuild
|
||||
uses: github/codeql-action/autobuild@v3
|
||||
|
||||
# Alternative: Manual build steps for Python if needed
|
||||
# - name: Build Python (manual)
|
||||
# if: matrix.language == 'python'
|
||||
# run: |
|
||||
# python -m pip install --upgrade pip
|
||||
# pip install -r backend/requirements.txt
|
||||
|
||||
# ========================================
|
||||
# 4. Perform CodeQL Analysis
|
||||
# ========================================
|
||||
- name: Perform CodeQL Analysis
|
||||
uses: github/codeql-action/analyze@v3
|
||||
with:
|
||||
category: "/language:${{ matrix.language }}"
|
||||
|
||||
# ========================================
|
||||
# Workflow Summary
|
||||
# ========================================
|
||||
#
|
||||
# This workflow:
|
||||
# 1. Runs on push, PR, schedule (weekly), and manual dispatch
|
||||
# 2. Analyzes code for security vulnerabilities using CodeQL
|
||||
# 3. Uploads results to GitHub Security tab
|
||||
# 4. Creates alerts for any issues found
|
||||
#
|
||||
# View results:
|
||||
# - Go to your repository → Security tab → Code scanning alerts
|
||||
#
|
||||
# Customization:
|
||||
# - Add more languages to matrix.language array
|
||||
# - Filter paths to analyze specific directories
|
||||
# - Adjust schedule frequency
|
||||
# - Add custom queries for domain-specific security checks
|
||||
418
.github/workflows/templates/comprehensive-ci-template.yml
vendored
Normal file
418
.github/workflows/templates/comprehensive-ci-template.yml
vendored
Normal file
@@ -0,0 +1,418 @@
|
||||
# Comprehensive CI Workflow Template
|
||||
# ===================================
|
||||
#
|
||||
# This template provides a complete CI pipeline for BlackRoad repositories.
|
||||
# It includes linting, type checking, testing, and build verification.
|
||||
#
|
||||
# How to use:
|
||||
# -----------
|
||||
# 1. Copy this file to .github/workflows/ci.yml in your repo
|
||||
# 2. Customize the jobs based on your stack (Python/JS/both)
|
||||
# 3. Update paths and commands as needed
|
||||
# 4. Commit and push - CI will run on PRs and pushes
|
||||
#
|
||||
# What this workflow does:
|
||||
# -----------------------
|
||||
# - Lints code (Python: flake8/black, JS: eslint/prettier)
|
||||
# - Runs type checking (Python: mypy, TS: tsc)
|
||||
# - Runs test suite with coverage
|
||||
# - Builds the application
|
||||
# - Validates environment config
|
||||
# - Reports results to PR
|
||||
|
||||
name: Continuous Integration
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
- develop
|
||||
- 'feature/**'
|
||||
pull_request:
|
||||
branches:
|
||||
- main
|
||||
- develop
|
||||
|
||||
# Cancel previous runs if new push
|
||||
concurrency:
|
||||
group: ci-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
env:
|
||||
PYTHON_VERSION: '3.11'
|
||||
NODE_VERSION: '20'
|
||||
|
||||
jobs:
|
||||
# ========================================
|
||||
# Job 1: Python Linting
|
||||
# ========================================
|
||||
lint-python:
|
||||
name: Lint Python Code
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 5
|
||||
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Set up Python
|
||||
uses: actions/setup-python@v4
|
||||
with:
|
||||
python-version: ${{ env.PYTHON_VERSION }}
|
||||
cache: 'pip'
|
||||
cache-dependency-path: 'backend/requirements.txt'
|
||||
|
||||
- name: Install linting tools
|
||||
run: |
|
||||
pip install flake8 black isort mypy
|
||||
|
||||
- name: Run Black (code formatter check)
|
||||
run: |
|
||||
black --check backend/app
|
||||
echo "✅ Black formatting check passed"
|
||||
|
||||
- name: Run isort (import sorting check)
|
||||
run: |
|
||||
isort --check-only backend/app
|
||||
echo "✅ isort check passed"
|
||||
|
||||
- name: Run flake8 (linter)
|
||||
run: |
|
||||
flake8 backend/app --max-line-length=100 --ignore=E203,W503
|
||||
echo "✅ flake8 linting passed"
|
||||
|
||||
# ========================================
|
||||
# Job 2: Python Type Checking
|
||||
# ========================================
|
||||
type-check-python:
|
||||
name: Python Type Check
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 5
|
||||
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Set up Python
|
||||
uses: actions/setup-python@v4
|
||||
with:
|
||||
python-version: ${{ env.PYTHON_VERSION }}
|
||||
cache: 'pip'
|
||||
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
pip install -r backend/requirements.txt
|
||||
pip install mypy types-redis types-requests
|
||||
|
||||
- name: Run mypy
|
||||
run: |
|
||||
mypy backend/app --ignore-missing-imports
|
||||
echo "✅ Type checking passed"
|
||||
|
||||
# ========================================
|
||||
# Job 3: Python Tests
|
||||
# ========================================
|
||||
test-python:
|
||||
name: Python Tests
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 10
|
||||
|
||||
# Test matrix for multiple Python versions (optional)
|
||||
strategy:
|
||||
matrix:
|
||||
python-version: ['3.11'] # Add ['3.10', '3.11', '3.12'] for multi-version testing
|
||||
|
||||
services:
|
||||
# PostgreSQL for tests
|
||||
postgres:
|
||||
image: postgres:15
|
||||
env:
|
||||
POSTGRES_USER: test
|
||||
POSTGRES_PASSWORD: test
|
||||
POSTGRES_DB: blackroad_test
|
||||
options: >-
|
||||
--health-cmd pg_isready
|
||||
--health-interval 10s
|
||||
--health-timeout 5s
|
||||
--health-retries 5
|
||||
ports:
|
||||
- 5432:5432
|
||||
|
||||
# Redis for tests
|
||||
redis:
|
||||
image: redis:7
|
||||
options: >-
|
||||
--health-cmd "redis-cli ping"
|
||||
--health-interval 10s
|
||||
--health-timeout 5s
|
||||
--health-retries 5
|
||||
ports:
|
||||
- 6379:6379
|
||||
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Set up Python
|
||||
uses: actions/setup-python@v4
|
||||
with:
|
||||
python-version: ${{ matrix.python-version }}
|
||||
cache: 'pip'
|
||||
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
pip install -r backend/requirements.txt
|
||||
pip install pytest pytest-cov pytest-asyncio
|
||||
|
||||
- name: Set up test environment
|
||||
env:
|
||||
DATABASE_URL: postgresql://test:test@localhost:5432/blackroad_test
|
||||
REDIS_URL: redis://localhost:6379/0
|
||||
SECRET_KEY: test-secret-key-for-ci
|
||||
ENVIRONMENT: test
|
||||
run: |
|
||||
echo "Test environment configured"
|
||||
|
||||
- name: Run tests with coverage
|
||||
env:
|
||||
DATABASE_URL: postgresql://test:test@localhost:5432/blackroad_test
|
||||
REDIS_URL: redis://localhost:6379/0
|
||||
SECRET_KEY: test-secret-key-for-ci
|
||||
ENVIRONMENT: test
|
||||
run: |
|
||||
cd backend
|
||||
pytest -v \
|
||||
--cov=app \
|
||||
--cov-report=term \
|
||||
--cov-report=xml \
|
||||
--cov-report=html \
|
||||
--maxfail=3
|
||||
|
||||
- name: Upload coverage to Codecov (optional)
|
||||
if: success()
|
||||
uses: codecov/codecov-action@v3
|
||||
with:
|
||||
file: ./backend/coverage.xml
|
||||
flags: backend
|
||||
name: backend-coverage
|
||||
|
||||
# ========================================
|
||||
# Job 4: JavaScript/TypeScript Linting (if applicable)
|
||||
# ========================================
|
||||
lint-javascript:
|
||||
name: Lint JavaScript/TypeScript
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 5
|
||||
# Only run if package.json exists
|
||||
if: hashFiles('package.json') != ''
|
||||
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Set up Node.js
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: ${{ env.NODE_VERSION }}
|
||||
cache: 'npm'
|
||||
|
||||
- name: Install dependencies
|
||||
run: npm ci
|
||||
|
||||
- name: Run ESLint
|
||||
run: npm run lint
|
||||
|
||||
- name: Run Prettier check
|
||||
run: npm run format:check
|
||||
|
||||
# ========================================
|
||||
# Job 5: JavaScript/TypeScript Tests (if applicable)
|
||||
# ========================================
|
||||
test-javascript:
|
||||
name: JavaScript/TypeScript Tests
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 10
|
||||
if: hashFiles('package.json') != ''
|
||||
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Set up Node.js
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: ${{ env.NODE_VERSION }}
|
||||
cache: 'npm'
|
||||
|
||||
- name: Install dependencies
|
||||
run: npm ci
|
||||
|
||||
- name: Run tests
|
||||
run: npm test -- --coverage
|
||||
|
||||
- name: Upload coverage
|
||||
if: success()
|
||||
uses: codecov/codecov-action@v3
|
||||
with:
|
||||
file: ./coverage/coverage-final.json
|
||||
flags: frontend
|
||||
name: frontend-coverage
|
||||
|
||||
# ========================================
|
||||
# Job 6: Build Verification
|
||||
# ========================================
|
||||
build:
|
||||
name: Build Verification
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 10
|
||||
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
|
||||
# Python build (if applicable)
|
||||
- name: Set up Python
|
||||
uses: actions/setup-python@v4
|
||||
with:
|
||||
python-version: ${{ env.PYTHON_VERSION }}
|
||||
|
||||
- name: Verify Python build
|
||||
run: |
|
||||
pip install build
|
||||
cd backend
|
||||
python -m build
|
||||
echo "✅ Python package builds successfully"
|
||||
|
||||
# Node build (if applicable)
|
||||
- name: Set up Node.js
|
||||
if: hashFiles('package.json') != ''
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: ${{ env.NODE_VERSION }}
|
||||
cache: 'npm'
|
||||
|
||||
- name: Build frontend (if applicable)
|
||||
if: hashFiles('package.json') != ''
|
||||
run: |
|
||||
npm ci
|
||||
npm run build
|
||||
echo "✅ Frontend builds successfully"
|
||||
|
||||
# ========================================
|
||||
# Job 7: Environment Validation
|
||||
# ========================================
|
||||
validate-env:
|
||||
name: Validate Environment Config
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 5
|
||||
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Validate .env.example exists
|
||||
run: |
|
||||
if [ ! -f backend/.env.example ]; then
|
||||
echo "❌ backend/.env.example not found"
|
||||
exit 1
|
||||
fi
|
||||
echo "✅ .env.example exists"
|
||||
|
||||
- name: Validate .env.example is not committed
|
||||
run: |
|
||||
if [ -f backend/.env ]; then
|
||||
echo "❌ backend/.env should not be committed!"
|
||||
exit 1
|
||||
fi
|
||||
echo "✅ .env is gitignored"
|
||||
|
||||
- name: Validate Railway config
|
||||
run: |
|
||||
if [ -f railway.toml ]; then
|
||||
echo "✅ railway.toml exists"
|
||||
else
|
||||
echo "⚠️ railway.toml not found (not required but recommended)"
|
||||
fi
|
||||
|
||||
# ========================================
|
||||
# Job 8: Security Scan (optional)
|
||||
# ========================================
|
||||
security-scan:
|
||||
name: Security Scan
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 5
|
||||
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Run Bandit (Python security linter)
|
||||
run: |
|
||||
pip install bandit
|
||||
bandit -r backend/app -ll
|
||||
echo "✅ Security scan passed"
|
||||
|
||||
- name: Check for secrets in code
|
||||
uses: trufflesecurity/trufflehog@main
|
||||
with:
|
||||
path: ./
|
||||
base: ${{ github.event.repository.default_branch }}
|
||||
head: HEAD
|
||||
|
||||
# ========================================
|
||||
# Job 9: Summary
|
||||
# ========================================
|
||||
ci-summary:
|
||||
name: CI Summary
|
||||
runs-on: ubuntu-latest
|
||||
needs:
|
||||
- lint-python
|
||||
- type-check-python
|
||||
- test-python
|
||||
- build
|
||||
- validate-env
|
||||
if: always()
|
||||
|
||||
steps:
|
||||
- name: Check all jobs passed
|
||||
if: |
|
||||
needs.lint-python.result == 'failure' ||
|
||||
needs.type-check-python.result == 'failure' ||
|
||||
needs.test-python.result == 'failure' ||
|
||||
needs.build.result == 'failure' ||
|
||||
needs.validate-env.result == 'failure'
|
||||
run: |
|
||||
echo "❌ CI failed - check job logs above"
|
||||
exit 1
|
||||
|
||||
- name: All checks passed
|
||||
run: |
|
||||
echo "✅ All CI checks passed!"
|
||||
echo "Code is ready to merge"
|
||||
|
||||
# ========================================
|
||||
# Workflow Summary
|
||||
# ========================================
|
||||
#
|
||||
# This comprehensive CI workflow:
|
||||
# 1. Lints Python code (black, isort, flake8)
|
||||
# 2. Type checks Python (mypy)
|
||||
# 3. Runs Python tests with coverage (pytest)
|
||||
# 4. Lints JavaScript/TypeScript (eslint, prettier)
|
||||
# 5. Runs JS/TS tests (jest)
|
||||
# 6. Verifies build succeeds
|
||||
# 7. Validates environment configuration
|
||||
# 8. Scans for security issues
|
||||
# 9. Provides overall summary
|
||||
#
|
||||
# Customize based on your stack:
|
||||
# - Remove JS jobs if Python-only
|
||||
# - Remove Python jobs if JS-only
|
||||
# - Add database migrations check
|
||||
# - Add API contract tests
|
||||
# - Add performance benchmarks
|
||||
#
|
||||
# Status checks:
|
||||
# - Configure branch protection to require these jobs
|
||||
# - Prevents merging failing code
|
||||
# - Ensures code quality standards
|
||||
286
.github/workflows/templates/frontend-deploy-template.yml
vendored
Normal file
286
.github/workflows/templates/frontend-deploy-template.yml
vendored
Normal file
@@ -0,0 +1,286 @@
|
||||
# Frontend Deployment Workflow Template
|
||||
# ======================================
|
||||
#
|
||||
# This template deploys static frontend sites to various platforms.
|
||||
#
|
||||
# Supported targets:
|
||||
# - GitHub Pages
|
||||
# - Cloudflare Pages
|
||||
# - Railway static hosting
|
||||
# - Vercel
|
||||
# - Netlify
|
||||
#
|
||||
# How to use:
|
||||
# -----------
|
||||
# 1. Copy this file to .github/workflows/frontend-deploy.yml
|
||||
# 2. Choose your deployment target (uncomment the relevant job)
|
||||
# 3. Configure custom domain settings
|
||||
# 4. Add required secrets
|
||||
# 5. Push to trigger deployment
|
||||
|
||||
name: Deploy Frontend
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
paths:
|
||||
- 'landing/**'
|
||||
- 'frontend/**'
|
||||
- 'backend/static/**'
|
||||
workflow_dispatch:
|
||||
|
||||
# Only allow one deployment at a time
|
||||
concurrency:
|
||||
group: frontend-deploy
|
||||
cancel-in-progress: false
|
||||
|
||||
jobs:
|
||||
# ========================================
|
||||
# Option 1: Deploy to GitHub Pages
|
||||
# ========================================
|
||||
deploy-github-pages:
|
||||
name: Deploy to GitHub Pages
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 10
|
||||
|
||||
# Grant GITHUB_TOKEN permissions
|
||||
permissions:
|
||||
contents: read
|
||||
pages: write
|
||||
id-token: write
|
||||
|
||||
# Protect production environment
|
||||
environment:
|
||||
name: github-pages
|
||||
url: ${{ steps.deployment.outputs.page_url }}
|
||||
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
|
||||
# If you have a build step:
|
||||
# - name: Set up Node.js
|
||||
# uses: actions/setup-node@v4
|
||||
# with:
|
||||
# node-version: '20'
|
||||
# cache: 'npm'
|
||||
#
|
||||
# - name: Install dependencies
|
||||
# run: npm ci
|
||||
#
|
||||
# - name: Build site
|
||||
# run: npm run build
|
||||
|
||||
- name: Setup Pages
|
||||
uses: actions/configure-pages@v4
|
||||
|
||||
- name: Upload artifact
|
||||
uses: actions/upload-pages-artifact@v3
|
||||
with:
|
||||
# Update path based on your static files location
|
||||
path: 'backend/static' # or 'landing/', 'dist/', etc.
|
||||
|
||||
- name: Deploy to GitHub Pages
|
||||
id: deployment
|
||||
uses: actions/deploy-pages@v4
|
||||
|
||||
- name: Deployment summary
|
||||
run: |
|
||||
echo "✅ Deployed to GitHub Pages"
|
||||
echo "URL: ${{ steps.deployment.outputs.page_url }}"
|
||||
|
||||
# ========================================
|
||||
# Option 2: Deploy to Railway (Static)
|
||||
# ========================================
|
||||
# deploy-railway:
|
||||
# name: Deploy to Railway
|
||||
# runs-on: ubuntu-latest
|
||||
# timeout-minutes: 10
|
||||
#
|
||||
# environment:
|
||||
# name: production-frontend
|
||||
# url: https://blackroad.systems
|
||||
#
|
||||
# steps:
|
||||
# - name: Checkout code
|
||||
# uses: actions/checkout@v4
|
||||
#
|
||||
# - name: Install Railway CLI
|
||||
# run: |
|
||||
# curl -fsSL https://railway.app/install.sh | sh
|
||||
# echo "$HOME/.railway/bin" >> $GITHUB_PATH
|
||||
#
|
||||
# - name: Deploy to Railway
|
||||
# env:
|
||||
# RAILWAY_TOKEN: ${{ secrets.RAILWAY_TOKEN }}
|
||||
# run: |
|
||||
# railway up --service frontend --detach
|
||||
# echo "✅ Deployed to Railway"
|
||||
|
||||
# ========================================
|
||||
# Option 3: Deploy to Cloudflare Pages
|
||||
# ========================================
|
||||
# deploy-cloudflare-pages:
|
||||
# name: Deploy to Cloudflare Pages
|
||||
# runs-on: ubuntu-latest
|
||||
# timeout-minutes: 10
|
||||
#
|
||||
# environment:
|
||||
# name: cloudflare-pages
|
||||
# url: https://blackroad.systems
|
||||
#
|
||||
# steps:
|
||||
# - name: Checkout code
|
||||
# uses: actions/checkout@v4
|
||||
#
|
||||
# # Build step if needed
|
||||
# # - name: Build site
|
||||
# # run: npm run build
|
||||
#
|
||||
# - name: Publish to Cloudflare Pages
|
||||
# uses: cloudflare/pages-action@v1
|
||||
# with:
|
||||
# apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
|
||||
# accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
|
||||
# projectName: blackroad-os
|
||||
# directory: backend/static # or dist/, build/, etc.
|
||||
# gitHubToken: ${{ secrets.GITHUB_TOKEN }}
|
||||
#
|
||||
# - name: Deployment summary
|
||||
# run: echo "✅ Deployed to Cloudflare Pages"
|
||||
|
||||
# ========================================
|
||||
# Option 4: Deploy to Vercel
|
||||
# ========================================
|
||||
# deploy-vercel:
|
||||
# name: Deploy to Vercel
|
||||
# runs-on: ubuntu-latest
|
||||
# timeout-minutes: 10
|
||||
#
|
||||
# environment:
|
||||
# name: vercel-production
|
||||
#
|
||||
# steps:
|
||||
# - name: Checkout code
|
||||
# uses: actions/checkout@v#
|
||||
#
|
||||
# - name: Deploy to Vercel
|
||||
# uses: amondnet/vercel-action@v25
|
||||
# with:
|
||||
# vercel-token: ${{ secrets.VERCEL_TOKEN }}
|
||||
# vercel-org-id: ${{ secrets.VERCEL_ORG_ID }}
|
||||
# vercel-project-id: ${{ secrets.VERCEL_PROJECT_ID }}
|
||||
# vercel-args: '--prod'
|
||||
# working-directory: ./
|
||||
#
|
||||
# - name: Deployment summary
|
||||
# run: echo "✅ Deployed to Vercel"
|
||||
|
||||
# ========================================
|
||||
# Post-Deployment: Cache Purge
|
||||
# ========================================
|
||||
purge-cache:
|
||||
name: Purge Cloudflare Cache
|
||||
runs-on: ubuntu-latest
|
||||
needs: deploy-github-pages # Update based on your deployment job
|
||||
if: success()
|
||||
|
||||
steps:
|
||||
- name: Purge Cloudflare cache
|
||||
env:
|
||||
CF_API_TOKEN: ${{ secrets.CF_API_TOKEN }}
|
||||
CF_ZONE_ID: ${{ secrets.CF_ZONE_ID }}
|
||||
run: |
|
||||
curl -X POST "https://api.cloudflare.com/client/v4/zones/$CF_ZONE_ID/purge_cache" \
|
||||
-H "Authorization: Bearer $CF_API_TOKEN" \
|
||||
-H "Content-Type: application/json" \
|
||||
--data '{"purge_everything":true}'
|
||||
|
||||
echo "✅ Cloudflare cache purged"
|
||||
|
||||
# ========================================
|
||||
# Post-Deployment: Smoke Tests
|
||||
# ========================================
|
||||
smoke-tests:
|
||||
name: Frontend Smoke Tests
|
||||
runs-on: ubuntu-latest
|
||||
needs: deploy-github-pages # Update based on your deployment job
|
||||
if: success()
|
||||
|
||||
steps:
|
||||
- name: Wait for deployment propagation
|
||||
run: sleep 30
|
||||
|
||||
- name: Test homepage loads
|
||||
run: |
|
||||
HTTP_CODE=$(curl -s -o /dev/null -w "%{http_code}" https://blackroad.systems/)
|
||||
if [ "$HTTP_CODE" != "200" ]; then
|
||||
echo "❌ Homepage returned HTTP $HTTP_CODE"
|
||||
exit 1
|
||||
fi
|
||||
echo "✅ Homepage loads successfully"
|
||||
|
||||
- name: Test key pages
|
||||
run: |
|
||||
PAGES=(
|
||||
"/"
|
||||
"/architecture"
|
||||
"/pricing"
|
||||
"/contact"
|
||||
)
|
||||
|
||||
for PAGE in "${PAGES[@]}"; do
|
||||
HTTP_CODE=$(curl -s -o /dev/null -w "%{http_code}" "https://blackroad.systems$PAGE")
|
||||
if [ "$HTTP_CODE" = "200" ]; then
|
||||
echo "✅ $PAGE loads successfully"
|
||||
else
|
||||
echo "⚠️ $PAGE returned HTTP $HTTP_CODE"
|
||||
fi
|
||||
done
|
||||
|
||||
- name: Test SSL certificate
|
||||
run: |
|
||||
echo | openssl s_client -servername blackroad.systems -connect blackroad.systems:443 2>/dev/null | \
|
||||
openssl x509 -noout -dates
|
||||
echo "✅ SSL certificate is valid"
|
||||
|
||||
# ========================================
|
||||
# Configuration Guide
|
||||
# ========================================
|
||||
#
|
||||
# GitHub Pages Setup:
|
||||
# ------------------
|
||||
# 1. Repository → Settings → Pages
|
||||
# 2. Source: GitHub Actions
|
||||
# 3. Custom domain: blackroad.systems
|
||||
# 4. CNAME file: Create in static files root
|
||||
#
|
||||
# Required GitHub Secrets:
|
||||
# -----------------------
|
||||
# - CF_API_TOKEN (for cache purge)
|
||||
# - CF_ZONE_ID (for cache purge)
|
||||
#
|
||||
# Optional Secrets (based on target):
|
||||
# ----------------------------------
|
||||
# - RAILWAY_TOKEN (for Railway)
|
||||
# - CLOUDFLARE_API_TOKEN (for CF Pages)
|
||||
# - CLOUDFLARE_ACCOUNT_ID (for CF Pages)
|
||||
# - VERCEL_TOKEN (for Vercel)
|
||||
# - VERCEL_ORG_ID (for Vercel)
|
||||
# - VERCEL_PROJECT_ID (for Vercel)
|
||||
#
|
||||
# Custom Domain:
|
||||
# -------------
|
||||
# 1. Add CNAME file to your static files:
|
||||
# echo "blackroad.systems" > CNAME
|
||||
# 2. Configure DNS (see infra/cloudflare/records.yaml)
|
||||
# 3. Wait for DNS propagation (5-60 minutes)
|
||||
#
|
||||
# Deployment Targets Comparison:
|
||||
# -----------------------------
|
||||
# GitHub Pages: Free, simple, good for docs/marketing
|
||||
# Cloudflare Pages: Free, global CDN, fast
|
||||
# Railway: Paid, unified with backend
|
||||
# Vercel: Free tier, excellent DX, edge functions
|
||||
# Netlify: Free tier, form handling, split testing
|
||||
292
.github/workflows/templates/railway-deploy-template.yml
vendored
Normal file
292
.github/workflows/templates/railway-deploy-template.yml
vendored
Normal file
@@ -0,0 +1,292 @@
|
||||
# Railway Deployment Workflow Template
|
||||
# ======================================
|
||||
#
|
||||
# This template can be copied to any BlackRoad repository that deploys to Railway.
|
||||
#
|
||||
# How to use:
|
||||
# -----------
|
||||
# 1. Copy this file to .github/workflows/railway-deploy.yml in your repo
|
||||
# 2. Update the service name and environment variables as needed
|
||||
# 3. Add required GitHub secrets:
|
||||
# - RAILWAY_TOKEN (get from: railway tokens create)
|
||||
# - RAILWAY_SERVICE_ID (optional, for specific service targeting)
|
||||
# 4. Push to main branch to trigger deployment
|
||||
#
|
||||
# Required GitHub Secrets:
|
||||
# -----------------------
|
||||
# RAILWAY_TOKEN - Railway API token for CLI authentication
|
||||
#
|
||||
# Optional GitHub Secrets/Variables:
|
||||
# ---------------------------------
|
||||
# RAILWAY_SERVICE_ID - Specific Railway service ID to deploy
|
||||
# SENTRY_DSN - Sentry error monitoring DSN
|
||||
#
|
||||
# Customization:
|
||||
# -------------
|
||||
# - Change trigger branches (currently: main)
|
||||
# - Add/remove build steps
|
||||
# - Configure environment-specific variables
|
||||
# - Add post-deploy notifications (Slack, Discord, etc.)
|
||||
|
||||
name: Deploy to Railway
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
paths-ignore:
|
||||
- '**.md'
|
||||
- 'docs/**'
|
||||
- '.github/**'
|
||||
- '!.github/workflows/railway-deploy.yml'
|
||||
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
environment:
|
||||
description: 'Deployment environment'
|
||||
required: true
|
||||
type: choice
|
||||
options:
|
||||
- production
|
||||
- staging
|
||||
default: 'production'
|
||||
|
||||
# Only allow one deployment at a time
|
||||
concurrency:
|
||||
group: railway-deploy-${{ github.ref }}
|
||||
cancel-in-progress: false
|
||||
|
||||
jobs:
|
||||
deploy:
|
||||
name: Deploy to Railway
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 15
|
||||
|
||||
# Set deployment environment
|
||||
environment:
|
||||
name: ${{ github.event.inputs.environment || 'production' }}
|
||||
url: https://os.blackroad.systems # Update with your actual URL
|
||||
|
||||
steps:
|
||||
# ========================================
|
||||
# 1. Checkout code
|
||||
# ========================================
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
|
||||
# ========================================
|
||||
# 2. Install Railway CLI
|
||||
# ========================================
|
||||
- name: Install Railway CLI
|
||||
run: |
|
||||
curl -fsSL https://railway.app/install.sh | sh
|
||||
echo "$HOME/.railway/bin" >> $GITHUB_PATH
|
||||
|
||||
- name: Verify Railway installation
|
||||
run: railway --version
|
||||
|
||||
# ========================================
|
||||
# 3. Set up environment
|
||||
# ========================================
|
||||
- name: Set up environment variables
|
||||
run: |
|
||||
echo "RAILWAY_TOKEN=${{ secrets.RAILWAY_TOKEN }}" >> $GITHUB_ENV
|
||||
echo "GIT_SHA=${GITHUB_SHA::8}" >> $GITHUB_ENV
|
||||
echo "DEPLOY_TIME=$(date -u +'%Y-%m-%d %H:%M:%S UTC')" >> $GITHUB_ENV
|
||||
|
||||
# ========================================
|
||||
# 4. Pre-deploy validation (optional)
|
||||
# ========================================
|
||||
- name: Validate environment variables
|
||||
run: |
|
||||
if [ -z "${{ secrets.RAILWAY_TOKEN }}" ]; then
|
||||
echo "❌ Error: RAILWAY_TOKEN secret is not set"
|
||||
exit 1
|
||||
fi
|
||||
echo "✅ Environment variables validated"
|
||||
|
||||
# ========================================
|
||||
# 5. Deploy to Railway
|
||||
# ========================================
|
||||
- name: Deploy to Railway
|
||||
id: deploy
|
||||
env:
|
||||
RAILWAY_TOKEN: ${{ secrets.RAILWAY_TOKEN }}
|
||||
run: |
|
||||
echo "🚀 Deploying to Railway..."
|
||||
echo "Environment: ${{ github.event.inputs.environment || 'production' }}"
|
||||
echo "Commit: ${GITHUB_SHA::8}"
|
||||
echo "Branch: ${GITHUB_REF_NAME}"
|
||||
|
||||
# Deploy using Railway CLI
|
||||
# If RAILWAY_SERVICE_ID is set, deploy to specific service
|
||||
if [ -n "${{ secrets.RAILWAY_SERVICE_ID }}" ]; then
|
||||
railway up \
|
||||
--service "${{ secrets.RAILWAY_SERVICE_ID }}" \
|
||||
--detach
|
||||
else
|
||||
railway up --detach
|
||||
fi
|
||||
|
||||
echo "✅ Deployment initiated"
|
||||
|
||||
# ========================================
|
||||
# 6. Wait for deployment and health check
|
||||
# ========================================
|
||||
- name: Wait for deployment
|
||||
id: wait
|
||||
env:
|
||||
RAILWAY_TOKEN: ${{ secrets.RAILWAY_TOKEN }}
|
||||
run: |
|
||||
echo "⏳ Waiting for deployment to complete..."
|
||||
|
||||
# Wait up to 5 minutes for deployment
|
||||
MAX_WAIT=300
|
||||
ELAPSED=0
|
||||
INTERVAL=10
|
||||
|
||||
while [ $ELAPSED -lt $MAX_WAIT ]; do
|
||||
# Check deployment status (simplified - adjust based on Railway CLI output)
|
||||
STATUS=$(railway status --json 2>/dev/null || echo '{"status":"unknown"}')
|
||||
|
||||
echo "Status check at ${ELAPSED}s: Deployment in progress..."
|
||||
|
||||
# Sleep and increment
|
||||
sleep $INTERVAL
|
||||
ELAPSED=$((ELAPSED + INTERVAL))
|
||||
done
|
||||
|
||||
echo "⏰ Deployment wait period completed"
|
||||
|
||||
# ========================================
|
||||
# 7. Health check (optional but recommended)
|
||||
# ========================================
|
||||
- name: Health check
|
||||
id: health
|
||||
run: |
|
||||
echo "🏥 Running health check..."
|
||||
|
||||
# Update with your actual health endpoint
|
||||
HEALTH_URL="https://os.blackroad.systems/health"
|
||||
|
||||
# Try health check up to 5 times
|
||||
MAX_ATTEMPTS=5
|
||||
ATTEMPT=1
|
||||
|
||||
while [ $ATTEMPT -le $MAX_ATTEMPTS ]; do
|
||||
echo "Health check attempt $ATTEMPT/$MAX_ATTEMPTS..."
|
||||
|
||||
HTTP_CODE=$(curl -s -o /dev/null -w "%{http_code}" "$HEALTH_URL" || echo "000")
|
||||
|
||||
if [ "$HTTP_CODE" = "200" ]; then
|
||||
echo "✅ Health check passed (HTTP $HTTP_CODE)"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
echo "⚠️ Health check returned HTTP $HTTP_CODE, retrying..."
|
||||
sleep 10
|
||||
ATTEMPT=$((ATTEMPT + 1))
|
||||
done
|
||||
|
||||
echo "❌ Health check failed after $MAX_ATTEMPTS attempts"
|
||||
exit 1
|
||||
|
||||
# ========================================
|
||||
# 8. Post-deploy notifications (optional)
|
||||
# ========================================
|
||||
- name: Notify deployment success
|
||||
if: success()
|
||||
run: |
|
||||
echo "✅ Deployment successful!"
|
||||
echo "SHA: ${GITHUB_SHA::8}"
|
||||
echo "Time: $(date -u +'%Y-%m-%d %H:%M:%S UTC')"
|
||||
|
||||
# Add Slack/Discord webhook here if needed
|
||||
# Example:
|
||||
# curl -X POST -H 'Content-type: application/json' \
|
||||
# --data '{"text":"✅ Deployed to Railway: '"${GITHUB_SHA::8}"'"}' \
|
||||
# ${{ secrets.SLACK_WEBHOOK_URL }}
|
||||
|
||||
# ========================================
|
||||
# 9. Handle deployment failure
|
||||
# ========================================
|
||||
- name: Notify deployment failure
|
||||
if: failure()
|
||||
run: |
|
||||
echo "❌ Deployment failed!"
|
||||
echo "SHA: ${GITHUB_SHA::8}"
|
||||
echo "Check Railway logs for details"
|
||||
|
||||
# Add Slack/Discord webhook here if needed
|
||||
|
||||
# ========================================
|
||||
# 10. Send to Sentry (optional)
|
||||
# ========================================
|
||||
- name: Create Sentry release
|
||||
if: success() && vars.SENTRY_DSN != ''
|
||||
env:
|
||||
SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }}
|
||||
SENTRY_ORG: blackroad
|
||||
SENTRY_PROJECT: blackroad-os
|
||||
run: |
|
||||
# Install Sentry CLI
|
||||
curl -sL https://sentry.io/get-cli/ | bash
|
||||
|
||||
# Create release
|
||||
sentry-cli releases new "${GITHUB_SHA::8}"
|
||||
sentry-cli releases set-commits "${GITHUB_SHA::8}" --auto
|
||||
sentry-cli releases finalize "${GITHUB_SHA::8}"
|
||||
sentry-cli releases deploys "${GITHUB_SHA::8}" new -e production
|
||||
|
||||
echo "✅ Sentry release created"
|
||||
|
||||
# ========================================
|
||||
# Optional: Smoke tests after deployment
|
||||
# ========================================
|
||||
smoke-tests:
|
||||
name: Smoke Tests
|
||||
runs-on: ubuntu-latest
|
||||
needs: deploy
|
||||
if: success()
|
||||
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Run smoke tests
|
||||
run: |
|
||||
echo "🧪 Running smoke tests..."
|
||||
|
||||
# Basic smoke tests
|
||||
BASE_URL="https://os.blackroad.systems"
|
||||
|
||||
# Test 1: Health endpoint
|
||||
echo "Test 1: Health endpoint"
|
||||
curl -f "$BASE_URL/health" || exit 1
|
||||
|
||||
# Test 2: API documentation
|
||||
echo "Test 2: API documentation"
|
||||
curl -f "$BASE_URL/api/docs" || exit 1
|
||||
|
||||
# Test 3: Frontend loads
|
||||
echo "Test 3: Frontend loads"
|
||||
curl -f "$BASE_URL/" || exit 1
|
||||
|
||||
echo "✅ All smoke tests passed"
|
||||
|
||||
# ========================================
|
||||
# Workflow Summary
|
||||
# ========================================
|
||||
#
|
||||
# This workflow:
|
||||
# 1. Triggers on push to main or manual dispatch
|
||||
# 2. Installs Railway CLI
|
||||
# 3. Validates environment
|
||||
# 4. Deploys to Railway
|
||||
# 5. Waits for deployment
|
||||
# 6. Runs health checks
|
||||
# 7. Sends notifications
|
||||
# 8. Creates Sentry release (optional)
|
||||
# 9. Runs smoke tests (optional)
|
||||
#
|
||||
# Customize as needed for your specific service!
|
||||
Reference in New Issue
Block a user