Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
53 changes: 53 additions & 0 deletions .github/workflows/ci-dashboard.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
name: Dashboard CI

on:
push:
branches: [main, rebranding/bishop-state]
paths:
- "codebenders-dashboard/**"
- ".github/workflows/ci-dashboard.yml"
pull_request:
branches: [main, rebranding/bishop-state]
paths:
- "codebenders-dashboard/**"
- ".github/workflows/ci-dashboard.yml"

defaults:
run:
working-directory: codebenders-dashboard

jobs:
ci:
name: Type check · Lint · Build
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v4

- uses: actions/setup-node@v4
with:
node-version: "20"
cache: "npm"
cache-dependency-path: codebenders-dashboard/package-lock.json

- name: Install dependencies
run: npm ci

- name: TypeScript type check
run: npx tsc --noEmit

- name: Lint
run: npm run lint

- name: Build
run: npm run build
env:
# Provide placeholder values so the build doesn't fail on missing env assertions.
# API routes and Supabase calls are opt-in at runtime; they are not executed during build.
NEXT_PUBLIC_SUPABASE_URL: https://placeholder.supabase.co
NEXT_PUBLIC_SUPABASE_ANON_KEY: placeholder-anon-key
DB_HOST: localhost
DB_PORT: 5432
DB_USER: postgres
DB_PASSWORD: postgres
DB_NAME: postgres
44 changes: 44 additions & 0 deletions .github/workflows/ci-python.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
name: Python CI

on:
push:
branches: [main, rebranding/bishop-state]
paths:
- "ai_model/**"
- "operations/**"
- "requirements.txt"
- ".github/workflows/ci-python.yml"
pull_request:
branches: [main, rebranding/bishop-state]
paths:
- "ai_model/**"
- "operations/**"
- "requirements.txt"
- ".github/workflows/ci-python.yml"

jobs:
ci:
name: Lint · Deps · Syntax check
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v4

- uses: actions/setup-python@v5
with:
python-version: "3.11"
cache: "pip"

- name: Install ruff
run: pip install ruff

- name: Lint (ruff)
run: ruff check ai_model/ operations/

- name: Install dependencies
run: pip install -r requirements.txt

- name: Syntax check — entry points
run: |
python -m py_compile ai_model/complete_ml_pipeline.py
python -m py_compile operations/db_config.py
57 changes: 57 additions & 0 deletions .github/workflows/deploy-preview.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
name: Deploy Preview

on:
pull_request:
types: [opened, synchronize, reopened]

jobs:
deploy:
name: Vercel preview deployment
runs-on: ubuntu-latest
# Only run when Vercel secrets are configured (skips forks / contributors without access)
if: ${{ vars.VERCEL_PROJECT_ID != '' }}

permissions:
pull-requests: write # needed to post the preview URL comment

steps:
- uses: actions/checkout@v4

- uses: actions/setup-node@v4
with:
node-version: "20"

- name: Install Vercel CLI
run: npm install --global vercel@latest

- name: Pull Vercel environment (preview)
run: vercel pull --yes --environment=preview --token=${{ secrets.VERCEL_TOKEN }}
env:
VERCEL_ORG_ID: ${{ secrets.VERCEL_ORG_ID }}
VERCEL_PROJECT_ID: ${{ secrets.VERCEL_PROJECT_ID }}

- name: Build
run: vercel build --token=${{ secrets.VERCEL_TOKEN }}
env:
VERCEL_ORG_ID: ${{ secrets.VERCEL_ORG_ID }}
VERCEL_PROJECT_ID: ${{ secrets.VERCEL_PROJECT_ID }}

- name: Deploy
id: deploy
run: |
url=$(vercel deploy --prebuilt --token=${{ secrets.VERCEL_TOKEN }})
echo "url=$url" >> "$GITHUB_OUTPUT"
env:
VERCEL_ORG_ID: ${{ secrets.VERCEL_ORG_ID }}
VERCEL_PROJECT_ID: ${{ secrets.VERCEL_PROJECT_ID }}

- name: Post preview URL to PR
uses: actions/github-script@v7
with:
script: |
github.rest.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
body: `## Preview deployment\n\n🚀 **${{ steps.deploy.outputs.url }}**\n\nDeployed from ${context.sha.slice(0, 7)}.`,
})
47 changes: 47 additions & 0 deletions .github/workflows/deploy-production.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
name: Deploy Production

on:
push:
branches: [main]

jobs:
deploy:
name: Vercel production deployment
runs-on: ubuntu-latest
# Only run when Vercel secrets are configured
if: ${{ vars.VERCEL_PROJECT_ID != '' }}

environment:
name: production
url: ${{ steps.deploy.outputs.url }}

steps:
- uses: actions/checkout@v4

- uses: actions/setup-node@v4
with:
node-version: "20"

- name: Install Vercel CLI
run: npm install --global vercel@latest

- name: Pull Vercel environment (production)
run: vercel pull --yes --environment=production --token=${{ secrets.VERCEL_TOKEN }}
env:
VERCEL_ORG_ID: ${{ secrets.VERCEL_ORG_ID }}
VERCEL_PROJECT_ID: ${{ secrets.VERCEL_PROJECT_ID }}

- name: Build
run: vercel build --prod --token=${{ secrets.VERCEL_TOKEN }}
env:
VERCEL_ORG_ID: ${{ secrets.VERCEL_ORG_ID }}
VERCEL_PROJECT_ID: ${{ secrets.VERCEL_PROJECT_ID }}

- name: Deploy
id: deploy
run: |
url=$(vercel deploy --prebuilt --prod --token=${{ secrets.VERCEL_TOKEN }})
echo "url=$url" >> "$GITHUB_OUTPUT"
env:
VERCEL_ORG_ID: ${{ secrets.VERCEL_ORG_ID }}
VERCEL_PROJECT_ID: ${{ secrets.VERCEL_PROJECT_ID }}
50 changes: 50 additions & 0 deletions .github/workflows/security-audit.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
name: Security Audit

on:
schedule:
- cron: "0 9 * * 1" # Every Monday at 09:00 UTC
push:
branches: [main]
workflow_dispatch:

jobs:
audit-npm:
name: npm audit (dashboard)
runs-on: ubuntu-latest

defaults:
run:
working-directory: codebenders-dashboard

steps:
- uses: actions/checkout@v4

- uses: actions/setup-node@v4
with:
node-version: "20"
cache: "npm"
cache-dependency-path: codebenders-dashboard/package-lock.json

- name: Install dependencies
run: npm ci

- name: Audit
run: npm audit --audit-level=high

audit-python:
name: pip-audit (ML pipeline)
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v4

- uses: actions/setup-python@v5
with:
python-version: "3.11"
cache: "pip"

- name: Install pip-audit
run: pip install pip-audit

- name: Audit
run: pip-audit -r requirements.txt
23 changes: 23 additions & 0 deletions ruff.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Ruff configuration for the ML pipeline and operations code.
#
# Rule selection is intentionally narrow to give a green CI baseline
# from the existing codebase. Expand select/remove ignores incrementally
# as the code is cleaned up.
#
# Selected rules:
# E9xx — syntax errors (always fatal)
# F — pyflakes: undefined names, bad imports, redefinitions
#
# Ignored rules (existing code baseline):
# F401 — imported but unused (common in ML notebooks-style scripts)
# F541 — f-string without placeholders (style, not a bug)
# F841 — local variable assigned but never used (acceptable in data scripts)

[lint]
select = ["E9", "F"]

ignore = [
"F401",
"F541",
"F841",
]
Loading