Skip to content

Use int64 for GitHub database IDs#13403

Open
williammartin wants to merge 5 commits into
trunkfrom
9247-ensure-the-cli-handles-github-database-ids-correctly
Open

Use int64 for GitHub database IDs#13403
williammartin wants to merge 5 commits into
trunkfrom
9247-ensure-the-cli-handles-github-database-ids-correctly

Conversation

@williammartin

@williammartin williammartin commented May 12, 2026

Copy link
Copy Markdown
Member

Use int64 for GitHub database IDs

Closes #9247

Problem

Several structs in the CLI use Go's int type for GitHub database ID fields. Go's int is platform-dependent and could be 32-bit on some architectures, while GitHub internally uses 64-bit integers for database IDs. The REST API OpenAPI spec explicitly declares many resource IDs as integer with format: int64 (e.g. repositories, GPG keys, SSH keys), and the GraphQL API has migrated some databaseId fields from Int to BigInt.

Changes

Updated all struct fields representing GitHub database IDs from int to int64, along with their downstream usage:

  • Codespaces: Repository.ID, CreateCodespaceParams.RepositoryID, startCreateRequest.RepositoryID, plus interface/mock/test cascading
  • Rulesets: RulesetGraphQL.DatabaseId, RulesetREST.Id, BypassActors.ActorId, RulesetRule.RulesetId, and the skills rulesetsResponse.ID
  • Keys: deployKey.ID, gpgKey.ID, sshKey.ID
  • Cache: Cache.Id, plus parseCacheID and deleteCacheByID (which still used int/strconv.Atoi)
  • Autolinks: Autolink.ID
  • Agent tasks: JobActor.ID, JobPullRequest.ID

All strconv.Itoa() calls on these fields were updated to strconv.FormatInt(x, 10).

GraphQL response structs were also audited - only RulesetGraphQL.DatabaseId needed updating. Others were already correct (GitHubUser.DatabaseID is int64, FullDatabaseID is string for GraphQL BigInt).

Future: Custom linter to prevent regressions

A custom go/analysis linter that flags struct fields with ID-like names or JSON tags still using int has been prototyped on a separate branch: 9247-idtype-linter. It's split out to keep this PR focused on the type changes. The linter correctly identifies all the violations fixed here.

Linter output BEFORE this PR (27 violations)
pkg/cmd/agent-task/capi/job.go:38:2: struct field ID looks like a GitHub database ID but uses int; use int64 instead
pkg/cmd/agent-task/capi/job.go:43:2: struct field ID looks like a GitHub database ID but uses int; use int64 instead
pkg/cmd/ssh-key/shared/user_keys.go:20:2: struct field ID looks like a GitHub database ID but uses int; use int64 instead
pkg/cmd/cache/shared/shared.go:25:2: struct field Id looks like a GitHub database ID but uses int; use int64 instead
internal/codespaces/api/api.go:153:2: struct field ID looks like a GitHub database ID but uses int; use int64 instead
internal/codespaces/api/api.go:807:2: struct field RepositoryID looks like a GitHub database ID but uses int; use int64 instead
internal/codespaces/api/api.go:858:2: struct field RepositoryID looks like a GitHub database ID but uses int; use int64 instead
pkg/cmd/codespace/mock_api.go:203:4: struct field RepoID looks like a GitHub database ID but uses int; use int64 instead
pkg/cmd/codespace/mock_api.go:216:4: struct field RepoID looks like a GitHub database ID but uses int; use int64 instead
pkg/cmd/codespace/mock_api.go:260:4: struct field RepoID looks like a GitHub database ID but uses int; use int64 instead
pkg/cmd/codespace/mock_api.go:591:3: struct field RepoID looks like a GitHub database ID but uses int; use int64 instead
pkg/cmd/codespace/mock_api.go:614:2: struct field RepoID looks like a GitHub database ID but uses int; use int64 instead
pkg/cmd/codespace/mock_api.go:621:3: struct field RepoID looks like a GitHub database ID but uses int; use int64 instead
pkg/cmd/codespace/mock_api.go:639:3: struct field RepoID looks like a GitHub database ID but uses int; use int64 instead
pkg/cmd/codespace/mock_api.go:660:2: struct field RepoID looks like a GitHub database ID but uses int; use int64 instead
pkg/cmd/codespace/mock_api.go:666:3: struct field RepoID looks like a GitHub database ID but uses int; use int64 instead
pkg/cmd/codespace/mock_api.go:858:3: struct field RepoID looks like a GitHub database ID but uses int; use int64 instead
pkg/cmd/codespace/mock_api.go:879:2: struct field RepoID looks like a GitHub database ID but uses int; use int64 instead
pkg/cmd/codespace/mock_api.go:885:3: struct field RepoID looks like a GitHub database ID but uses int; use int64 instead
pkg/cmd/gpg-key/delete/http.go:14:2: struct field ID looks like a GitHub database ID but uses int; use int64 instead
pkg/cmd/repo/autolink/shared/autolink.go:6:2: struct field ID looks like a GitHub database ID but uses int; use int64 instead
pkg/cmd/repo/deploy-key/list/http.go:16:2: struct field ID looks like a GitHub database ID but uses int; use int64 instead
pkg/cmd/ruleset/shared/shared.go:13:2: struct field DatabaseId looks like a GitHub database ID but uses int; use int64 instead
pkg/cmd/ruleset/shared/shared.go:27:2: struct field Id looks like a GitHub database ID but uses int; use int64 instead
pkg/cmd/ruleset/shared/shared.go:33:3: struct field ActorId looks like a GitHub database ID but uses int; use int64 instead
pkg/cmd/ruleset/shared/shared.go:53:2: struct field RulesetId looks like a GitHub database ID but uses int; use int64 instead
pkg/cmd/skills/publish/publish.go:67:2: struct field ID looks like a GitHub database ID but uses int; use int64 instead
Linter output AFTER this PR (0 violations)
(clean - no output)

