- CI workflow commits
cities/*/events.json,cities.json, andversion.txtto git after every build - Individual
.icsfiles from scrapers/feeds are also committed - The app does not serve these files to users — it queries Supabase directly
- The
load-eventsedge function fetchesevents.jsonfromraw.githubusercontent.comto upsert into Supabase cities.jsonandversion.txtARE used by the frontend at load time (via GitHub Pages)
The issue proposes GitHub Releases as a data archive, but there's a critical dependency: load-events fetches events.json from the raw git content. If we stop committing those files to main, we need an alternative path for getting data into Supabase.
Option A — Direct upload from CI to Supabase (recommended, simplest)
- Instead of: CI commits → git push → edge function fetches from GitHub → upserts to Supabase
- Do: CI generates events.json → CI calls
load-eventswith the data inline (POST body) or CI directly calls the Supabase REST API - This eliminates the round-trip through git entirely
- The
load-eventsedge function already accepts a city list in the POST body; we'd extend it to accept event data too, OR we bypass it and use the Supabase REST API directly from CI
Option B — Upload to GitHub Release, fetch from there
- CI creates a release tarball,
load-eventsfetches from the latest release instead of raw git - More complex (release API, finding latest asset URL) with no real benefit over Option A
Recommendation: Option A. Modify the workflow to POST event data directly to the edge function or Supabase API, removing the git-as-transport pattern entirely.
-
Add to
.gitignore:cities/*/*.ics cities/*/events.json cities/*/combined.ics -
git rm --cachedto untrack existing files (keeps them locally):git rm --cached cities/*/*.ics cities/*/events.json
-
Keep committing
cities.jsonandversion.txt— these are small, stable, and consumed by the frontend from GitHub Pages
Create an orphan data branch (no shared history with main) for analysis, debugging, and auditing:
- name: Archive data to data branch
run: |
# Save generated files
mkdir -p /tmp/build-data
cp -r cities/*/events.json cities/*/*.ics report.json /tmp/build-data/ 2>/dev/null || true
# Switch to data branch
git fetch origin data || git checkout --orphan data
git checkout data
# Copy in new data
cp -r /tmp/build-data/* .
git add cities/*/events.json cities/*/*.ics report.json
git commit -m "Build $(date +%Y%m%d-%H%M%S)"
git push origin data
# Return to main
git checkout mainWhy a data branch:
- Diffing is trivial:
git diff data~1..data -- cities/santarosa/events.json - No noise on
main—databranch never merges intomain - Full git history of generated data, searchable with
git log - Timezone tests / report.json auditing can check out
databranch or fetch individual files viaraw.githubusercontent.com/.../data/... - Per-source event count regressions are visible in
git diff
For periodic archival with pruning (complements the data branch):
- name: Create data release
run: |
TAG="build-$(date +%Y%m%d-%H%M%S)"
tar czf data.tar.gz cities/*/events.json cities/*/*.ics
gh release create "$TAG" data.tar.gz \
--title "Build $TAG" \
--notes "Auto-generated calendar data"
- name: Prune old releases (keep last 30)
run: |
gh release list --limit 100 --json tagName,createdAt \
| jq -r '.[30:][].tagName' \
| xargs -I{} gh release delete {} --yes --cleanup-tagModify supabase/functions/load-events/index.ts to accept event data directly in the POST body instead of fetching from GitHub:
// Current: fetches from raw.githubusercontent.com
// New: accepts events array in request body per city
// Fallback: can still fetch from data branch URL if neededThe workflow step changes from triggering a fetch to posting data directly.
tests/test_timezone_pipeline.pyalready uses synthetic ICS data — no changes needed- Browser tests (
test.html) query Supabase — no changes needed - Regression tests use the live app — no changes needed
- If any future test needs real build data, it can check out the
databranch
Remove from generate-calendar.yml:
- The git add/commit/push block (lines ~441-478) that commits generated files to
main - The rebase-conflict retry logic (no longer needed)
- Keep the git push for
cities.jsonandversion.txtonly
git pullstops conflicting — no more "always expect push to fail" pattern- Git history becomes meaningful — only real code changes on
main - Repo size stops growing on
main— no more ~800 ICS files per build - CI is faster — no rebase/retry loop
load-eventsedge function must be updated before we stop committing (Phase 1 before Phase 2)- Edge function JWT gotcha still applies if we redeploy
load-events - Rollback path: if Supabase is down, we can't recover from
mainanymore — but we CAN recover from thedatabranch or latest GitHub Release cities.jsonandversion.txtshould still be committed tomain(small, used by frontend)databranch size will grow over time — consider periodic squashing or starting a fresh orphan if it gets unwieldy
- Modify
load-eventsto accept inline data (or switch to direct Supabase REST calls from CI) - Test the new ingestion path on one city
- Create the orphan
databranch - Add the data-branch archive step to the workflow
- Update
.gitignoreandgit rm --cached - Remove the old commit/push logic from the workflow
- Optionally add GitHub Releases for long-term snapshots
- Test a full CI run end-to-end