MUL-5265: GitHub API-snapshot PR cards — CI status + mergeability#5889
Merged
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
…265) Fetch each linked PR's CI checks and mergeability from the GitHub GraphQL API as the single source of truth (Plan C). Webhooks, page visits and a bounded TTL sweep are refresh triggers only; nothing is inferred from webhook payloads anymore. Backend (server/internal/integrations/ghsnapshot): - installation-token cache + GraphQL client (private key / tokens never logged) - one paginated pullRequest query -> normalized per-check snapshot - outbound queue: (installation,repo,PR) dedup + single in-flight per PR, bounded worker pool, Retry-After / rate-limit backoff, jitter - head-SHA-guarded atomic batch replace (a slow response for an old head can never overwrite a newer head's snapshot) - bounded chase window (30s->5m, stops on terminal/closed) + page-visit + TTL refresh; clean degradation when no App private key is configured Removes the old suite-level webhook aggregation display path (query + handlers + tests). check_suite / check_run / status are now pure triggers. Frontend: PR card shows two independent tri-state elements (CI status + mergeability). "Ready to merge" only when merge state is clean; no-checks and unknown-mergeable never assert a positive verdict; progress strip removed; four locales; stale marker. Docs: github-integration + environment-variables (four languages) — now required App private key, read-only Checks/Commit-statuses permissions, new event subscriptions, capability boundaries and troubleshooting. Co-authored-by: multica-agent <github@multica.ai>
Co-authored-by: multica-agent <github@multica.ai>
Bohan-J
force-pushed
the
agent/j/c94b5693
branch
from
July 24, 2026 09:10
3c34e69 to
58fd43b
Compare
Co-authored-by: multica-agent <github@multica.ai>
…n mint Address Elon's third-round review on the MUL-5265 PR snapshot pipeline. Must-fix — migration built a non-concurrent index. The github_pull_request_check_run table declared PRIMARY KEY (pr_id, ordinal) inside CREATE TABLE, which builds a unique index synchronously and violates the repo rule that every migration-created index (including on a new table) use CREATE UNIQUE INDEX CONCURRENTLY in its own single-statement file. Split: 222 now creates the table without a primary key; new 223 adds the (pr_id, ordinal) unique index CONCURRENTLY. The atomic delete-all/insert write path already guarantees ordinal uniqueness, so a plain unique index is sufficient; the index also serves the pr_id-prefix list aggregation and the workspace/PR cleanup deletes. Nit — token mint now singleflights per installation. installationToken released the lock before minting, so the N workers of one installation could mint N tokens on a cold cache or a simultaneous renew. Concurrent callers for the same installation are now collapsed via singleflight into one HTTP mint; added a -race concurrent-mint test asserting a single mint under 16 callers. Verified: fresh DB migrates through 223 (table has no PK, concurrent unique index present); ghsnapshot suite + new test pass under -race; migration lint and handler github/workspace-delete tests pass; sqlc produced no diff; go build / vet / gofmt / git diff --check clean. Co-authored-by: multica-agent <github@multica.ai>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Implements MUL-5265 — PR cards now show two independent, honest facts, each tri-state, sourced from the GitHub API as the single source of truth (Plan C, decided in MUL-5180). Webhooks, page visits and a bounded TTL sweep are refresh triggers only; nothing is inferred from webhook payloads anymore. Builds on clean
mainafter the #5855 revert and removes the old suite-level aggregation display path.Architecture
server/internal/integrations/ghsnapshot/pullRequestGraphQL query (cost 1):headRefOid,mergeable,mergeStateStatus,statusCheckRollup+ every check/status context. Contexts are paginated and CheckRun/StatusContext are normalized into one per-check shape.(installation, repo, PR)dedup + single in-flight per PR, bounded worker pool,Retry-After/rate-limit backoff, jitter; the head-SHA-guarded atomic batch replace; the bounded chase window; page-visit + TTL sweep triggers.Snapshot is stored as an atomic batch replace per PR (guarded UPDATE of
github_pull_requestsnapshot columns + full DELETE/INSERT ofgithub_pull_request_check_run) in one transaction.ListPullRequestsByIssuenow aggregates the run-level snapshot; the oldcheck_suitewrite path, its queries and its tests are removed (check_suite/check_run/statuswebhooks are now pure triggers).Acceptance criteria
UpdateGitHubPRSnapshot ... WHERE head_sha=$head;TestApplySnapshotHeadSHAGuard(DB)FetchPRSnapshotcursor loop;TestFetchPRSnapshotPaginatesContextsManager.Enqueue/process;TestEnqueueCoalesces,TestProcessRateLimitedSetsPause,TestGraphQLRateLimited,TestRateLimitFromResponseTestManagerDisabledNoOps,TestNewClientFromEnvstatusCheckRollup=null≠ passed;mergeable=UNKNOWNshows neitherderiveChecksStatus/deriveMergeStatus;TestFetchPRSnapshotNullRollup,TestSnapshotDecided+ frontend testsTestNewClientFromEnvmaxChaseAttempts, terminal-stop;TestScheduleChaseBoundedCLEANpull-request-status+pull-request-listtestsUI
Two independent elements shown only for open/draft PRs: CI (✓ all passed with count / ✗ N failed · names / ● x/y running / ○ no checks yet) and mergeability (✓ ready to merge — only when merge state is clean / ⚠ has conflicts / ⊘ blocked·behind·unstable). Progress strip removed. Stale snapshots grey out with a time hint. Four locales.
Verification
go build ./...,go vet,gofmtclean;ghsnapshotsuite (incl. DB-backed head-SHA guard) and handler GitHub tests pass on a freshly-migrated DB.@multica/core1032 and@multica/views2941 tests pass;pnpm typecheckfor core+views passes.@multica/docsMDX compiles for all four locales (the onlynext buildfailure is the pre-existing, content-unrelated/404prerender).Deploy / config (operator action)
Requires a GitHub App private key in the server env (
GITHUB_APP_ID+GITHUB_APP_PRIVATE_KEY) and read-only Pull requests + Checks + Commit statuses permissions, subscribed to Pull request, Check suite, Check run, Status. Each existing installation must approve the added permissions. Without the key the feature degrades off (card hides the CI/merge region); PR linking and merge→Done are unaffected. Docs updated in all four languages.