Skip to content

Fix SQL Server REPL launch on Windows - #20704

Merged
Mitch Denny (mitchdenny) merged 5 commits into
mainfrom
mitchdenny-sql-repl-diagnostics
Oct 3, 2026
Merged

Mitch Denny (mitchdenny) merged 5 commits into
mainfrom
mitchdenny-sql-repl-diagnostics

Conversation

@mitchdenny

@mitchdenny Mitch Denny (mitchdenny) commented Oct 3, 2026 •

Copy link
Copy Markdown
Member

Description

Fix SQL Server's dashboard REPL failing to launch from Windows checkouts. The embedded /bin/sh script retained CRLF line endings and failed with Syntax error: "elif" unexpected, sometimes leaving the dashboard showing "Terminal view is not connected."

Launch /opt/mssql-tools18/bin/sqlcmd directly, matching the default SQL Server image. Add an optional Action<SqlServerReplOptions> callback and SqlServerReplCommand.Version17 / Version18 path constants so older or custom images can select an installed client or an executable wrapper script. Preserve the existing parameterless C# overload and generated TypeScript withRepl() call.

The README includes version overrides, custom paths, and before/after wrapper scripts. Tests cover defaults, configuration capture, invalid commands, run/publish behavior, credential forwarding, and authenticated SQL execution. Committed TypeScript codegen coverage compiles the callback, command accessors, version constants, and custom paths across npm, Bun, Yarn, and pnpm, and rejects numeric command versions.

Fixes #20645

User-facing usage

Existing calls use the default client:

builder.AddSqlServer("sql").WithRepl();

Select the client installed in an older image:

builder.AddSqlServer("sql")
    .WithRepl(options => options.Command = SqlServerReplCommand.Version17);
import { SqlServerReplCommand } from "./.aspire/modules/aspire.mjs";

await builder.addSqlServer("sql").withRepl({
    configure: async options => {
        await options.command.set(SqlServerReplCommand.Version17);
    }
});

Command also accepts a custom executable path such as /usr/local/bin/sqlcmd-wrapper. It does not install tools or modify the container image.

Breaking changes

Older SQL Server images that only contain /opt/mssql-tools/bin/sqlcmd no longer get automatic client-path discovery. Those AppHosts must select SqlServerReplCommand.Version17 explicitly. The default image and parameterless API remain supported.

Security considerations

The existing opt-in, run-only REPL still authenticates as sa and should only be enabled for trusted dashboard users. The executable override is AppHost-authored configuration and runs inside the existing container with the sqlcmd arguments. No shell interprets the command or arguments, and SQLCMDPASSWORD remains an environment variable rather than a command-line argument. Custom wrapper scripts receive that environment and must avoid logging credentials.

Validation

Runtime-tested commit: 475b2624dee66923ce452deba5dd1b2f86f2a045. Packaged CLI, templates, and integrations: 17.0.0-pr.20704.g475b2624.

  • CI passed, including stabilization, package builds, SQL Server tests on Windows/Linux, and TypeScript API compatibility. A Linux ARM64 hosted runner lost communication with GitHub; its automatic retry passed.
  • Windows source tests: 165 passed, zero failures or skips: SQL Server REPL/public API 49, MongoDB 30, PostgreSQL 23, MySQL 23, Redis 20, Valkey 20. These include real authenticated terminal sessions, MongoDB replica-set/TLS variants, and PostgreSQL/MySQL alternate ports. Quarantine and outerloop scenarios were excluded.
  • Fresh PR-artifact C# AppHost, Windows host with Docker Desktop Linux containers, actual Edge dashboard REPLs: SQL Server, MongoDB, PostgreSQL, MySQL, Redis, and Valkey all accepted input, returned the expected authenticated query result or PONG, and exited cleanly. Default MongoDB and Redis TLS configurations were exercised.
  • SQL Server Version17 worked with the real 2022-CU13-ubuntu-22.04 image. The README Dockerfile/wrapper example ran both its pre-session and post-session work around an authenticated SQL session.
  • Fresh TypeScript AppHost: the generated callback read the default Version18 command, set Version17, and opened a working legacy-client SQL session through the dashboard.
  • Stopped-resource negative case: the dashboard disabled REPL, and direct CLI invocation failed with The container is not running. and exit code 16.
  • Temporary AppHosts, containers, isolated CLI/hive, and tooling were cleaned up; logs, terminal snapshots, screenshots, and fixture sources were retained locally.

