diff --git a/apps/gittensory-ui/src/routes/docs.maintainer-self-hosting.tsx b/apps/gittensory-ui/src/routes/docs.maintainer-self-hosting.tsx index a194c6b712..28aecaaf51 100644 --- a/apps/gittensory-ui/src/routes/docs.maintainer-self-hosting.tsx +++ b/apps/gittensory-ui/src/routes/docs.maintainer-self-hosting.tsx @@ -203,6 +203,94 @@ function MaintainerSelfHosting() { Tuning your reviews for gate semantics and this section for running the service yourself.

+ +

Moving a repo between hosted and self-host

+

+ "Hosted" here means the private managed-beta shared gittensory App + described in GitHub App configuration — a repo installed + there is reviewed by gittensory's own cloud Worker and its own database. + "Self-host" means your own container from{" "} + Quickstart, with its own GitHub App (or + brokered Orb enrollment) and its own data store. There is{" "} + no automated migration path between the two today — moving a repo is a + manual App swap plus re-creating whatever settings you had, not a toggle. +

+ +

Switching a repo from hosted to self-host

+
    +
  1. + Stand up your self-host instance first and confirm /ready is healthy — see{" "} + Quickstart — before touching the hosted + install, so the repo is never briefly reviewed by nothing. +
  2. +
  3. + Create your own GitHub App via the self-host{" "} + setup wizard (or brokered Orb enrollment). + You cannot repoint the existing shared hosted App at your self-host container — the shared + App's credentials belong to gittensory's cloud Worker, and{" "} + src/selfhost/setup-wizard.ts always mints a distinct App tied to your + instance's own webhook URL. +
  4. +
  5. + Install your new self-host App on the repo, choosing only that repo (or the org, if you're + migrating several at once). +
  6. +
  7. + Uninstall the shared hosted App from that repo (repo Settings → Integrations → GitHub Apps + → gittensory → Uninstall, or the equivalent org-level App settings page) once you've + confirmed the self-host App is reviewing PRs correctly. Leaving both installed means two + reviewers post competing checks and comments on the same PRs. +
  8. +
+ +

What does not carry over automatically

+

+ Hosted-side settings live in gittensory's own cloud database, keyed by repo full name —{" "} + resolveRepositorySettings (src/settings/repository-settings.ts) + reads them from env.DB, which is a completely different database instance than + your self-host container's. A self-host instance has no access to, and no import path + for, whatever thresholds, gate modes, or review-mode settings you configured on the hosted + side through the control panel or API. If you want the same behavior, you have to + re-configure it on the new instance from scratch — there is no export/import tool for this + today. +

+

+ + One thing genuinely does carry over: a repo's own .gittensory.yml + {" "} + (config-as-code), because it lives in the repository's git history, not in either + service's database. resolveRepositorySettings overlays it on top of + whatever DB settings exist, on either hosted or self-host — so gate-mode overrides, + thresholds, and other settings expressed in that file apply identically the moment the new + App starts reviewing, with nothing to re-enter. +

+ + Past review comments, check-run history, and any per-PR state gittensory recorded while the + hosted App was active stay wherever they were created — GitHub comments and check runs are + never deleted or copied by an uninstall/install, but nothing in the self-host database is + backfilled from the hosted side. A migrated repo starts its self-host review history from + zero. + +

+ What stays identical for contributors either way: the review still posts as a{" "} + gittensory[bot]-style comment (under your own App's slug once you migrate, + not literally gittensory[bot]) plus the same check-run shape, and the gate + semantics in Tuning your reviews and{" "} + How reviews work are unchanged — only the + infrastructure and the settings storage location differ. +

+ +

Switching a repo from self-host back to hosted

+

+ The reverse migration has the same shape and the same gap: uninstall your self-host App from + the repo, install the shared hosted App (if you have managed-beta access — see{" "} + GitHub App configuration), and re-create any DB-backed + settings on the hosted side. .gittensory.yml again carries over for free since + it travels with the repo; nothing else does. Your self-host instance's data volumes are + untouched by this — see{" "} + Uninstalling and decommissioning if you also + intend to shut the instance down rather than keep it idle or reuse it for other repos. +

); } diff --git a/apps/gittensory-ui/src/routes/docs.self-hosting-operations.tsx b/apps/gittensory-ui/src/routes/docs.self-hosting-operations.tsx index 7800038b54..285e07b5f9 100644 --- a/apps/gittensory-ui/src/routes/docs.self-hosting-operations.tsx +++ b/apps/gittensory-ui/src/routes/docs.self-hosting-operations.tsx @@ -10,13 +10,13 @@ export const Route = createFileRoute("/docs/self-hosting-operations")({ { name: "description", content: - "Operate the self-hosted Gittensory review service: readiness, metrics, logs, dashboards, jobs, queues, routine checks, and safe updates/rollback.", + "Operate the self-hosted Gittensory review service: readiness, metrics, logs, dashboards, jobs, queues, routine checks, safe updates/rollback, and clean uninstall/decommissioning.", }, { property: "og:title", content: "Self-host operations — Gittensory docs" }, { property: "og:description", content: - "Operate the self-hosted Gittensory review service: readiness, metrics, logs, dashboards, jobs, queues, routine checks, and safe updates/rollback.", + "Operate the self-hosted Gittensory review service: readiness, metrics, logs, dashboards, jobs, queues, routine checks, safe updates/rollback, and clean uninstall/decommissioning.", }, { property: "og:url", content: "/docs/self-hosting-operations" }, ], @@ -610,6 +610,117 @@ docker inspect --format '{{.Config.Image}}' "$(docker compose ps -q gittensory)" If an operating check fails, go to{" "} Self-host troubleshooting.

+ +

Uninstalling and decommissioning

+

+ Tearing an instance down cleanly touches four independent things: the GitHub App + installation, the data volumes, brokered-mode enrollment, and control-panel access. None of + this is scripted today — do each step deliberately, in this order, and decide what to keep + before you delete anything. +

+ +

1. Revoke the GitHub App installation

+

+ Uninstalling stops GitHub from sending any further webhook events and immediately revokes + the App's installation tokens — nothing on the self-host side needs to be told; there + is no installation deleted webhook handler to run first. From the + repo or org: Settings → Integrations → GitHub Apps → your App → Uninstall. Do this before + stopping the container so you are not left with a dangling install pointed at a dead webhook + URL. +

+

+ If you only want to pause reviews without losing the App's configuration (permissions, + webhook URL, private key), suspend the installation instead of uninstalling it — GitHub + stops delivering events to a suspended install but keeps everything else intact for a later + resume. +

+ +

2. Decide what happens to the data volumes

+

+ Stopping the container does not delete anything — docker compose stop or{" "} + docker compose down (without -v) leaves every named volume ( + gittensory-data, gittensory-pg, qdrant-data,{" "} + gittensory-backups, grafana-data, and the rest declared in{" "} + docker-compose.yml) on disk, along with the ./gittensory-config{" "} + host directory (a bind mount, not a named volume, so it is never affected by -v{" "} + either way). Pick one: +

+ + + If you have not exported a backup off-host first, docker compose down -v{" "} + permanently destroys review history, settings, and the vector index with no recovery path — + the volumes are the only copy. See{" "} + Backup and scaling before running it on + an instance you care about. + + +

3. Deregister from the Orb broker (brokered mode only)

+

+ If this instance runs in brokered mode (ORB_ENROLLMENT_SECRET is set — see{" "} + GitHub App and Orb), be aware there is{" "} + no self-service revocation endpoint today — the "Minimum broker + safeguards" checklist on that page lists a revocation path as a prerequisite for a + public brokered rollout that has not shipped yet. An enrollment record ( + orb_enrollments) lives in gittensory's own central database, not your + container, and nothing in this codebase writes a revoked_at value to it outside + of tests. Practical steps until that exists: +

+ + +

4. Remove ADMIN_GITHUB_LOGINS access

+

+ ADMIN_GITHUB_LOGINS is read fresh from the environment on every control-panel + request (isAuthorizedGitHubSessionLogin in src/auth/security.ts) — + it is never cached at startup or baked into an issued session. To remove someone's + operator access, delete their login from the comma/whitespace-separated list in{" "} + .env and restart the gittensory service so the process picks up + the new value: +

+ +

+ This takes effect on their very next control-panel request after the restart — no signed-in + session is grandfathered in, because authorization is re-checked against the current + allowlist every time, not read from the session itself. If you are decommissioning the whole + instance rather than removing one operator, this step is moot once the container is stopped. +

); }