Skip to content

Commit 9e21caf

Browse files
raujaiswalazure-pipelines-bot
andauthored
Fix authentication failures for inherited partial clone repositories during checkout (#5294)
* Add promisor remote detection for partial clone authentication * Clean up excessive debug logging and verbose comments in GitSourceProvider * Enhance partial clone detection with comprehensive config checks and improved debug logging * Update partial clone detection * Add enhanced partial clone detection with new feature flag while preserving legacy behavior --------- Co-authored-by: azure-pipelines-bot <[email protected]>
1 parent 9f840a6 commit 9e21caf

File tree

2 files changed

+75
-1
lines changed

2 files changed

+75
-1
lines changed

src/Agent.Plugins/GitSourceProvider.cs

Lines changed: 68 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -799,7 +799,39 @@ public async Task GetSourceAsync(
799799
string args = ComposeGitArgs(executionContext, gitCommandManager, configKey, username, password, useBearerAuthType);
800800
additionalFetchArgs.Add(args);
801801

802-
if (additionalFetchFilterOptions.Any() && AgentKnobs.AddForceCredentialsToGitCheckout.GetValue(executionContext).AsBoolean())
802+
// Partial Clone Credential Handling:
803+
// Two feature flags control when credentials are added to git checkout for partial clones:
804+
// 1. AddForceCredentialsToGitCheckout (legacy): Only checks explicit fetch filters
805+
// 2. AddForceCredentialsToGitCheckoutEnhanced (new): Checks both explicit filters AND inherited partial clone config
806+
// The enhanced flag takes precedence when both are enabled.
807+
bool hasExplicitFetchFilter = additionalFetchFilterOptions.Any();
808+
bool forceCredentialsLegacyEnabled = AgentKnobs.AddForceCredentialsToGitCheckout.GetValue(executionContext).AsBoolean();
809+
bool forceCredentialsEnhancedEnabled = AgentKnobs.AddForceCredentialsToGitCheckoutEnhanced.GetValue(executionContext).AsBoolean();
810+
811+
bool shouldAddCredentials = false;
812+
813+
// Enhanced behavior takes precedence - checks both explicit filters and promisor remote configuration
814+
if (forceCredentialsEnhancedEnabled)
815+
{
816+
// Enhanced detection: check for inherited partial clone configuration via git config
817+
bool hasInheritedPartialCloneConfig = await IsPartialCloneRepository(executionContext, gitCommandManager, targetPath);
818+
executionContext.Debug($"Enhanced partial clone detection - ExplicitFilter: {hasExplicitFetchFilter}, InheritedConfig: {hasInheritedPartialCloneConfig}, ForceCredentialsEnhanced: {forceCredentialsEnhancedEnabled}");
819+
if (hasExplicitFetchFilter || hasInheritedPartialCloneConfig)
820+
{
821+
executionContext.Debug("Adding credentials to checkout due to enhanced partial clone detection");
822+
shouldAddCredentials = true;
823+
}
824+
}
825+
else if (forceCredentialsLegacyEnabled && hasExplicitFetchFilter)
826+
{
827+
// Legacy behavior: only check explicit fetch filter, used when enhanced flag is disabled
828+
executionContext.Debug($"Legacy partial clone detection - ExplicitFilter: {hasExplicitFetchFilter}, ForceCredentials: {forceCredentialsLegacyEnabled}");
829+
executionContext.Debug("Adding credentials to checkout due to explicit fetch filter and legacy force credentials knob");
830+
shouldAddCredentials = true;
831+
}
832+
833+
// Apply credentials to checkout if either feature flag condition was satisfied
834+
if (shouldAddCredentials)
803835
{
804836
additionalCheckoutArgs.Add(args);
805837
}
@@ -1530,6 +1562,41 @@ private IEnumerable<string> ParseFetchFilterOptions(AgentTaskPluginExecutionCont
15301562
return filters;
15311563
}
15321564

1565+
private async Task<bool> IsPartialCloneRepository(AgentTaskPluginExecutionContext executionContext, GitCliManager gitCommandManager, string targetPath)
1566+
{
1567+
try
1568+
{
1569+
// Skip check if .git directory doesn't exist (not a Git repository)
1570+
string gitDir = Path.Combine(targetPath, ".git");
1571+
if (!Directory.Exists(gitDir))
1572+
{
1573+
executionContext.Debug("Not a Git repository: .git directory does not exist");
1574+
return false;
1575+
}
1576+
1577+
// Check for promisor remote configuration (primary indicator)
1578+
if (await gitCommandManager.GitConfigExist(executionContext, targetPath, "remote.origin.promisor"))
1579+
{
1580+
executionContext.Debug("Detected partial clone: remote.origin.promisor exists");
1581+
return true;
1582+
}
1583+
1584+
// Check for partial clone filter configuration (secondary indicator)
1585+
if (await gitCommandManager.GitConfigExist(executionContext, targetPath, "remote.origin.partialclonefilter"))
1586+
{
1587+
executionContext.Debug("Detected partial clone: remote.origin.partialclonefilter exists");
1588+
return true;
1589+
}
1590+
return false;
1591+
}
1592+
catch (Exception ex)
1593+
{
1594+
// Default to false on detection failure to avoid breaking builds
1595+
executionContext.Debug($"Failed to detect partial clone state: {ex.Message}");
1596+
return false;
1597+
}
1598+
}
1599+
15331600
private async Task RunGitStatusIfSystemDebug(AgentTaskPluginExecutionContext executionContext, GitCliManager gitCommandManager, string targetPath)
15341601
{
15351602
if (executionContext.IsSystemDebugTrue())

src/Agent.Sdk/Knob/AgentKnobs.cs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -800,6 +800,13 @@ public class AgentKnobs
800800
new PipelineFeatureSource(nameof(AddForceCredentialsToGitCheckout)),
801801
new BuiltInDefaultKnobSource("false"));
802802

803+
public static readonly Knob AddForceCredentialsToGitCheckoutEnhanced = new Knob(
804+
nameof(AddForceCredentialsToGitCheckoutEnhanced),
805+
"If true, the credentials will be added to Git checkout for partial clones with enhanced detection including promisor remote config.",
806+
new RuntimeKnobSource("ADD_FORCE_CREDENTIALS_TO_GIT_CHECKOUT_ENHANCED"),
807+
new PipelineFeatureSource(nameof(AddForceCredentialsToGitCheckoutEnhanced)),
808+
new BuiltInDefaultKnobSource("false"));
809+
803810
public static readonly Knob InstallLegacyTfExe = new Knob(
804811
nameof(InstallLegacyTfExe),
805812
"If true, the agent will install the legacy versions of TF, vstsom and vstshost",

0 commit comments

Comments
 (0)