Repository navigation
Resolve the git credential when each remote command runs - #2124
Merged
Merged
Conversation
ppXD
force-pushed
the
fix/resolve-the-git-credential-at-each-push
branch
from
October 18, 2026 11:20
79cdf48 to
707475b
Compare
ppXD
force-pushed
the
fix/show-build-and-credential-plumbing-health
branch
from
October 18, 2026 11:23
9412742 to
9c3a330
Compare
ppXD
changed the base branch from
fix/show-build-and-credential-plumbing-health
to
main
October 18, 2026 12:08
A run's workspace was provisioned with the access token resolved once at its start, and the end-of-run push, its LFS upload, the readback and every revise re-push reused that string. A GitLab OAuth access token lives two hours and is revoked the moment any caller refreshes it, while the refresher only refreshes under two minutes left, so a long run, or one whose credential a sibling run refreshed, pushed with a dead token. The push retried that token three times, the failure was swallowed into a Warning, and the run stayed Succeeded with no branch. WorkspaceRequest now names the repository and team its token was resolved for. The workspace provider asks a narrow IWorkspaceTokenSource for the credential immediately before each command that reaches the remote; the source re-resolves through the same resolver and provider auth layer that provisioned the clone, so it reads the credential as it stands now, refreshes it if due and adopts a pair a sibling stored. A request without a repository id, or a provider without a source, keeps the captured token exactly as before. A push the remote refuses is tried once more with a freshly resolved credential when that differs from the refused one. Refused again, or resolved to the same one, it ends as a typed GitCredentialRejected failure instead of presenting the same refusal a third time. The run keeps its Succeeded status, so every caller that reads Succeeded is unchanged; the failure is recorded on the run result (code and message), the publish manifest and the timeline. A contract that finds nothing to grade because of it now says credential-rejected, classed as infra, instead of no-branch-or-repo.
ppXD
force-pushed
the
fix/resolve-the-git-credential-at-each-push
branch
from
October 18, 2026 12:08
707475b to
420f458
Compare
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.
Summary
IWorkspaceTokenSourcebacked by the same resolver and provider-auth layer that provisioned the workspace. A GitLab OAuth access token lives two hours and is revoked the moment any caller refreshes it, so a token captured at run start was dead by the end-of-run push in long runs, or whenever a sibling run refreshed the credential.WorkspaceRequestgains additiveRepositoryId/TeamId(data only, in Messages). A request without a repository id, or a provider without a token source, keeps the captured token exactly as before.GitCredentialRejectedException(git.credential_rejected, not retried) instead of presenting the same refusal three times against the account.Succeededso every caller that reads that status is unchanged. The failure is recorded asPublishFailureCodeandPublishErroron the run result, in the publish manifest and on the timeline. A run whose acceptance contract finds nothing to grade because of it now fails closed with credential-rejected (infra) instead ofno-branch-or-repo.AgentRunExecutornow describe this behaviour: a refused credential is classified by the workspace provider and never retried, while otherWorkspaceExceptions still get the bounded blind retry.LocalWorkspaceHandletakes its collaborators as one privateHandleDependenciesrecord, so its constructor stays within five parameters.Test plan
LocalGitWorkspaceProviderCredentialTests,RepositoryWorkspaceTokenSourceTests,AgentRunExecutorPushTests,AgentRunExecutorAcceptanceTests,FailureTaxonomyTests(442 passed with the workspace slice)AgentRunExecutorand Sandbox suites (560 passed)RepositoryIdtakes the captured-token path unchanged; no migration; no env toggle; new fields are additive and nullable, so rolling deploy and rollback are safe