Follow-up at a3c214e9c5f4538decfb72079bdc01377e09b4ce:

  • Merged origin/main through 810d40942cd18ec3e6c47ee0fdeaacc44d6c7c97 without conflicts. Rebuilt and passed 49 SQL Server REPL/public API tests and 33 dashboard terminal tests on Windows.
  • Added committed TypeScript generated-SDK regression coverage. All four toolchains passed on Windows with Docker Desktop Linux containers, using the exact native CLI/package artifacts 17.0.0-pr.20704.g475b2624. The SQL Server implementation is unchanged by the follow-up test commit. Local setup required the native bundle rather than the CLI-only archive, the root-level CLI package metadata used by CI, and LocalArchive installation rather than the PR-mode activation path. No production or test-harness workaround was added.
  • CI for the updated branch is running; the earlier successful CI result above applies to the earlier runtime-tested commit.

Checklist

  • Is this feature complete?
    • Yes. Ready to ship.
    • No. Follow-up changes expected.
  • Are you including unit tests for the changes and scenario tests if relevant?
    • Yes
    • No
  • Did you add public API?
    • Yes
      • If yes, did you have an API Review for it?
        • Yes
        • No
      • Did you add <remarks /> and <code /> elements on your triple slash comments?
        • Yes
        • No
    • No
  • Does the change make any security assumptions or guarantees?
    • Yes
      • If yes, have you done a threat model and had a security review?
        • Yes
        • No
    • No

Launch sqlcmd directly instead of parsing a checkout-dependent shell script. Add configurable executable paths and well-known client commands, with C# and TypeScript documentation and coverage.

Fixes #20645

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
@github-actions

github-actions Bot commented Oct 3, 2026

Copy link
Copy Markdown
Contributor

🚀 Dogfood this PR with:

⚠️ WARNING: Do not do this without first carefully reviewing the code of this PR to satisfy yourself it is safe.

curl -fsSL https://raw.githubusercontent.com/microsoft/aspire/main/eng/scripts/get-aspire-cli-pr.sh | bash -s -- 20704

Or

  • Run remotely in PowerShell:
iex "& { $(irm https://raw.githubusercontent.com/microsoft/aspire/main/eng/scripts/get-aspire-cli-pr.ps1) } 20704"

@aspire-repo-bot
aspire-repo-bot Bot requested a balanced review from Copilot October 3, 2026 04:14
@github-actions github-actions Bot added the area-integrations Issues pertaining to Aspire Integrations packages label Oct 3, 2026
@mitchdenny Mitch Denny (mitchdenny) added the breaking-change Issue or PR that represents a breaking API or functional change over a prerelease. label Oct 3, 2026
@github-actions

This comment has been minimized.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Copilot review overview

🔵 Needs a closer look

The security-sensitive public API and breaking fallback change still require human review and the pending cross-platform CI validation.

Review effort: Balanced
Findings: None

What changed in this PR

Fixes the SQL Server run-only dashboard REPL on Windows by directly launching sqlcmd instead of an embedded shell script.

Changes:

  • Adds configurable SQL client paths with version constants.
  • Preserves C# and TypeScript withRepl() compatibility.
  • Expands runtime tests and usage documentation.
File Description
SqlServerBuilderExtensions.cs Directly launches the selected executable.
SqlServerReplOptions.cs Adds REPL configuration options.
SqlServerReplCommand.cs Defines known SQL client paths.
SqlServerContainerImageTags.cs Aligns the default client with the image.
README.md Documents overrides and wrapper scripts.
SqlServerReplCommandTests.cs Covers configuration, validation, and execution.