Reviewer Notes

We should run A/C tests on this before merging.

@williammartin williammartin linked an issue May 12, 2026 that may be closed by this pull request
williammartin and others added 2 commits May 13, 2026 13:16
Change all struct fields representing GitHub database IDs from int to
int64 to match the API spec and prevent potential overflow on 32-bit
architectures.

Add a custom go/analysis linter (idtype-checker) that flags struct
fields with ID-like names or JSON tags using int instead of int64,
integrated into make lint.

Closes #9247

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The idtype linter directly imports golang.org/x/tools/go/analysis, so
go mod tidy correctly moves it from indirect to direct.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@williammartin williammartin force-pushed the 9247-ensure-the-cli-handles-github-database-ids-correctly branch from 4a447a9 to d120828 Compare May 13, 2026 11:18
@williammartin williammartin requested a review from Copilot May 13, 2026 15:11

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR standardizes GitHub database ID handling by migrating relevant struct fields from Go’s platform-dependent int to int64, and adds a custom go/analysis linter to prevent regressions.

Changes:

  • Updated multiple REST/GraphQL response/request structs to use int64 for GitHub database IDs (and adjusted downstream usages).
  • Replaced strconv.Itoa with strconv.FormatInt(..., 10) where IDs are stringified.
  • Added an idtype analyzer + idtype-checker command, and wired it into make lint.
Show a summary per file
File Description
pkg/linter/idtype/testdata/src/example/example.go Analyzer test fixture covering flagged and non-flagged ID patterns.
pkg/linter/idtype/analyzer.go New go/analysis analyzer that reports int-typed ID-like struct fields.
pkg/linter/idtype/analyzer_test.go Runs the analyzer against analysistest testdata.
cmd/idtype-checker/main.go singlechecker entrypoint for running the analyzer in lint.
Makefile Adds idtype-checker execution to the lint target.
go.mod Promotes golang.org/x/tools to a direct dependency for the analyzer tooling.
pkg/cmd/ssh-key/shared/user_keys.go Switches SSH key ID field to int64.
pkg/cmd/ssh-key/list/list.go Uses FormatInt for SSH key ID display.
pkg/cmd/skills/publish/publish.go Switches rulesets API response ID field to int64.
pkg/cmd/ruleset/shared/shared.go Switches ruleset-related ID fields (GraphQL/REST) to int64.
pkg/cmd/ruleset/list/list.go Uses FormatInt for ruleset ID display.
pkg/cmd/ruleset/view/view.go Uses FormatInt for ruleset IDs (both selected and displayed).
pkg/cmd/repo/deploy-key/list/http.go Switches deploy key ID field to int64.
pkg/cmd/repo/deploy-key/list/list.go Uses FormatInt for deploy key ID display.
pkg/cmd/repo/autolink/shared/autolink.go Switches autolink ID field to int64.
pkg/cmd/gpg-key/delete/http.go Switches GPG key ID field to int64.
pkg/cmd/gpg-key/delete/delete.go Uses FormatInt for selected GPG key ID.
pkg/cmd/cache/shared/shared.go Switches cache ID field to int64.
pkg/cmd/cache/delete/delete.go Uses FormatInt when collecting cache IDs to delete.
pkg/cmd/agent-task/capi/job.go Switches agent-task actor/PR ID fields to int64.
internal/codespaces/api/api.go Switches codespaces repository/request IDs and related method params to int64.
pkg/cmd/codespace/common.go Updates codespaces API client interface method signatures to use int64 repo IDs.
pkg/cmd/codespace/create.go Updates helper signature to accept int64 repo IDs.
pkg/cmd/codespace/create_test.go Updates mock signatures to match int64 repo ID APIs.
pkg/cmd/codespace/mock_api.go Updates generated mock types/signatures and call capture fields to int64.

Copilot's findings

Tip

Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Files not reviewed (1)
  • pkg/cmd/codespace/mock_api.go: Language not supported
  • Files reviewed: 24/25 changed files
  • Comments generated: 1

Comment thread pkg/linter/idtype/analyzer.go Outdated
williammartin and others added 3 commits May 13, 2026 17:31
Replace manual string manipulation with strconv.Unquote and
reflect.StructTag.Lookup to correctly parse both raw (backtick) and
interpreted (double-quoted) struct tag literals. The previous
implementation silently missed ID fields when tags used interpreted
string literals with escape sequences.

Add test cases with interpreted string literal tags using non-ID field
names to isolate coverage of the JSON tag parsing path.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The idtype linter has been moved to the 9247-idtype-linter branch
for separate review.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
These functions still used int/strconv.Atoi, which would silently
truncate cache IDs larger than 2^31-1 on 32-bit systems.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot's findings

Files not reviewed (1)
  • pkg/cmd/codespace/mock_api.go: Language not supported
  • Files reviewed: 18/19 changed files
  • Comments generated: 0 new

@williammartin williammartin marked this pull request as ready for review May 13, 2026 16:22
@williammartin williammartin requested review from a team as code owners May 13, 2026 16:22
@williammartin williammartin requested a review from BagToad May 13, 2026 16:23

@SamMorrowDrums SamMorrowDrums left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approving skills part, and 100% agree generally

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Ensure the CLI handles GitHub database IDs correctly

3 participants