Skip to content

phonotechnologies/cicosts-api

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

44 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

CICosts API

CI/CD

FastAPI backend for CICosts - Track and optimize your CI/CD costs.

Environment URL
Production https://api.cicosts.dev
Development https://dev-api.cicosts.dev
API Docs https://dev-api.cicosts.dev/docs

Architecture

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                      AWS Lambda                              β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”           β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”‚
β”‚  β”‚   handler.py    β”‚           β”‚      workers.py         β”‚  β”‚
β”‚  β”‚   (API Lambda)  β”‚           β”‚   (Workers Lambda)      β”‚  β”‚
β”‚  β”‚                 β”‚           β”‚                         β”‚  β”‚
β”‚  β”‚  FastAPI +      β”‚           β”‚  SQS β†’ Process webhooks β”‚  β”‚
β”‚  β”‚  Mangum         β”‚           β”‚  Calculate costs        β”‚  β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”˜           β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β”‚
β”‚           β”‚                                 β”‚                β”‚
β”‚           β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜                β”‚
β”‚                            β–Ό                                 β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”β”‚
β”‚  β”‚                       app/                               β”‚β”‚
β”‚  β”‚  routers/   β†’ API endpoints (auth, dashboard, alerts)   β”‚β”‚
β”‚  β”‚  services/  β†’ Business logic (cost calc, alerts, email) β”‚β”‚
β”‚  β”‚  workers/   β†’ Webhook processing (workflow_run, job)    β”‚β”‚
β”‚  β”‚  models/    β†’ SQLAlchemy models                         β”‚β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                            β”‚
                            β–Ό
              β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
              β”‚   Supabase Postgres   β”‚
              β”‚  (Transaction Pooler) β”‚
              β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Tech Stack

  • Framework: FastAPI (Python 3.11)
  • ORM: SQLAlchemy 2.0
  • Database: PostgreSQL (Supabase)
  • Auth: GitHub OAuth + JWT
  • Email: AWS SES
  • Queue: AWS SQS
  • Testing: pytest + SQLite in-memory
  • Deployment: AWS Lambda via GitHub Actions

Local Development

Prerequisites

  • Python 3.11+
  • PostgreSQL (or Supabase connection)

Setup

# Create virtual environment
python -m venv venv
source venv/bin/activate  # or `venv\Scripts\activate` on Windows

# Install dependencies
pip install -r requirements.txt

# Copy environment file
cp .env.example .env
# Edit .env with your credentials

# Run development server
uvicorn app.main:app --reload --port 8000

API Docs

Project Structure

cicosts-api/
β”œβ”€β”€ handler.py              # Lambda API entry point
β”œβ”€β”€ workers.py              # Lambda workers entry point
β”œβ”€β”€ app/
β”‚   β”œβ”€β”€ main.py             # FastAPI application
β”‚   β”œβ”€β”€ config.py           # Environment settings
β”‚   β”œβ”€β”€ database.py         # Database connection
β”‚   β”œβ”€β”€ dependencies.py     # Auth middleware
β”‚   β”œβ”€β”€ routers/
β”‚   β”‚   β”œβ”€β”€ health.py       # Health check
β”‚   β”‚   β”œβ”€β”€ auth.py         # GitHub OAuth
β”‚   β”‚   β”œβ”€β”€ dashboard.py    # Dashboard data
β”‚   β”‚   β”œβ”€β”€ alerts.py       # Alerts CRUD
β”‚   β”‚   β”œβ”€β”€ settings.py     # User settings
β”‚   β”‚   └── webhooks.py     # GitHub/Stripe webhooks
β”‚   β”œβ”€β”€ models/
β”‚   β”‚   β”œβ”€β”€ user.py
β”‚   β”‚   β”œβ”€β”€ organization.py
β”‚   β”‚   β”œβ”€β”€ org_membership.py
β”‚   β”‚   β”œβ”€β”€ workflow_run.py
β”‚   β”‚   β”œβ”€β”€ job.py
β”‚   β”‚   β”œβ”€β”€ alert.py
β”‚   β”‚   └── github_installation.py
β”‚   β”œβ”€β”€ services/
β”‚   β”‚   β”œβ”€β”€ cost_calculator.py  # Runner pricing
β”‚   β”‚   β”œβ”€β”€ alert_service.py    # Alert logic
β”‚   β”‚   └── email_service.py    # AWS SES
β”‚   └── workers/
β”‚       └── handler.py          # SQS processing
β”œβ”€β”€ alembic/                # Database migrations
β”œβ”€β”€ tests/                  # Test suite (189 tests)
β”œβ”€β”€ scripts/
β”‚   β”œβ”€β”€ seed_data.py        # Sample data
β”‚   └── simulate_webhooks.py
└── requirements.txt

