A unified web calendar for all CMU academic events https://cmucal.com
  • Python 60.5%
  • TypeScript 36.3%
  • HTML 1.4%
  • Nix 0.7%
  • CSS 0.6%
  • Other 0.4%
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
Jalen Lu 7d7581e8c5
All checks were successful
kennel/build build succeeded
kennel/deploy deployment healthy
CI / check-1 (push) Successful in 2m19s
CI / build (push) Successful in 2m11s
CI / check (push) Successful in 0s
docs: get dev secrets from OpenBao, keep env files as the manual setup (#94)
2026-10-03 22:49:20 +00:00
.forgejo/workflows feat(scraper): import club events from TartanConnect (#93) 2026-10-03 22:47:01 +00:00
api feat(scraper): import club events from TartanConnect (#93) 2026-10-03 22:47:01 +00:00
docs docs: get dev secrets from OpenBao, keep env files as the manual setup (#94) 2026-10-03 22:49:20 +00:00
redirect fix: redirect cal.scottylabs.org to cmucal.com (#6) 2026-09-29 00:26:58 +00:00
web docs: get dev secrets from OpenBao, keep env files as the manual setup (#94) 2026-10-03 22:49:20 +00:00
.env.example fix: satisfy the shared CI hook set 2026-08-24 19:35:34 -04:00
.gitignore docs: get dev secrets from OpenBao, keep env files as the manual setup (#94) 2026-10-03 22:49:20 +00:00
.mcp.json chore: link prod and dev Supabase projects to the MCP config 2026-08-22 18:59:04 -04:00
devenv.lock chore: commit devenv.lock (#20) 2026-10-03 02:44:24 +00:00
devenv.nix fix: redirect cal.scottylabs.org to cmucal.com (#6) 2026-09-29 00:26:58 +00:00
devenv.yaml fix: declare the full devenv input set 2026-08-24 19:21:42 -04:00
flake.lock chore: update nixpkgs lock (#4) 2026-09-29 01:17:06 +00:00
flake.nix feat: page views in posthog and api errors in sentry (#18) 2026-10-03 02:58:49 +00:00
README.md feat: migrate auth from clerk to keycloak (#13) 2026-09-29 01:03:11 +00:00
secretspec.toml feat: page views in posthog and api errors in sentry (#18) 2026-10-03 02:58:49 +00:00
ty.toml chore: point ty at the api venv (#11) 2026-09-29 00:26:50 +00:00

cal

A unified web calendar for all CMU academic events, live at cmucal.com. Deployed with kennel.

  • api/: Flask API, scrapers, and course agent (the api service).
  • web/: Next.js 16 frontend (the web service).
  • docs/: contributor docs, published on docs.scottylabs.org.

Both services are declared in devenv.nix under scottylabs.kennel.services and built by the matching packages in flake.nix.

Getting started

No nix needed: Node 22, Python 3.10+, and uv. Full walkthrough in docs/getting-started.md.

cp api/.env.example api/.env.development   # fill in the secrets
cd api && uv sync && uv run python run.py  # http://localhost:8080

cp web/.env.example web/.env.local         # in a second terminal; sign-in
                                           # also needs Ricochet (see docs)
cd web && npm install && npm run dev       # http://localhost:3000

Nix and devenv are only needed to change the build and deploy config (devenv.nix, flake.nix, secretspec.toml): run nix run git+https://git.cmu.dev/ScottyLabs/kennel#login once, then devenv allow.

Deployment

Kennel deploys main to production (cmucal.com, api.cmucal.com), so a merge ships to users. Other branch pushes are ignored; open a pull request to get CI. Preview deployments are off because every deployment would share the one Supabase database.

Each service exposes GET /api/health, which kennel polls after starting it.

Secrets

Declared in secretspec.toml, stored in OpenBao, injected at deploy time. Never committed.

secretspec set -P prod SUPABASE_DB_URL
secretspec check -P prod

web/.env.production is the exception: NEXT_PUBLIC_* values are inlined at build time, before kennel resolves secrets, and are public by design.

Known gaps

  • Supabase (free tier) is still the database. .forgejo/workflows/keepalive.yml keeps it from pausing. Moving to kennel Postgres means rewriting the scraper and course agent writers, which use the Supabase REST client.
  • Scraped course events do not skip holidays, and lecture vs recitation is guessed from the section label.
  • Ruff runs a reduced rule set and the ty hook is off.
  • nix build .#api fails on macOS (a darwin nix bug); CI builds on Linux.