Repository navigation
fix(gitops): repository identity and complete repository listing - #104
Merged
Merged
Conversation
…gured provider Butler holds one Git provider per install, but two code paths ignored it. Enabling GitOps on a cluster recorded the repository as https://github.com/<owner>/<repo> regardless of which provider was configured, so a GitLab install stored GitHub URLs for every cluster it bootstrapped. The console reads that field in preference to the live Flux source, so operators were shown the wrong Git host. The URL is now derived from the configured provider, covering public GitHub, GitHub Enterprise (whose API URL carries an /api/v3 suffix), GitLab SaaS and self-hosted GitLab. The addon and release export paths parsed the stored URL by taking its last two path segments. That silently rewrote a nested GitLab group path such as group/subgroup/service/repo into subgroup/repo, addressing a project that usually does not exist. Resolution now preserves the full path, which is the project ID the GitLab API expects. Export also used the stored repository URL together with the globally configured provider client, with no check that the two agreed. When a repository is hosted somewhere other than the configured provider, Butler now refuses instead of addressing the same path on the configured host: that path is either absent or belongs to somebody else. This matters while a platform is moving between providers, when some clusters are still backed by the old host. Cluster lifecycle and Flux reconciliation are untouched; neither reads this configuration.
atbagan
force-pushed
the
fix/git-provider-authority
branch
from
August 31, 2026 13:59
e60ec78 to
75e09b3
Compare
Repository listing walked pages correctly but returned early once it had collected 200 entries, mid page. A caller could not tell that short list from a complete one, so an operator configuring a group with more than 200 projects was shown a silently truncated set and the repositories missing from it simply looked absent. On a group with 272 projects the listing returned 200. The cap is removed for both providers. The walk now continues until the provider reports no next page. A page bound remains as a guard against a looping or pathological response, but exceeding it returns RepositoryListTooLargeError rather than a partial list, on the same principle: a short answer that looks complete is worse than a clear failure. An error on any page already aborted the whole listing and still does. Page size and the bound move to shared constants, since both providers page the same way. Tests drive a fake GitLab that serves the real pagination headers, covering empty, single, sub page, exact page size, one over, the old cap, one over the old cap, the 272 case this was found on, and a thousand, plus a mid walk failure that must not yield a truncated result.
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.
Three Git provider correctness defects, all in the same area.
Recorded repository URL was hardcoded to github.com
EnableGitOpsandEnableManagementGitOpsstoredhttps://github.com/<owner>/<repo>for the cluster regardless of the configured provider, so a GitLab install recorded GitHub URLs for every cluster it bootstrapped.GetStatusprefers that stored field over the live FluxGitRepository, so the console showed the wrong Git host.ProviderWebBaseURLandRepositoryWebURLderive the URL from the configured provider, handling that the GitHub API URL is not the web host (https://api.github.com, and/api/v3for Enterprise) while the GitLab URL is the instance itself.Export truncated nested group paths and could cross hosts
The addon and release export paths parsed the stored URL by taking its last two path segments, rewriting
group/subgroup/service/repointosubgroup/repo. On GitLab the project ID is the full path, so export addressed a project that usually does not exist.Export also combined a stored repository URL with the globally configured provider client without checking the two agreed.
ResolveRepoForProviderpreserves the full path and returns a typedProviderHostMismatchErrorwhen the stored repository is hosted somewhere other than the configured provider. Butler refuses rather than addressing the same path on the configured host: that path is either absent or belongs to somebody else. This matters while a platform moves between providers and some clusters are still backed by the old host.parseGitHubURLis removed.Repository listing stopped at 200
Listing walked pages correctly but returned early once it had collected 200 entries, mid page. A caller could not distinguish that from a complete list, so a group with more than 200 projects appeared to contain 200 and the rest looked absent.
The cap is removed for both providers. The walk continues until the provider reports no next page. A page bound remains as a guard, but exceeding it returns
RepositoryListTooLargeErrorrather than a partial list.Scope
No change to cluster lifecycle or Flux reconciliation; neither reads this configuration. No change to the single provider per install model, and no change to how
EnableGitOpsbootstraps Flux.Tests
Provider URL handling across public GitHub, GitHub Enterprise, GitLab SaaS, self hosted GitLab, nested groups, scp style remotes, malformed and unsupported providers. Pagination against a fake GitLab serving real pagination headers: empty, single, sub page, exact page size, one over, 200, 201, 272, 1000, and a mid walk failure that must not yield a truncated result. Full suite passes.