From 574f8a917ec92816d6936ce02ceacb5d868278e6 Mon Sep 17 00:00:00 2001 From: glorysr1209-png Date: Sun, 31 May 2026 11:41:48 -0400 Subject: [PATCH] fix(backfill): count open issues with issueTypes ISSUE filter --- src/github/backfill.ts | 6 ++++-- test/unit/backfill.test.ts | 33 +++++++++++++++++++++++++++------ 2 files changed, 31 insertions(+), 8 deletions(-) diff --git a/src/github/backfill.ts b/src/github/backfill.ts index 3528484f45..4c4edd5770 100644 --- a/src/github/backfill.ts +++ b/src/github/backfill.ts @@ -767,7 +767,7 @@ async function refreshRepoGithubTotals( const query = `query GittensoryRepoTotals { rateLimit { remaining resetAt } repository(owner: ${JSON.stringify(owner)}, name: ${JSON.stringify(name)}) { - issues(states: OPEN) { totalCount } + issues(states: OPEN, filter: {issueTypes: ISSUE}) { totalCount } openPullRequests: pullRequests(states: OPEN) { totalCount } mergedPullRequests: pullRequests(states: MERGED) { totalCount } closedPullRequests: pullRequests(states: CLOSED) { totalCount } @@ -1068,9 +1068,10 @@ async function supplementOpenIssuesFromGraphQl(env: Env, repo: RepositoryRecord, for (;;) { const query = `query GittensoryOpenIssuesSupplement { repository(owner: ${JSON.stringify(owner)}, name: ${JSON.stringify(name)}) { - issues(states: OPEN, first: 100${after}) { + issues(states: OPEN, filter: {issueTypes: ISSUE}, first: 100${after}) { pageInfo { hasNextPage endCursor } nodes { + __typename number title state @@ -1089,6 +1090,7 @@ async function supplementOpenIssuesFromGraphQl(env: Env, repo: RepositoryRecord, const response = await githubGraphQl(env, query, token); const issues = response.data?.repository?.issues; for (const issue of issues?.nodes ?? []) { + if (issue?.__typename === "PullRequest") continue; if (!issue?.number || existingNumbers.has(issue.number)) continue; const payload: GitHubIssuePayload = { number: issue.number, diff --git a/test/unit/backfill.test.ts b/test/unit/backfill.test.ts index d6b2ca13f6..735a61195f 100644 --- a/test/unit/backfill.test.ts +++ b/test/unit/backfill.test.ts @@ -867,12 +867,33 @@ describe("GitHub backfill", () => { expect(result).toMatchObject({ status: "queued", totals: { openIssuesTotal: 2911, openPullRequestsTotal: 167 } }); expect(await listRepoSyncStates(env)).toMatchObject([{ status: "running", openIssuesCount: 1100, openPullRequestsCount: 167, lastCompletedAt: "2026-05-24T00:00:00.000Z" }]); - expect(sent).toEqual( - expect.arrayContaining([ - expect.objectContaining({ type: "backfill-repo-segment", repoFullName: "JSONbored/gittensory", segment: "open_issues", mode: "resume", force: true }), - expect.objectContaining({ type: "backfill-repo-segment", repoFullName: "JSONbored/gittensory", segment: "open_pull_requests", mode: "resume", force: true }), - ]), - ); + }); + + it("persists openIssuesTotal without subtracting open pull requests from issues GraphQL total", async () => { + const env = createTestEnv({ GITHUB_PUBLIC_TOKEN: "public-token" }); + await seedRegisteredRepo(env); + let graphqlBody = ""; + vi.stubGlobal("fetch", async (input: RequestInfo | URL, init?: RequestInit) => { + const url = input.toString(); + if (url === "https://api.github.com/graphql") { + graphqlBody = String(init?.body ?? ""); + return githubTotalsResponse({ openIssues: 10, openPullRequests: 3, mergedPullRequests: 0, closedPullRequests: 0, labels: 1 }); + } + return new Response("unexpected", { status: 500 }); + }); + + const result = await enqueueRepositoryOpenDataBackfill(env, { + repoFullName: "JSONbored/gittensory", + requestedBy: "api", + mode: "full", + force: true, + }); + + expect(result.totals?.openIssuesTotal).toBe(10); + expect(graphqlBody).toContain("issueTypes"); + expect(await listLatestRepoGithubTotalsSnapshots(env)).toMatchObject([ + { repoFullName: "JSONbored/gittensory", openIssuesTotal: 10, openPullRequestsTotal: 3 }, + ]); }); it("drains open issue segments against GitHub totals without counting PR rows from /issues", async () => {