API Endpoints

Health

GET /health           # Full health check
GET /health/ready     # Readiness probe
GET /health/live      # Liveness probe

Authentication

GET  /api/v1/auth/login      # Initiate GitHub OAuth
GET  /api/v1/auth/callback   # OAuth callback
GET  /api/v1/auth/me         # Get current user
POST /api/v1/auth/logout     # Logout
POST /api/v1/auth/refresh    # Refresh token

Dashboard

GET /api/v1/dashboard/summary        # Cost summary (today, week, month)
GET /api/v1/dashboard/trends         # Cost trends over time
GET /api/v1/dashboard/top-workflows  # Top workflows by cost
GET /api/v1/dashboard/recent-runs    # Recent workflow runs
GET /api/v1/dashboard/workflows      # Paginated workflow list

Alerts

GET    /api/v1/alerts              # List alerts
POST   /api/v1/alerts              # Create alert
GET    /api/v1/alerts/{id}         # Get alert
PUT    /api/v1/alerts/{id}         # Update alert
DELETE /api/v1/alerts/{id}         # Delete alert
GET    /api/v1/alerts/{id}/triggers # Alert trigger history
POST   /api/v1/alerts/{id}/check   # Manually check alert

Settings

GET   /api/v1/settings/user          # Get user profile
PATCH /api/v1/settings/user          # Update profile
GET   /api/v1/settings/notifications # Notification preferences
PATCH /api/v1/settings/notifications # Update notifications
GET   /api/v1/settings/organizations # List organizations
POST  /api/v1/settings/organizations/{id}/leave # Leave org
DELETE /api/v1/settings/account      # Delete account

Webhooks

POST /api/v1/webhooks/github   # GitHub App webhooks
POST /api/v1/webhooks/stripe   # Stripe webhooks

Testing

# Run all tests (189 tests)
python -m pytest tests/ -v

# With coverage
python -m pytest tests/ --cov=app --cov-report=html

# Specific test file
python -m pytest tests/test_cost_calculator.py -v

# With short tracebacks
python -m pytest tests/ -v --tb=short

Test Coverage

Test File Tests Description
test_cost_calculator.py 34 Runner pricing logic
test_email_service.py 11 Email templates
test_dashboard.py 26 Dashboard endpoints
test_alerts_router.py 34 Alerts CRUD
test_auth.py 18 OAuth flow
test_settings.py 17 User settings
test_webhooks.py 9 Webhook handling
test_worker_handler.py 12 SQS processing

Total: 189/189 passing (100%)

Seed Data

For local development, populate the database:

python scripts/seed_data.py

Cost Calculator

GitHub Actions runner pricing (per minute):

Runner Price/min
ubuntu-latest (2-core) $0.008
ubuntu-latest-4-cores $0.016
ubuntu-latest-8-cores $0.032
ubuntu-latest-16-cores $0.064
windows-latest $0.016
macos-latest $0.080
macos-latest-large $0.120
ubuntu-latest-arm $0.005

CI/CD Pipeline

Unified pipeline via .github/workflows/ci-cd.yml:

Push to main β†’ Test β†’ Lint β†’ Build β†’ Deploy Dev β†’ Deploy Prod
                                           ↓
                                   (requires approval)
Stage Description
Test pytest with coverage + Codecov upload
Lint ruff + mypy (non-blocking)
Build Create Lambda package β†’ upload artifact
Deploy Dev Update cicosts-dev-api + cicosts-dev-workers
Deploy Prod Update cicosts-prod-api + cicosts-prod-workers (requires approval)

Manual Deployment

pip install -r requirements.txt -t package/
cp -r app package/
cp handler.py workers.py package/
cd package && zip -r ../lambda-package.zip .

aws lambda update-function-code \
  --function-name cicosts-prod-api \
  --zip-file fileb://lambda-package.zip

Environment Variables

Variable Description
DATABASE_URL PostgreSQL connection string
JWT_SECRET JWT signing secret
GITHUB_CLIENT_ID OAuth client ID
GITHUB_CLIENT_SECRET OAuth client secret
GITHUB_APP_PRIVATE_KEY GitHub App private key
GITHUB_WEBHOOK_SECRET Webhook signature secret
AWS_SQS_QUEUE_URL SQS queue for webhooks
STRIPE_SECRET_KEY Stripe API key
RESEND_API_KEY Email service API key

Production Data

As of December 21, 2025:

  • 41 workflow runs tracked
  • 64 jobs with cost data
  • $0.22 total costs calculated
  • 35.78 minutes billable time

References

Releases

No releases published

Packages

 
 
 

Contributors