You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Switch from callbacks to webhooks for repos (#2466)
* Agent task to move from callback to webhooks for repo syncing
* Move from callback to webhook for repos
* Add docs for local development
* Docs: UI as gateway for local dev; github app
* Not require code in callback
* Add retry logic to installation link fetching
- Move repo sync away from the OAuth callback and drive updates from GitHub webhooks.
5
+
- Keep Digger’s repo list accurate when repos are added/removed from the app scope.
6
+
- On uninstall, soft-delete repos (and their installation records) so they disappear from the UI/API.
7
+
8
+
## Current behavior (source of truth today)
9
+
- OAuth callback (`backend/controllers/github_callback.go`) validates the install, links/creates org, then lists all repos via `Apps.ListRepos`, soft-deletes existing `github_app_installations` and repos for the org, and recreates them via `GithubRepoAdded` + `createOrGetDiggerRepoForGithubRepo`.
10
+
- Webhook handler (`backend/controllers/github.go`) only uses `installation` events with action `deleted` to mark installation links inactive and set `github_app_installations` status deleted for the repos in the payload. It does not touch `repos`. There is no handling for `installation_repositories` add/remove.
11
+
- Runtime lookups (`GetGithubService` / `GetGithubClient`) require an active record in `github_app_installations` for the repo.
12
+
13
+
## Target design
14
+
- Keep OAuth callback minimal: verify installation, create/link org, store the install id/app id, but do **not** list or mutate repos. It should return immediately and rely on webhooks for repo population.
15
+
- Webhook-driven reconciliation:
16
+
-`installation` event (`created`, `unsuspended`, `new_permissions_accepted`): ensure installation link exists/active; reconcile repos using the payload’s `installation.repositories` list as authoritative. If the link is missing, log an error and return (no auto-create).
17
+
- Soft-delete existing `github_app_installations` for that installation id, and soft-delete repos for the linked org (scoped to that installation) before re-adding.
18
+
- Upsert each repo: mark/install via `GithubRepoAdded` and create/restore the Digger repo record (store app id, installation id, default branch, clone URL when available).
- For `repositories_added`: fetch repo details (to get default branch + clone URL), then call `GithubRepoAdded` and create/restore the repo record.
21
+
- For `repositories_removed`: mark `GithubRepoRemoved`, soft-delete the repo **and its projects**, and handle absence gracefully.
22
+
-`installation` event (`deleted`): mark installation link inactive, mark installation records deleted, and soft-delete repos **and projects** for that installation’s org so they no longer appear in APIs/UI.
23
+
- Shared helpers:
24
+
-`syncReposForInstallation(installationId, appId, reposPayload)` to wrap the add/remove logic and reuse between `installation` and `installation_repositories` handlers.
25
+
-`softDeleteRepoAndProjects(orgId, repoFullName)` to encapsulate repo + project soft-deletion.
26
+
- Observability: structured logs per action, and possibly a metric for sync success/failure per installation.
27
+
28
+
## Migration plan
29
+
1) Add webhook handling for `installation_repositories` in `GithubAppWebHook` switch and wire to a new handler.
30
+
2) Extend `installation` handling to cover `created`/`unsuspended` (not just `deleted`) and call `syncReposForInstallation`.
31
+
3) Update uninstall handling to also soft-delete repos and projects.
32
+
4) Strip repo enumeration/deletion from the OAuth callback; leave only installation/org linking.
33
+
5) Add tests using existing payload fixtures (`installationRepositoriesAddedPayload`, `installationRepositoriesDeletedPayload`, `installationCreatedEvent`) to verify DB state changes (installation records + repos soft-delete/restore).
34
+
6) Backfill existing installations: one-off job/command or admin endpoint to resync repos via `Apps.ListRepos` and `syncReposForInstallation` to align data after deploying (manual trigger, no cron yet).
35
+
36
+
## Testing / validation
37
+
- Unit tests for add/remove/uninstall flows verifying:
38
+
-`github_app_installations` status transitions.
39
+
- Repos are created/restored with correct installation/app ids.
40
+
- Repos and projects are soft-deleted on removal/uninstall.
41
+
42
+
## Open questions
43
+
- None right now (decided: log missing-link errors only; soft-delete repos and projects on removal/uninstall; add manual resync endpoint, no cron yet).
0 commit comments