Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -98,12 +98,107 @@ private async Task UpgradeFromGaToDevDoesNotDuplicateStorageAccountsCore(Cancell

// Step 5: Create single-file AppHost with GA CLI
output.WriteLine("Step 5: Creating single-file AppHost with GA CLI...");
var waitingForLanguageSelectionPrompt = new CellPatternSearcher()
.Find("Which language would you like to use?");
var waitingForTemplateVersionPrompt = new CellPatternSearcher()
.Find("NuGet.config");
var waitingForAgentInitPrompt = new CellPatternSearcher()
.Find("configure AI agent environments");
var waitingForSuccessPrompt = new CellPatternSearcher()
.FindPattern(counter.Value.ToString())
.RightText(" OK] $ ");
Comment on lines +101 to +109
Copy link

Copilot AI Apr 12, 2026

Choose a reason for hiding this comment

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

waitingForTemplateVersionPrompt is searching for "NuGet.config", but the template-version prompt itself has a stable header (e.g., "Select a template version:"). Depending on the configured channel/source, the selection items may not include "NuGet.config", which would make this state machine miss the prompt and time out while aspire init is still waiting for input. Prefer matching the prompt header text rather than a source-detail substring.

Copilot uses AI. Check for mistakes.

await auto.TypeAsync("aspire init");
await auto.EnterAsync();
await auto.WaitAsync(TimeSpan.FromSeconds(5));
await auto.EnterAsync();
await auto.WaitUntilTextAsync("Aspire initialization complete", timeout: TimeSpan.FromMinutes(2));
await auto.DeclineAgentInitPromptAsync(counter);

var initState = "success";
await auto.WaitUntilAsync(s =>
{
if (waitingForLanguageSelectionPrompt.Search(s).Count > 0)
{
initState = "language";
return true;
}

if (waitingForTemplateVersionPrompt.Search(s).Count > 0)
{
initState = "template-version";
return true;
}

if (waitingForAgentInitPrompt.Search(s).Count > 0)
{
initState = "agent-init";
return true;
}

if (waitingForSuccessPrompt.Search(s).Count > 0)
{
initState = "success";
return true;
}

return false;
}, timeout: TimeSpan.FromMinutes(2), description: "language prompt, template version prompt, agent init prompt, or init success prompt");

if (initState == "language")
{
await auto.EnterAsync();

await auto.WaitUntilAsync(s =>
{
if (waitingForTemplateVersionPrompt.Search(s).Count > 0)
{
initState = "template-version";
return true;
}

if (waitingForAgentInitPrompt.Search(s).Count > 0)
{
initState = "agent-init";
return true;
}

if (waitingForSuccessPrompt.Search(s).Count > 0)
{
initState = "success";
return true;
}

return false;
}, timeout: TimeSpan.FromMinutes(2), description: "template version prompt, agent init prompt, or init success prompt");
}

if (initState == "template-version")
{
await auto.EnterAsync();

await auto.WaitUntilAsync(s =>
{
if (waitingForAgentInitPrompt.Search(s).Count > 0)
{
initState = "agent-init";
return true;
}

if (waitingForSuccessPrompt.Search(s).Count > 0)
{
initState = "success";
return true;
}

return false;
}, timeout: TimeSpan.FromMinutes(2), description: "agent init prompt or init success prompt");
}

if (initState == "agent-init")
{
await auto.DeclineAgentInitPromptAsync(counter);
}
else
{
await auto.WaitForSuccessPromptAsync(counter);
}

// Step 6: Add ACA package using GA CLI (uses GA NuGet packages)
output.WriteLine("Step 6: Adding Azure Container Apps package (GA)...");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ private async Task DeployStarterWithManagedRedisToAzureContainerAppsCore(Cancell
.Find($"Enter the project name ({workspace.WorkspaceRoot.Name}): ");

var waitingForOutputPathPrompt = new CellPatternSearcher()
.Find("Enter the output path:");
.Find("Enter the output path");

var waitingForUrlsPrompt = new CellPatternSearcher()
.Find("Use *.dev.localhost URLs");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,10 +74,17 @@ private async Task DeployPythonStarterWithPurgeTaskCore(CancellationToken cancel
await auto.PrepareEnvironmentAsync(workspace, counter);

// Step 2: Set up CLI environment (in CI)
// Python apphosts need the full bundle because
// the prebuilt AppHost server is required for aspire new with Python templates.
if (DeploymentE2ETestHelpers.IsRunningInCI)
{
output.WriteLine("Step 2: Using pre-installed Aspire CLI from local build...");
await auto.SourceAspireCliEnvironmentAsync(counter);
var prNumber = DeploymentE2ETestHelpers.GetPrNumber();
if (prNumber > 0)
{
output.WriteLine($"Step 2: Installing Aspire bundle from PR #{prNumber}...");
await auto.InstallAspireBundleFromPullRequestAsync(prNumber, counter);
}
await auto.SourceAspireBundleEnvironmentAsync(counter);
}

// Step 3: Create Python FastAPI project using aspire new
Expand All @@ -95,7 +102,7 @@ private async Task DeployPythonStarterWithPurgeTaskCore(CancellationToken cancel
await auto.TypeAsync("aspire add Aspire.Hosting.Azure.AppContainers");
await auto.EnterAsync();

if (DeploymentE2ETestHelpers.IsRunningInCI)
if (DeploymentE2ETestHelpers.IsRunningInCI && DeploymentE2ETestHelpers.GetPrNumber() <= 0)
{
await auto.WaitUntilTextAsync("(based on NuGet.config)", timeout: TimeSpan.FromSeconds(60));
await auto.EnterAsync();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,10 +76,17 @@ private async Task DeployPythonFastApiTemplateToAzureAppServiceCore(Cancellation
await auto.PrepareEnvironmentAsync(workspace, counter);

// Step 2: Set up CLI environment (in CI)
// Python apphosts need the full bundle because
// the prebuilt AppHost server is required for aspire new with Python templates.
if (DeploymentE2ETestHelpers.IsRunningInCI)
{
output.WriteLine("Step 2: Using pre-installed Aspire CLI from local build...");
await auto.SourceAspireCliEnvironmentAsync(counter);
var prNumber = DeploymentE2ETestHelpers.GetPrNumber();
if (prNumber > 0)
{
output.WriteLine($"Step 2: Installing Aspire bundle from PR #{prNumber}...");
await auto.InstallAspireBundleFromPullRequestAsync(prNumber, counter);
}
await auto.SourceAspireBundleEnvironmentAsync(counter);
}

// Step 3: Create Python FastAPI project using aspire new with interactive prompts
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,10 +76,17 @@ private async Task DeployPythonFastApiTemplateToAzureContainerAppsCore(Cancellat
await auto.PrepareEnvironmentAsync(workspace, counter);

// Step 2: Set up CLI environment (in CI)
// Python apphosts need the full bundle because
// the prebuilt AppHost server is required for aspire new with Python templates.
if (DeploymentE2ETestHelpers.IsRunningInCI)
{
output.WriteLine("Step 2: Using pre-installed Aspire CLI from local build...");
await auto.SourceAspireCliEnvironmentAsync(counter);
var prNumber = DeploymentE2ETestHelpers.GetPrNumber();
if (prNumber > 0)
{
output.WriteLine($"Step 2: Installing Aspire bundle from PR #{prNumber}...");
await auto.InstallAspireBundleFromPullRequestAsync(prNumber, counter);
}
await auto.SourceAspireBundleEnvironmentAsync(counter);
}

// Step 3: Create Python FastAPI project using aspire new with interactive prompts
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,28 +86,60 @@ private async Task DeployTypeScriptVnetSqlServerInfrastructureCore(CancellationT
// Step 3: Create TypeScript AppHost using aspire init
output.WriteLine("Step 3: Creating TypeScript AppHost with aspire init...");

var waitingForNuGetConfigPrompt = new CellPatternSearcher()
var waitingForTemplateVersionPrompt = new CellPatternSearcher()
.Find("NuGet.config");
var waitingForInitComplete = new CellPatternSearcher()
.Find("Aspire initialization complete");
var waitingForAgentInitPrompt = new CellPatternSearcher()
.Find("configure AI agent environments");
var waitingForSuccessPrompt = new CellPatternSearcher()
.FindPattern(counter.Value.ToString())
.RightText(" OK] $ ");
Comment on lines +89 to +95
Copy link

Copilot AI Apr 12, 2026

Choose a reason for hiding this comment

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

The "template version prompt" matcher is currently Find("NuGet.config"), which is a brittle signal (it depends on the channel/source text shown in the selection list). If the CLI shows the template-version selection but without the "NuGet.config" suffix, this wait will never detect it and aspire init will hang until the 2-minute timeout. Consider matching the actual prompt text (e.g., "Select a template version:") instead of relying on "NuGet.config" appearing somewhere in the output.

Copilot uses AI. Check for mistakes.

await auto.TypeAsync("aspire init --language typescript");
await auto.EnterAsync();

// NuGet.config prompt may or may not appear depending on environment.
await auto.WaitUntilAsync(
s => waitingForNuGetConfigPrompt.Search(s).Count > 0
|| waitingForInitComplete.Search(s).Count > 0,
timeout: TimeSpan.FromMinutes(2),
description: "NuGet.config prompt or init completion");
await auto.EnterAsync(); // Dismiss NuGet.config prompt if present
var sawTemplateVersionPrompt = false;
var sawAgentInitPrompt = false;
await auto.WaitUntilAsync(s =>
{
if (waitingForTemplateVersionPrompt.Search(s).Count > 0)
{
sawTemplateVersionPrompt = true;
return true;
}

await auto.WaitUntilAsync(
s => waitingForInitComplete.Search(s).Count > 0,
timeout: TimeSpan.FromMinutes(2),
description: "aspire initialization complete");
if (waitingForAgentInitPrompt.Search(s).Count > 0)
{
sawAgentInitPrompt = true;
return true;
}

return waitingForSuccessPrompt.Search(s).Count > 0;
}, timeout: TimeSpan.FromMinutes(2), description: "template version prompt, agent init prompt, or init success prompt");

if (sawTemplateVersionPrompt)
{
await auto.EnterAsync();

await auto.DeclineAgentInitPromptAsync(counter);
await auto.WaitUntilAsync(s =>
{
if (waitingForAgentInitPrompt.Search(s).Count > 0)
{
sawAgentInitPrompt = true;
return true;
}

return waitingForSuccessPrompt.Search(s).Count > 0;
}, timeout: TimeSpan.FromMinutes(2), description: "agent init prompt or init success prompt");
}

if (sawAgentInitPrompt)
{
await auto.DeclineAgentInitPromptAsync(counter);
}
else
{
await auto.WaitForSuccessPromptAsync(counter);
}

// Step 4a: Add Aspire.Hosting.Azure.AppContainers
output.WriteLine("Step 4a: Adding Azure Container Apps hosting package...");
Expand Down
Loading