From 713c95148014d534a929cf975a401afacf1d8f80 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 30 Oct 2025 14:36:12 +0000 Subject: [PATCH 1/3] Initial plan From aeb45f67d5cbc05250257b27dda2297145128e26 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 30 Oct 2025 14:45:51 +0000 Subject: [PATCH 2/3] Add GitHub Copilot environment detection to auto-disable git engine Co-authored-by: AArnott <3548+AArnott@users.noreply.github.com> --- src/NerdBank.GitVersioning/GitContext.cs | 21 +++- .../GitContextTests.cs | 100 +++++++++++++++++- 2 files changed, 115 insertions(+), 6 deletions(-) diff --git a/src/NerdBank.GitVersioning/GitContext.cs b/src/NerdBank.GitVersioning/GitContext.cs index 5c1970485..74601ae43 100644 --- a/src/NerdBank.GitVersioning/GitContext.cs +++ b/src/NerdBank.GitVersioning/GitContext.cs @@ -134,7 +134,7 @@ public string RepoRelativeProjectDirectory protected string? DotGitPath { get; } /// - /// Gets the effective git engine to use, taking into account automatic disabling for Dependabot. + /// Gets the effective git engine to use, taking into account automatic disabling for Dependabot and GitHub Copilot. /// This overload checks the NBGV_GitEngine environment variable and parses it automatically. /// /// The engine to use if no environment variables dictate otherwise. @@ -144,11 +144,12 @@ public string RepoRelativeProjectDirectory /// Valid values are "LibGit2", "Managed", and "Disabled" (case-sensitive). /// Unrecognized values are treated as if the variable was not set, maintaining backward compatibility. /// Otherwise, if the DEPENDABOT environment variable is set to "true" (case-insensitive), returns . + /// Otherwise, if the GITHUB_ACTOR environment variable is set to "copilot-swe-agent[bot]", returns . /// Otherwise, returns . /// public static Engine GetEffectiveGitEngine(Engine defaultEngine = Engine.ReadOnly) { - // If NBGV_GitEngine is set, respect that setting regardless of Dependabot + // If NBGV_GitEngine is set, respect that setting regardless of Dependabot or GitHub Copilot string? nbgvGitEngine = Environment.GetEnvironmentVariable("NBGV_GitEngine"); if (!string.IsNullOrEmpty(nbgvGitEngine)) { @@ -177,6 +178,12 @@ public static Engine GetEffectiveGitEngine(Engine defaultEngine = Engine.ReadOnl return Engine.Disabled; } + // If we're in a GitHub Copilot environment and NBGV_GitEngine is not set, automatically disable the git engine + if (IsGitHubCopilotEnvironment()) + { + return Engine.Disabled; + } + // Otherwise, use the default engine return defaultEngine; } @@ -398,4 +405,14 @@ private static bool IsDependabotEnvironment() string? dependabotEnvVar = Environment.GetEnvironmentVariable("DEPENDABOT"); return string.Equals(dependabotEnvVar, "true", StringComparison.OrdinalIgnoreCase); } + + /// + /// Determines whether the current environment is running under GitHub Copilot. + /// + /// if GITHUB_ACTOR environment variable is set to "copilot-swe-agent[bot]"; otherwise, . + private static bool IsGitHubCopilotEnvironment() + { + string? githubActorEnvVar = Environment.GetEnvironmentVariable("GITHUB_ACTOR"); + return string.Equals(githubActorEnvVar, "copilot-swe-agent[bot]", StringComparison.Ordinal); + } } diff --git a/test/Nerdbank.GitVersioning.Tests/GitContextTests.cs b/test/Nerdbank.GitVersioning.Tests/GitContextTests.cs index 9ba37e6a3..319e6b32d 100644 --- a/test/Nerdbank.GitVersioning.Tests/GitContextTests.cs +++ b/test/Nerdbank.GitVersioning.Tests/GitContextTests.cs @@ -193,13 +193,15 @@ public void HeadCanonicalName_PackedHead() [Fact] public void GetEffectiveGitEngine_DefaultBehavior() { - // Arrange: Clear both environment variables + // Arrange: Clear all environment variables var originalDependabot = Environment.GetEnvironmentVariable("DEPENDABOT"); var originalNbgvGitEngine = Environment.GetEnvironmentVariable("NBGV_GitEngine"); + var originalGitHubActor = Environment.GetEnvironmentVariable("GITHUB_ACTOR"); try { Environment.SetEnvironmentVariable("DEPENDABOT", null); Environment.SetEnvironmentVariable("NBGV_GitEngine", null); + Environment.SetEnvironmentVariable("GITHUB_ACTOR", null); // Act & Assert: With no environment variables, should return default ReadOnly Assert.Equal(GitContext.Engine.ReadOnly, GitContext.GetEffectiveGitEngine()); @@ -209,6 +211,7 @@ public void GetEffectiveGitEngine_DefaultBehavior() { Environment.SetEnvironmentVariable("DEPENDABOT", originalDependabot); Environment.SetEnvironmentVariable("NBGV_GitEngine", originalNbgvGitEngine); + Environment.SetEnvironmentVariable("GITHUB_ACTOR", originalGitHubActor); } } @@ -218,13 +221,15 @@ public void GetEffectiveGitEngine_DefaultBehavior() [InlineData("True")] public void GetEffectiveGitEngine_DependabotEnvironment_DisablesEngine(string dependabotValue) { - // Arrange: Set DEPENDABOT=true and clear NBGV_GitEngine + // Arrange: Set DEPENDABOT=true and clear NBGV_GitEngine and GITHUB_ACTOR var originalDependabot = Environment.GetEnvironmentVariable("DEPENDABOT"); var originalNbgvGitEngine = Environment.GetEnvironmentVariable("NBGV_GitEngine"); + var originalGitHubActor = Environment.GetEnvironmentVariable("GITHUB_ACTOR"); try { Environment.SetEnvironmentVariable("DEPENDABOT", dependabotValue); Environment.SetEnvironmentVariable("NBGV_GitEngine", null); + Environment.SetEnvironmentVariable("GITHUB_ACTOR", null); // Act & Assert: Should return Disabled regardless of requested engine Assert.Equal(GitContext.Engine.Disabled, GitContext.GetEffectiveGitEngine()); @@ -235,6 +240,7 @@ public void GetEffectiveGitEngine_DependabotEnvironment_DisablesEngine(string de { Environment.SetEnvironmentVariable("DEPENDABOT", originalDependabot); Environment.SetEnvironmentVariable("NBGV_GitEngine", originalNbgvGitEngine); + Environment.SetEnvironmentVariable("GITHUB_ACTOR", originalGitHubActor); } } @@ -245,13 +251,15 @@ public void GetEffectiveGitEngine_DependabotEnvironment_DisablesEngine(string de [InlineData("")] public void GetEffectiveGitEngine_DependabotNotTrue_UsesDefault(string dependabotValue) { - // Arrange: Set DEPENDABOT to non-true value and clear NBGV_GitEngine + // Arrange: Set DEPENDABOT to non-true value and clear NBGV_GitEngine and GITHUB_ACTOR var originalDependabot = Environment.GetEnvironmentVariable("DEPENDABOT"); var originalNbgvGitEngine = Environment.GetEnvironmentVariable("NBGV_GitEngine"); + var originalGitHubActor = Environment.GetEnvironmentVariable("GITHUB_ACTOR"); try { Environment.SetEnvironmentVariable("DEPENDABOT", dependabotValue); Environment.SetEnvironmentVariable("NBGV_GitEngine", null); + Environment.SetEnvironmentVariable("GITHUB_ACTOR", null); // Act & Assert: Should use default behavior Assert.Equal(GitContext.Engine.ReadOnly, GitContext.GetEffectiveGitEngine()); @@ -261,6 +269,7 @@ public void GetEffectiveGitEngine_DependabotNotTrue_UsesDefault(string dependabo { Environment.SetEnvironmentVariable("DEPENDABOT", originalDependabot); Environment.SetEnvironmentVariable("NBGV_GitEngine", originalNbgvGitEngine); + Environment.SetEnvironmentVariable("GITHUB_ACTOR", originalGitHubActor); } } @@ -270,13 +279,15 @@ public void GetEffectiveGitEngine_DependabotNotTrue_UsesDefault(string dependabo [InlineData("Disabled", GitContext.Engine.Disabled)] public void GetEffectiveGitEngine_NbgvGitEngineOverridesDependabot(string nbgvValue, GitContext.Engine expectedEngine) { - // Arrange: Set both DEPENDABOT and NBGV_GitEngine + // Arrange: Set both DEPENDABOT and NBGV_GitEngine, clear GITHUB_ACTOR var originalDependabot = Environment.GetEnvironmentVariable("DEPENDABOT"); var originalNbgvGitEngine = Environment.GetEnvironmentVariable("NBGV_GitEngine"); + var originalGitHubActor = Environment.GetEnvironmentVariable("GITHUB_ACTOR"); try { Environment.SetEnvironmentVariable("DEPENDABOT", "true"); Environment.SetEnvironmentVariable("NBGV_GitEngine", nbgvValue); + Environment.SetEnvironmentVariable("GITHUB_ACTOR", null); // Act & Assert: NBGV_GitEngine should take precedence and be parsed correctly Assert.Equal(expectedEngine, GitContext.GetEffectiveGitEngine()); @@ -285,6 +296,87 @@ public void GetEffectiveGitEngine_NbgvGitEngineOverridesDependabot(string nbgvVa { Environment.SetEnvironmentVariable("DEPENDABOT", originalDependabot); Environment.SetEnvironmentVariable("NBGV_GitEngine", originalNbgvGitEngine); + Environment.SetEnvironmentVariable("GITHUB_ACTOR", originalGitHubActor); + } + } + + [Fact] + public void GetEffectiveGitEngine_GitHubCopilotEnvironment_DisablesEngine() + { + // Arrange: Set GITHUB_ACTOR to copilot-swe-agent[bot] and clear NBGV_GitEngine and DEPENDABOT + var originalGitHubActor = Environment.GetEnvironmentVariable("GITHUB_ACTOR"); + var originalNbgvGitEngine = Environment.GetEnvironmentVariable("NBGV_GitEngine"); + var originalDependabot = Environment.GetEnvironmentVariable("DEPENDABOT"); + try + { + Environment.SetEnvironmentVariable("GITHUB_ACTOR", "copilot-swe-agent[bot]"); + Environment.SetEnvironmentVariable("NBGV_GitEngine", null); + Environment.SetEnvironmentVariable("DEPENDABOT", null); + + // Act & Assert: Should return Disabled regardless of requested engine + Assert.Equal(GitContext.Engine.Disabled, GitContext.GetEffectiveGitEngine()); + Assert.Equal(GitContext.Engine.Disabled, GitContext.GetEffectiveGitEngine(GitContext.Engine.ReadOnly)); + Assert.Equal(GitContext.Engine.Disabled, GitContext.GetEffectiveGitEngine(GitContext.Engine.ReadWrite)); + } + finally + { + Environment.SetEnvironmentVariable("GITHUB_ACTOR", originalGitHubActor); + Environment.SetEnvironmentVariable("NBGV_GitEngine", originalNbgvGitEngine); + Environment.SetEnvironmentVariable("DEPENDABOT", originalDependabot); + } + } + + [Theory] + [InlineData("user")] + [InlineData("dependabot[bot]")] + [InlineData("copilot-swe-agent")] + [InlineData("COPILOT-SWE-AGENT[BOT]")] + [InlineData("")] + public void GetEffectiveGitEngine_GitHubActorNotCopilot_UsesDefault(string gitHubActorValue) + { + // Arrange: Set GITHUB_ACTOR to non-copilot value and clear NBGV_GitEngine and DEPENDABOT + var originalGitHubActor = Environment.GetEnvironmentVariable("GITHUB_ACTOR"); + var originalNbgvGitEngine = Environment.GetEnvironmentVariable("NBGV_GitEngine"); + var originalDependabot = Environment.GetEnvironmentVariable("DEPENDABOT"); + try + { + Environment.SetEnvironmentVariable("GITHUB_ACTOR", gitHubActorValue); + Environment.SetEnvironmentVariable("NBGV_GitEngine", null); + Environment.SetEnvironmentVariable("DEPENDABOT", null); + + // Act & Assert: Should use default behavior + Assert.Equal(GitContext.Engine.ReadOnly, GitContext.GetEffectiveGitEngine()); + Assert.Equal(GitContext.Engine.ReadWrite, GitContext.GetEffectiveGitEngine(GitContext.Engine.ReadWrite)); + } + finally + { + Environment.SetEnvironmentVariable("GITHUB_ACTOR", originalGitHubActor); + Environment.SetEnvironmentVariable("NBGV_GitEngine", originalNbgvGitEngine); + Environment.SetEnvironmentVariable("DEPENDABOT", originalDependabot); + } + } + + [Theory] + [InlineData("LibGit2", GitContext.Engine.ReadWrite)] + [InlineData("Managed", GitContext.Engine.ReadOnly)] + [InlineData("Disabled", GitContext.Engine.Disabled)] + public void GetEffectiveGitEngine_NbgvGitEngineOverridesGitHubCopilot(string nbgvValue, GitContext.Engine expectedEngine) + { + // Arrange: Set both GITHUB_ACTOR=copilot-swe-agent[bot] and NBGV_GitEngine + var originalGitHubActor = Environment.GetEnvironmentVariable("GITHUB_ACTOR"); + var originalNbgvGitEngine = Environment.GetEnvironmentVariable("NBGV_GitEngine"); + try + { + Environment.SetEnvironmentVariable("GITHUB_ACTOR", "copilot-swe-agent[bot]"); + Environment.SetEnvironmentVariable("NBGV_GitEngine", nbgvValue); + + // Act & Assert: NBGV_GitEngine should take precedence and be parsed correctly + Assert.Equal(expectedEngine, GitContext.GetEffectiveGitEngine()); + } + finally + { + Environment.SetEnvironmentVariable("GITHUB_ACTOR", originalGitHubActor); + Environment.SetEnvironmentVariable("NBGV_GitEngine", originalNbgvGitEngine); } } } From b8efd46255523e0bb1a8d1c498cc809c83fa4f63 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 30 Oct 2025 14:47:49 +0000 Subject: [PATCH 3/3] Update documentation to mention GitHub Copilot auto-detection Co-authored-by: AArnott <3548+AArnott@users.noreply.github.com> --- docfx/docs/shallow-cloning-agents.md | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/docfx/docs/shallow-cloning-agents.md b/docfx/docs/shallow-cloning-agents.md index 51165b882..073f11881 100644 --- a/docfx/docs/shallow-cloning-agents.md +++ b/docfx/docs/shallow-cloning-agents.md @@ -15,7 +15,15 @@ A few caveats with this: ## GitHub Copilot Coding Agent -To configure the Copilot Coding Agent to set this environment variable, follow these steps to set environment variables for the `copilot` environment: +**As of Nerdbank.GitVersioning v3.9, the git engine is automatically disabled when running under GitHub Copilot**, eliminating the need for manual configuration in most cases. + +Specifically, when the `GITHUB_ACTOR` environment variable is set to `copilot-swe-agent[bot]` and the `NBGV_GitEngine` environment variable is **not** set, Nerdbank.GitVersioning automatically behaves as if `NBGV_GitEngine=Disabled`. This ensures that GitHub Copilot runs succeed without any additional setup. + +If you need to override this behavior for any reason, you can explicitly set the `NBGV_GitEngine` environment variable to your desired value, which will take precedence over the automatic GitHub Copilot detection. + +### Manual configuration (optional) + +If automatic detection doesn't work for your scenario, you can manually configure the Copilot Coding Agent to set the environment variable by following these steps to set environment variables for the `copilot` environment: 1. Navigate to your GitHub repo's Settings tab. 1. Select Environments from the list on the left.