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
6 changes: 3 additions & 3 deletions .github/workflows/verify.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,9 @@ jobs:
- name: Install dependencies
run: bun install --frozen-lockfile

# verify:json runs the exact 10-gate suite developers run locally
# verify:json runs the exact 11-gate suite developers run locally
# (typecheck · check · lint · format · coverage · dup · deadcode · cycles
# · build · audit), collects every failure (not fail-fast), and exits
# non-zero if any gate is red.
# · boundaries · build · audit), collects every failure (not fail-fast),
# and exits non-zero if any gate is red.
- name: Run gate suite
run: bun run verify:json
5 changes: 3 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,15 @@
</p>

<p align="center">
Single &amp; batch migrations · Real-time SSE progress · Cancellation &amp; restart · Crash recovery · GitHub App &amp; PAT auth
Single &amp; batch migrations · Pre-migration profiling · Real-time SSE progress · Cancellation &amp; restart · Crash recovery · GitHub App &amp; PAT auth
</p>

---

## Capabilities

- Migrates repositories GHES → GHEC and GHEC → GHEC, via archive upload or direct passthrough.
- Profiles an organization before migrating — crawls every repository and surfaces per-repo migration *considerations* (what GEI won't carry over) plus actionable insights, streamed live.
- Accepts batch requests of up to 500 repositories; a FIFO queue caps execution at 10 concurrent migrations (GitHub's limit).
- Reports progress over Server-Sent Events (SSE) — phase timeline, per-resource progress, and throughput.
- Supports cancelling in-flight migrations and restarting failed or cancelled ones in place.
Expand Down Expand Up @@ -94,7 +95,7 @@ Then open the app, click **New Migration**, and go. Full walkthrough in

- **Stack:** [Bun](https://bun.sh) · SvelteKit 2 + Svelte 5 (runes) · TypeScript · `bun:sqlite` · Tailwind v4 · [Biome](https://biomejs.dev)
- **Requirements:** Bun ≥ 1.3.9, Docker/Podman for containerized deployment
- **Quality gates:** `bun run verify` runs typecheck, svelte-check, lint, format, coverage, duplication, dead-code, circular-import, build, and audit — see [Development](docs/development.md)
- **Quality gates:** `bun run verify` runs typecheck, svelte-check, lint, format, coverage, duplication, dead-code, circular-import, import-boundary, build, and audit — see [Development](docs/development.md)

```bash
bun install # install deps
Expand Down
49 changes: 49 additions & 0 deletions docs/api.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,13 @@ unauthenticated `/api/*` requests get `401`. `/api/health` is always reachable
auth-configuration details to authenticated callers.

Migration endpoints are namespaced under `/api/migrate/*` (the Migrate
workspace) and profiler endpoints under `/api/profile/*` (the Profile
workspace). `/api/health` and `/api/rate-limits` are workspace-agnostic and stay
at the root.

- [Migrations](#migrations)
- [Batches](#batches)
- [Profile](#profile)
- [System & streams](#system--streams)
- [Request validation](#request-validation)
- [SSE streams](#sse-streams)
Expand Down Expand Up @@ -67,6 +69,53 @@ a `targetOrg`.

---

## Profile

The Profiler workspace (`/api/profile/*`) crawls an organization's repositories
and reports per-repo migration *considerations* (things GEI won't carry over)
and actionable insights, so you can assess readiness before migrating.

| Method | Endpoint | Description |
|---|---|---|
| `POST` | `/api/profile` | Start a profiling run for an organization |
| `GET` | `/api/profile` | List profiling runs (most recent first) |
| `GET` | `/api/profile/:id` | Run details — status, per-repo considerations, insights |
| `GET` | `/api/profile/:id/events` | Per-run SSE stream of live progress |

A profiling run needs only the organization login — source credentials come from
the server environment (the same source auth the Migrate workspace uses):

```jsonc
{
"org": "octo-org" // required; a GitHub org login
}
```

The run record is created synchronously and returned with `201`; the crawl then
proceeds in the background (poll `GET /api/profile/:id` or subscribe to the
event stream for progress). `POST` returns `400` if `org` is missing or
malformed, or if no source credentials are configured on the server.

`GET /api/profile` returns `{ "runs": [ … ] }` (most recent first).
`GET /api/profile/:id` returns the run plus its per-repo results (each with its
applying considerations and derived insights), or `404` if the id is unknown.

### Profile progress stream

`GET /api/profile/:id/events` streams `text/event-stream`. Each event is JSON
with a `type` discriminator:

- `{ "type": "progress", "profiled": <n>, "total": <n>, "repo": "owner/name" }`
— emitted as each repository is profiled.
- `{ "type": "done", "state": "completed" | "failed" }` — emitted once when the
run settles, after which the stream closes.

Unlike the migration streams, profile progress is ephemeral: there is no event
replay or `?after=` cursor. A reconnecting client simply refetches
`GET /api/profile/:id` for the current snapshot. An unknown run id → `404`.

---

## System & streams

| Method | Endpoint | Description |
Expand Down