💡 Add a code-review agent skill for context-aware, tailored reviews. Learn more in the docs.

Avoid introducing a namespace that shadows Azure.Provisioning.Sql.SqlServer and keep shared image metadata independent of the hosting assembly.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
@github-actions

This comment has been minimized.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Copilot review overview

🟡 Changes recommended

Terminal failure diagnostics remain incomplete, and the new generated TypeScript API shape lacks committed regression coverage.

Review effort: Balanced
Findings: 1 Medium severity

Open (1)
Previously missed (1)

In code that hasn't changed since last review

Medium severity Add terminal launch and completion diagnostics with exit status

src/​Aspire.Hosting.SqlServer/​SqlServerBuilderExtensions.cs:195

This does not satisfy the linked issue's failure-diagnostics requirement. If this configured path is absent or not executable (notably when an older image is used without the new override), docker exec can still end before a viewer attaches; Hex1bAspireTerminal.RunTerminalAsync logs exceptions and cancellation but no normal workload completion or exit status, so the dashboard can still show only the generic disconnected state. Add observable launch/completion diagnostics (including exit status when available), or do not close #20645 as fully fixed.

Comment thread src/Aspire.Hosting.SqlServer/SqlServerBuilderExtensions.cs

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

No additional high-confidence findings. Repository restore succeeded, and all 31 focused SQL Server REPL tests passed locally, including authenticated container sessions.

@github-actions

github-actions Bot commented Oct 3, 2026

Copy link
Copy Markdown
Contributor

Retrying the failed CI jobs for this pull request from the CI run attempt. The rerun is being tracked in the rerun attempt.

@mitchdenny

Copy link
Copy Markdown
Member Author

The broader terminal launch/completion diagnostics mentioned in the Copilot review summary are out of scope for this PR. We're working on enhancements upstream in Hex1b and will handle that work separately. This PR is focused on fixing the SQL Server REPL launch on Windows.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Type-check default and configured REPL calls, command get/set, version constants, custom paths, and rejection of numeric versions across npm, Bun, Yarn, and pnpm.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
@github-actions

This comment has been minimized.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Copilot review overview

🟢 Approval recommended

The implementation and coverage are sound; remaining feedback only corrects portable README path notation.

Review effort: Balanced
Findings: 1 Low severity

Open (1)
Resolved since last review (1)

Comment thread src/Aspire.Hosting.SqlServer/README.md Outdated
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
@github-actions

github-actions Bot commented Oct 3, 2026

Copy link
Copy Markdown
Contributor

Tests selector

8 / 98 PR test projects · 2 PR jobs, from 6 changed files.

Selected PR test projects (8 / 98)

Aspire.Cli.EndToEnd.Tests, Aspire.Hosting.Azure.Kubernetes.Tests, Aspire.Hosting.Azure.Tests, Aspire.Hosting.Radius.Tests, Aspire.Hosting.SqlServer.Tests, Aspire.Microsoft.Data.SqlClient.Tests, Aspire.Microsoft.EntityFrameworkCore.SqlServer.Tests, Aspire.Playground.Tests

Selected PR jobs (2)

polyglot, typescript-api-compat


How these were chosen — grouped by what changed

🔧 src/Aspire.Hosting.SqlServer/SqlServerBuilderExtensions.cs (changed source)
→ 1 directly: Aspire.Hosting.SqlServer.Tests
→ 4 via the project graph: Aspire.Hosting.Azure.Kubernetes.Tests (3 hops), Aspire.Hosting.Azure.Tests (2 hops), Aspire.Hosting.Radius.Tests, Aspire.Playground.Tests (2 hops)

🔧 src/Aspire.Hosting.SqlServer/SqlServerContainerImageTags.cs (changed source)
→ 1 directly: Aspire.Hosting.SqlServer.Tests
→ 2 via the project graph: Aspire.Microsoft.Data.SqlClient.Tests, Aspire.Microsoft.EntityFrameworkCore.SqlServer.Tests

