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
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
## 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.
- Profiles an organization before migrating — crawls every repository and surfaces per-repo migration *considerations* (what the GitHub export 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
4 changes: 2 additions & 2 deletions docs/api.md
Original file line number Diff line number Diff line change
Expand Up @@ -72,8 +72,8 @@ 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.
and reports per-repo migration *considerations* (things the GitHub export won't
carry over) and actionable insights, so you can assess readiness before migrating.

| Method | Endpoint | Description |
|---|---|---|
Expand Down
10 changes: 5 additions & 5 deletions src/lib/profile/consideration-registry.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@ import {
type Consideration,
type ConsiderationKind,
type ConsiderationSeverity,
GEI_DOC_URL,
GEI_DOCS_VERIFIED,
MIGRATION_CONSIDERATIONS,
MIGRATION_DOC_URL,
MIGRATION_DOCS_VERIFIED,
} from "./consideration-registry";

const KINDS: ConsiderationKind[] = [
Expand Down Expand Up @@ -79,7 +79,7 @@ describe("consideration registry integrity", () => {
for (const g of MIGRATION_CONSIDERATIONS) {
expect(g.docAnchor, g.id).toMatch(/^#[a-z0-9-]+$/);
}
expect(GEI_DOC_URL).toMatch(/^https:\/\/docs\.github\.com\//);
expect(MIGRATION_DOC_URL).toMatch(/^https:\/\/docs\.github\.com\//);
});

test("size/limit blockers are estimated, exact-signal considerations are exact", () => {
Expand All @@ -93,8 +93,8 @@ describe("consideration registry integrity", () => {
});

test("the docs-verified stamp is an ISO date", () => {
expect(GEI_DOCS_VERIFIED).toMatch(/^\d{4}-\d{2}-\d{2}$/);
expect(Number.isNaN(Date.parse(GEI_DOCS_VERIFIED))).toBe(false);
expect(MIGRATION_DOCS_VERIFIED).toMatch(/^\d{4}-\d{2}-\d{2}$/);
expect(Number.isNaN(Date.parse(MIGRATION_DOCS_VERIFIED))).toBe(false);
});

test("covers the considerations the Profile workspace is built around", () => {
Expand Down
32 changes: 16 additions & 16 deletions src/lib/profile/consideration-registry.ts
Original file line number Diff line number Diff line change
@@ -1,26 +1,26 @@
/**
* Consideration registry — the canonical list of source data that GitHub
* Enterprise Importer (GEI) does not migrate cleanly. The Profile workspace
* reads this to detect each consideration, classify it, and route it to its
* remediation (supplemental tooling, a reconfigure step, or a "heads up, this
* is lost" note).
* Consideration registry — the canonical list of source data that the GitHub
* export does not carry cleanly. The Profile workspace reads this to detect
* each consideration, classify it, and route it to its remediation
* (supplemental tooling, a reconfigure step, or a "heads up, this is lost"
* note).
*
* It is plain reference data — edit it whenever GEI changes. The accompanying
* test (consideration-registry.test.ts) guards its integrity (unique ids,
* well-formed entries, kind/severity consistency) so edits can't silently
* corrupt it.
* It is plain reference data — edit it whenever the export's coverage changes.
* The accompanying test (consideration-registry.test.ts) guards its integrity
* (unique ids, well-formed entries, kind/severity consistency) so edits can't
* silently corrupt it.
*
* Verified against GitHub's "About migrations between GitHub products" and its
* "Limitations on migrated data" section. Several entries are in public preview
* upstream, so re-check periodically and bump GEI_DOCS_VERIFIED.
* upstream, so re-check periodically and bump MIGRATION_DOCS_VERIFIED.
*/

/** Base GEI documentation URL; each entry's `docAnchor` appends to this. */
export const GEI_DOC_URL =
/** Base migration documentation URL; each entry's `docAnchor` appends to this. */
export const MIGRATION_DOC_URL =
"https://docs.github.com/en/migrations/using-github-enterprise-importer/migrating-between-github-products/about-migrations-between-github-products";

/** Date the registry was last reconciled with the GEI docs (YYYY-MM-DD). */
export const GEI_DOCS_VERIFIED = "2026-06-13";
/** Date the registry was last reconciled with the migration docs (YYYY-MM-DD). */
export const MIGRATION_DOCS_VERIFIED = "2026-06-13";

/**
* What kind of remediation a consideration needs:
Expand Down Expand Up @@ -63,7 +63,7 @@ export interface Consideration {
routesTo: string | null;
/** One-line, doc-grounded explanation of the consideration. */
summary: string;
/** Anchor into GEI_DOC_URL backing this entry. */
/** Anchor into MIGRATION_DOC_URL backing this entry. */
docAnchor: string;
}

Expand Down Expand Up @@ -109,7 +109,7 @@ export const MIGRATION_CONSIDERATIONS: readonly Consideration[] = [
detector: "graphql-discussions-count",
confidence: "exact",
routesTo: "Discussions migration tooling",
summary: "Discussions at the repository level are not migrated by GEI.",
summary: "Discussions at the repository level are not included in the GitHub export.",
docAnchor: NOT_MIGRATED,
},
{
Expand Down
2 changes: 1 addition & 1 deletion src/lib/server/migrate/github-ops.test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/**
* Tests for the GEI archive-export wait helper. `waitForArchive` polls a GHES
* Tests for the archive-export wait helper. `waitForArchive` polls a GHES
* migration's status and resolves with the archive URL once it's exported.
*
* The helper takes a full `InstanceType<typeof RetryOctokit>` (hundreds of
Expand Down
6 changes: 3 additions & 3 deletions src/lib/server/migrate/github-ops.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
/**
* GitHub Enterprise Importer (GEI) operations — the migration-specific GitHub
* GitHub cross-product migration operations — the migration-specific GitHub
* calls that drive the import pipeline, kept out of `core/github` so that
* module stays a generic client + repo-operations primitive any domain can use.
*
* Two groups:
* - GHES archive export (REST): version gate + git/metadata archive jobs and
* the poll-until-exported wait.
* - GEI GraphQL: migration-source creation, start/get/abort a repository
* - Migration GraphQL: migration-source creation, start/get/abort a repository
* migration, and post-migration source archiving.
*
* Depends only on `core` (the client type, the version comparator, sleep) — no
Expand Down Expand Up @@ -122,7 +122,7 @@ export async function waitForArchive(
throw new Error("Archive wait aborted");
}

// ── GEI GraphQL ──────────────────────────────────────────────────────────────
// ── Migration GraphQL ───────────────────────────────────────────────────────────

export async function getOrgId(gql: typeof graphql, org: string): Promise<string> {
const result = await gql<{ organization: { id: string } }>(
Expand Down
4 changes: 2 additions & 2 deletions src/lib/server/profile/analyze.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
/**
* Consideration-analysis engine — runs a repository's signals against the GEI
* Consideration-analysis engine — runs a repository's signals against the
* consideration registry and produces a per-repo readiness profile.
*
* The registry (`$lib/profile/consideration-registry`) is the canonical checklist of
* what GEI does not migrate cleanly. This engine evaluates each entry against
* what the GitHub export does not carry cleanly. This engine evaluates each entry against
* the gathered `RepoSignals` and classifies it:
*
* - applies — the consideration is present (with human-readable evidence)
Expand Down
6 changes: 3 additions & 3 deletions src/lib/server/profile/augment.ts
Original file line number Diff line number Diff line change
Expand Up @@ -99,9 +99,9 @@ function ownerOf(nameWithOwner: string): string {
}

/**
* Whether a branch protection rule uses any feature GitHub's importer does not
* migrate. (Plain required-reviews/status-checks DO migrate, so a rule using
* only those counts as zero here.)
* Whether a branch protection rule uses any feature the GitHub export does not carry.
* (Plain required-reviews/status-checks DO migrate, so a rule using only those
* counts as zero here.)
*/
function usesUnmigratedFeature(rule: BranchProtectionRuleNode): boolean {
return (
Expand Down
4 changes: 2 additions & 2 deletions src/lib/server/profile/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -97,8 +97,8 @@ export interface RepoSignals extends DiscoveredRepo {
/** Branch protection rules (`branchProtectionRules.totalCount`). */
branchProtectionRuleCount: number;
/**
* How many branch protection rules use at least one feature GEI does not
* migrate (force-push allowance, required deployments, lock branch, block
* How many branch protection rules use at least one feature the GitHub export
* does not carry (force-push allowance, required deployments, lock branch, block
* creations, require last-push approval, or bypass actors). `> 0` means the
* branch-protection-partial gap applies.
*/
Expand Down
4 changes: 2 additions & 2 deletions src/routes/+page.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,8 @@
</div>
<h2 class="text-lg font-semibold text-gray-50">Profile</h2>
<p class="mt-1.5 flex-1 text-sm text-gray-400">
Analyze a source organization for migration readiness — surface what GEI
won't carry cleanly and route each consideration to its remediation.
Analyze a source organization for migration readiness — surface what the
GitHub export won't carry cleanly and route each consideration to its remediation.
</p>
<div class="mt-4 flex items-center justify-end text-sm">
<span class="inline-flex items-center gap-1 font-medium text-violet-400">
Expand Down
2 changes: 1 addition & 1 deletion src/routes/profile/+page.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@
Profile
</h1>
<p class="mt-1 text-sm text-gray-400">
Crawl a source organization and surface what GitHub Enterprise Importer won't migrate cleanly.
Crawl a source organization and surface what the GitHub export won't carry cleanly.
</p>
</div>
<a href="/" class="text-sm text-gray-400 transition-colors hover:text-gray-50">← Workspaces</a>
Expand Down