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
32 changes: 25 additions & 7 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,9 @@ NATS_URL=nats://nats:4222
# ── Clerk (Auth) ─────────────────────────────────────────────
# Get these from https://clerk.com → Your App → API Keys
# Required for ALL Go services (JWT validation)
CLERK_SECRET_KEY=sk_test_REPLACE_ME
CLERK_SECRET_KEY=REPLACE_ME
# Used in frontend only:
NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY=pk_test_REPLACE_ME
NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY=REPLACE_ME
NEXT_PUBLIC_CLERK_SIGN_IN_URL=/sign-in
NEXT_PUBLIC_CLERK_SIGN_UP_URL=/sign-up
NEXT_PUBLIC_CLERK_AFTER_SIGN_IN_URL=/dashboard
Expand Down Expand Up @@ -61,7 +61,7 @@ INTEGRATION_SERVICE_HEALTH_PORT=8084
# Generate locally with: openssl rand -base64 32
CREDENTIAL_ENCRYPTION_KEY=REPLACE_WITH_BASE64_32_BYTE_KEY

# ── GitHub App (Phase 2) ─────────────────────────────────────
# ── GitHub App ───────────────────────────────────────────────
# Create this in GitHub Developer Settings -> GitHub Apps.
# Keep private keys and webhook secrets out of git.
GITHUB_APP_ID=REPLACE_ME
Expand All @@ -72,18 +72,36 @@ GITHUB_APP_WEBHOOK_SECRET=REPLACE_ME
GITHUB_APP_INSTALL_URL=https://github.com/apps/REPLACE_WITH_APP_SLUG/installations/new
GITHUB_APP_CALLBACK_URL=http://localhost:8080/api/v1/integrations/github/callback
GITHUB_WEBHOOK_URL=http://localhost:8080/api/v1/webhooks/github
GITHUB_API_VERSION=2026-03-10
FRONTEND_URL=http://localhost:3000
CORS_ALLOWED_ORIGINS=http://localhost:3000
RATE_LIMIT_REQUESTS_PER_MINUTE=120

# ── Frontend ─────────────────────────────────────────────────
NEXT_PUBLIC_API_URL=http://localhost:8080
NEXT_PUBLIC_GITHUB_APP_INSTALL_URL=https://github.com/apps/REPLACE_WITH_APP_SLUG/installations/new

# ── AI (Phase 3 — fill these later) ─────────────────────────
# ── AI providers ─────────────────────────────────────────────
# Groq API: https://groq.com → Console → API Keys (free)
GROQ_API_KEY=gsk_REPLACE_ME_IN_PHASE_3
GROQ_API_KEY=REPLACE_ME
GROQ_MODEL=openai/gpt-oss-120b

# Gemini API: https://aistudio.google.com → Get API Key (free)
GEMINI_API_KEY=AIza_REPLACE_ME_IN_PHASE_3
GEMINI_API_KEY=REPLACE_ME
EMBEDDING_PROVIDER=local
GEMINI_EMBEDDING_MODEL=gemini-embedding-2
EMBEDDING_DIMENSIONS=768

# AI Worker
AI_WORKER_PORT=8090
AI_WORKER_HEALTH_PORT=8091
AI_WORKER_URL=http://ai-worker:8090
# Required for gateway -> AI worker calls. Generate with: openssl rand -hex 32
AI_WORKER_INTERNAL_TOKEN=REPLACE_WITH_HIGH_ENTROPY_INTERNAL_TOKEN
RUN_BACKGROUND_WORKER=true
# Frequency of lifecycle cleanup; per-workspace retention defaults to 30 days.
RETENTION_CLEANUP_SECONDS=3600

# Dedicated internal runner for proposed-fix tests. Generate with:
# openssl rand -hex 32
SANDBOX_RUNNER_URL=http://sandbox-runner:8092
SANDBOX_RUNNER_INTERNAL_TOKEN=REPLACE_WITH_HIGH_ENTROPY_INTERNAL_TOKEN
139 changes: 139 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
name: OpsPilot CI

