feat: GraphQL diff-shape fetch — per-PR file stats without patch content (GitHub + GitLab) (#49) - #61
Merged
Merged
Conversation
Add per-PR diff shape (FileStat) via GraphQL to both platform adapters,
with extension reduction, wire-honesty golden files, degradation tests,
and cross-adapter parity fixtures.
Provider layer (provider/provider.go):
- FileStat{Ext, Additions, Deletions} with no path field (type-level
privacy guarantee)
- ErrDiffShapeUnsupported sentinel error
- DiffShapeFetcher optional interface
Extension reduction (provider/github/ext.go, provider/gitlab/ext.go):
- Adapter-internal: basename last-dot substring, lowercased, no leading
dot; empty for dotless, dot-starting, or dot-ending basenames
- Table test covers: Main.GO->go, service.test.ts->ts, Makefile->'',
.gitignore->'', archive.tar.gz->gz, noext.->''
GitHub adapter (provider/github/github.go):
- GraphQL pullRequest.files { nodes { path additions deletions } }
with cursored pagination (first: 100)
- Multi-page fixture exercising pagination
- Query golden and forbidden-content-field checks
- Path containment: internal/secret-project/service.go in fixture but
never reaches output
- Degradation: 401/404/GraphQL errors -> ErrDiffShapeUnsupported
GitLab adapter (provider/gitlab/gitlab.go):
- GraphQL mergeRequest.diffStats { path additions deletions }
(flat list, no pagination needed)
- Same golden, containment, and degradation patterns
Parity (provider/parity_test.go):
- Equivalent GitHub and GitLab fixtures produce identical FileStat
slices across adapters
All existing provider tests pass unchanged.
Files changed:
provider/provider.go +22 (types + sentinel + interface)
provider/github/github.go +142 (query + FetchDiffShape + postGraphQL)
provider/github/ext.go +31 (extension reduction)
provider/github/ext_test.go +31 (extension table test)
provider/github/query_test.go +37 (golden match + content check)
provider/github/diffshape_test.go +247 (integration tests)
provider/github/testdata/graphql_files_page1.json (fixture)
provider/github/testdata/graphql_files_page2.json (fixture)
provider/github/testdata/graphql_files_query.golden (golden query)
provider/gitlab/gitlab.go +124 (query + FetchDiffShape + postGraphQL)
provider/gitlab/ext.go +31 (extension reduction)
provider/gitlab/ext_test.go +31 (extension table test)
provider/gitlab/query_test.go +37 (golden match + content check)
provider/gitlab/diffshape_test.go +237 (integration tests)
provider/gitlab/testdata/graphql_diffstats.json (fixture)
provider/gitlab/testdata/graphql_diffstats_query.golden (golden query)
provider/parity_test.go +55 (diff shape parity test)
provider/testdata/parity_github_diffshape_page1.json (parity fixture)
provider/testdata/parity_github_diffshape_page2.json (parity fixture)
provider/testdata/parity_gitlab_diffshape.json (parity fixture)
Co-Authored-By: Claude <noreply@anthropic.com>
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.
Closes #49
Implemented by the autonomous loop (DA: deepseek/deepseek-v4-flash). The orchestrator's own in-container gate check failed spuriously across all 3 rounds due to an environment bug (the sandbox image's Go toolchain wasn't on PATH for a login shell, unrelated to this code — now fixed), so this never reached the QAA review round through the normal pipeline. I independently verified it directly:
go test ./...,go vet ./...,gofmt -l .all pass cleanly, both on host and via the corrected sandbox image.provider/github,provider/gitlab,provider/testdata), plus one incidental, harmless gofmt whitespace fix inrender/charts_test.gooutside it.provider/provider.go(the shared file) only addsFileStat,ErrDiffShapeUnsupported, and the optionalDiffShapeFetcherinterface - no changes to any existing type or method.