📦 affected project Aspire.Hosting.SqlServer
→ 1 test: Aspire.Cli.EndToEnd.Tests

🔧 src/Aspire.Hosting.SqlServer/SqlServerReplCommand.cs (changed source)
→ 1 directly: Aspire.Hosting.SqlServer.Tests

🔧 src/Aspire.Hosting.SqlServer/SqlServerReplOptions.cs (changed source)
→ 1 directly: Aspire.Hosting.SqlServer.Tests

🧪 tests/Aspire.Cli.EndToEnd.Tests/TypeScriptCodegenValidationTests.cs (changed test)
→ 1 directly: Aspire.Cli.EndToEnd.Tests

🧪 tests/Aspire.Hosting.SqlServer.Tests/SqlServerReplCommandTests.cs (changed test)
→ 1 directly: Aspire.Hosting.SqlServer.Tests

Job reasons

Job Triggered by
polyglot • affected project Aspire.Hosting.SqlServer
• affected project Aspire.Hosting.Azure.Provisioning.Sql
typescript-api-compat affected project Aspire.Hosting.SqlServer

Selection computed for commit 80d9433.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Copilot review overview

🟢 Approval recommended

The implementation and coverage are sound; only a minor cross-platform documentation path needs correction.

Review effort: Balanced
Findings: None

Resolved since last review (1)

@github-actions

github-actions Bot commented Oct 3, 2026

Copy link
Copy Markdown
Contributor

Retrying the failed CI jobs for this pull request from the CI run attempt. The rerun is being tracked in the rerun attempt.

@mitchdenny
Mitch Denny (mitchdenny) merged commit b572dc5 into main Oct 3, 2026
306 of 309 checks passed
@microsoft-github-policy-service microsoft-github-policy-service Bot added this to the 17.0 milestone Oct 3, 2026
aspire-repo-bot Bot added a commit to microsoft/aspire.dev that referenced this pull request Oct 3, 2026
…apper scripts

Documents changes from microsoft/aspire#20704: the REPL now invokes
/opt/mssql-tools18/bin/sqlcmd directly instead of probing for a client,
adds SqlServerReplOptions/SqlServerReplCommand to select Version17 for
older images or a custom executable path, and supports wrapper scripts
that run work before/after the interactive session.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@aspire-repo-bot

Copy link
Copy Markdown
Contributor

Pull request created: #1822

Generated by PR Documentation Check · copilot · auto · 74.7 AIC · ⌖ 17.5 AIC · ⊞ 20.3K

@aspire-repo-bot

Copy link
Copy Markdown
Contributor

📝 Documentation has been drafted in microsoft/aspire.dev#1822 targeting release/17.0.

Updated the SQL Server REPL documentation in sql-server-host.mdx to match PR #20704's behavior change: triggered signals container_image_tags_file_changed, integration_readme_changed, new_public_type, pr_body_has_user_facing_section, and pr_label_breaking_change.

  • Replaced the "supports both tools18/tools17" description with "invokes /opt/mssql-tools18/bin/sqlcmd directly" (per SqlServerContainerImageTags.cs and the README diff).
  • Added a Select the client executable section documenting the new SqlServerReplOptions/SqlServerReplCommand public types (Version17/Version18 constants) and a :::note[Breaking change] callout for older images that previously relied on auto-discovery, per the PR body's "Breaking changes" section.
  • Added a Run a wrapper script section with the Dockerfile/wrapper example from the README, including the SQLCMDPASSWORD env-var and exit-code guidance from the PR's security-considerations section.
  • All C#/TypeScript snippets use synced Tabs/TabItem with syncKey='aspire-lang', consistent with the rest of the page.

Note

This draft PR needs human review before merging.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area-integrations Issues pertaining to Aspire Integrations packages breaking-change Issue or PR that represents a breaking API or functional change over a prerelease.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

SQL Server REPL reports "Terminal view is not connected" without useful failure diagnostics

3 participants