on:
pull_request:
push:
branches: [main]

permissions:
contents: read

concurrency:
group: opspilot-ci-${{ github.ref }}
cancel-in-progress: true

jobs:
frontend:
runs-on: ubuntu-latest
defaults:
run:
working-directory: frontend
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: "22"
cache: npm
cache-dependency-path: frontend/package-lock.json
- run: npm ci
- run: npm test
- run: npm run lint
- run: npm run build
env:
NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY: pk_test_ci_placeholder
CLERK_SECRET_KEY: sk_test_ci_placeholder
NEXT_PUBLIC_API_URL: http://localhost:8080
- run: npm audit --audit-level=high

test:
runs-on: ubuntu-latest
services:
postgres:
image: pgvector/pgvector:pg16
env:
POSTGRES_DB: opspilot
POSTGRES_USER: opspilot
POSTGRES_PASSWORD: test-password
ports:
- 5432:5432
options: >-
--health-cmd "pg_isready -U opspilot -d opspilot"
--health-interval 5s
--health-timeout 5s
--health-retries 10
steps:
- uses: actions/checkout@v4
- uses: actions/setup-go@v5
with:
go-version: "1.22.x"
cache-dependency-path: |
services/*/go.sum
gen/go/go.sum
- uses: actions/setup-python@v5
with:
python-version: "3.12"
cache: pip
cache-dependency-path: |
ai-worker/requirements.txt
sandbox-runner/requirements.txt
- uses: bufbuild/buf-setup-action@v1
with:
version: "1.47.2"
- name: Install Python test dependencies
run: python -m pip install -r ai-worker/requirements.txt -r sandbox-runner/requirements.txt
- name: Install pinned protobuf generators
run: |
go install google.golang.org/protobuf/cmd/protoc-gen-go@v1.34.2
go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@v1.4.0
- name: Validate protobuf sources and generated code
run: |
buf lint
PATH="$(go env GOPATH)/bin:$PATH" buf generate
git diff --exit-code -- proto gen/go
- name: Apply every database migration
env:
PGPASSWORD: test-password
run: |
for migration in infra/migrations/*.sql; do
psql -h 127.0.0.1 -U opspilot -d opspilot -v ON_ERROR_STOP=1 -f "$migration"
done
- name: Run Go and Python suites
run: make test
- name: Validate Compose expansion
env:
CLERK_SECRET_KEY: test-only
AI_WORKER_INTERNAL_TOKEN: test-only-internal-token
SANDBOX_RUNNER_INTERNAL_TOKEN: test-only-sandbox-token
run: docker compose config --quiet

images:
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
include:
- name: api-gateway
context: .
dockerfile: services/api-gateway/Dockerfile
- name: auth-service
context: .
dockerfile: services/auth-service/Dockerfile
- name: workspace-service
context: .
dockerfile: services/workspace-service/Dockerfile
- name: project-service
context: .
dockerfile: services/project-service/Dockerfile
- name: integration-service
context: .
dockerfile: services/integration-service/Dockerfile
- name: ai-worker
context: ai-worker
dockerfile: ai-worker/Dockerfile
- name: sandbox-runner
context: sandbox-runner
dockerfile: sandbox-runner/Dockerfile
- name: frontend
context: frontend
dockerfile: frontend/Dockerfile
steps:
- uses: actions/checkout@v4
- uses: docker/setup-buildx-action@v3
- uses: docker/build-push-action@v6
with:
context: ${{ matrix.context }}
file: ${{ matrix.dockerfile }}
push: false
tags: opspilot/${{ matrix.name }}:ci
cache-from: type=gha,scope=${{ matrix.name }}
cache-to: type=gha,mode=max,scope=${{ matrix.name }}
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ __pycache__/
venv/
*.egg-info/
dist/
.coverage
.pytest_cache/

# Docker
*.log
Expand Down
Loading
Loading