Skip to content

Omit connection string placeholders when running EF tool during publish - #17905

Merged
Mitch Denny (mitchdenny) merged 2 commits into
mainfrom
copilot/fix-connection-strings-publish
Jul 14, 2026
Merged

Omit connection string placeholders when running EF tool during publish#17905
Mitch Denny (mitchdenny) merged 2 commits into
mainfrom
copilot/fix-connection-strings-publish

Conversation

Copilot AI commented Jun 4, 2026

Copy link
Copy Markdown
Contributor

Fixes #17847

Description

During aspire publish, the EF Core tool generates migration scripts/bundles by running the migration's startup project. The ConnectionStrings__<name> env var (from WithReference) resolves to a manifest placeholder expression (e.g. {postgresdb.connectionString}) in publish mode, since the target database isn't provisioned yet. That placeholder was passed to dotnet ef, causing design-time DbContext creation to fail with "Format of the initialization string does not conform to specification starting at index 0."

Generating a migration script/bundle doesn't need a live connection — the bundle receives the real connection string at deploy time (invoked with --connection "$ConnectionStrings__<name>").

Changes

  • EFResourceBuilderExtensions.StartEfToolResourceAsync: route the EF tool's environment variables through a new GetToolEnvironmentVariables helper that skips ConnectionStringReference values when in publish mode. Run mode is unchanged (real values still flow through).
  • Tests: added unit tests covering placeholder omission in publish mode and preservation of real connection strings in run mode.

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

Copilot AI and others added 2 commits June 4, 2026 15:33
Co-authored-by: AndriySvyryd <6539701+AndriySvyryd@users.noreply.github.com>
…ublish

Co-authored-by: AndriySvyryd <6539701+AndriySvyryd@users.noreply.github.com>
@github-actions

github-actions Bot commented Jun 4, 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 -- 17905

Or

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

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.

Pull request overview

This PR adjusts how the EF Core tool process is launched during aspire publish so that connection string environment variables coming from WithReference are not forwarded when they resolve to manifest placeholders (e.g., {postgresdb.connectionString}), avoiding EF design-time DbContext creation failures. This aligns with the publish-time behavior where the actual connection string is only available at deploy time, while still preserving current run-mode behavior.

Changes:

  • Route EF tool environment-variable application through a new helper (GetToolEnvironmentVariables) that skips ConnectionStringReference values in publish mode.
  • Add unit tests validating omission in publish mode and preservation in run mode.
  • Add a minimal IExecutionConfigurationResult test stub to exercise the environment-variable selection logic without launching a process.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.

File Description
src/Aspire.Hosting.EntityFrameworkCore/EFResourceBuilderExtensions.cs Filters EF tool environment variables in publish mode to avoid passing connection string placeholders.
tests/Aspire.Hosting.EntityFrameworkCore.Tests/EFMigrationPipelineTests.cs Adds unit coverage for the new environment-variable filtering behavior (publish vs run).

@AndriySvyryd

Copy link
Copy Markdown
Member

PR Testing Report

PR Information

CLI Version Verification

  • Expected Commit (PR head): d1ab3ca
  • Installed Version: 13.5.0-pr.17905.gd1ab3ca4
  • Status: ✅ Verified — version contains the PR number and head short SHA.

Note: The original CI run's dogfood artifacts had expired (run was ~20 days old). The successful workflow run 26962587137 was re-run to regenerate cli-native-archives-win-x64 and built-nugets, which were then used to dogfood-install the PR CLI.

Changes Analyzed

Files Changed

  • src/Aspire.Hosting.EntityFrameworkCore/EFResourceBuilderExtensions.cs — adds GetToolEnvironmentVariables(...), which omits environment variables whose unprocessed value is a ConnectionStringReference when isPublishMode is true.
  • tests/Aspire.Hosting.EntityFrameworkCore.Tests/EFMigrationPipelineTests.cs — 2 new unit tests (publish omits placeholder, run keeps connection string).

Change Categories

  • CLI changes
  • Hosting integration changes (EF Core)
  • Dashboard changes
  • Template changes
  • Client/Component changes
  • Test changes

Test Scenarios Executed

Scenario 1: Publish EF-migrations AppHost (happy path / core fix)

Objective: Run aspire publish (publish mode) against an AppHost using AddEFMigrations(...).PublishAsMigrationBundle(...) with a database WithReference, and verify the EF tool generates the migration bundle without the Format of the initialization string does not conform to specification error that this PR fixes.
Coverage Type: Happy path (exact reproduction of the fixed scenario)
Status: ✅ Passed

Setup:

  • AppHost: in-repo playground/SqlServerEndToEnd/SqlServerEndToEnd.AppHost (canonical repro — no aspire new template scaffolds EF migrations). Workspace checked out at the PR head commit d1ab3ca4, so the AppHost's referenced Aspire.Hosting.EntityFrameworkCore assembly contains the fix.
  • Output directory: isolated temp folder.
  • Command: aspire publish --apphost <playground AppHost> --output-path <temp> --non-interactive --include-exception-details --pipeline-log-level debug

Result:

  • Exit code: 0
  • Pipeline: Pipeline succeeded — 10/11 steps succeeded, 1 unrelated warning (No azure compute environments found in the model).
  • db1-migrations-generate-migration-bundlecompleted successfully (36.25s)
  • db2-migrations-generate-migration-bundlecompleted successfully (27.45s)
  • EF tool invoked for both contexts: dotnet tool exec dotnet-ef ... migrations bundle ... --context MyDb1Context/MyDb2Context ... --target-runtime linux-x64
  • Log message: migration bundle generated successfully for 'db1-migrations' / ... 'db2-migrations'
  • No Format of the initialization string does not conform to specification error appeared anywhere in the log.

Artifacts produced:

  • publish-output/efmigrations/db1-migrations — 36,409,099 bytes (self-contained linux-x64 bundle executable)
  • publish-output/efmigrations/db2-migrations — 36,409,099 bytes

Scenario 2: Run-mode contrast (boundary)

Objective: Verify the fix only suppresses connection strings in publish mode and still forwards them in run mode.
Coverage Type: Boundary
Status: ✅ Passed (via the PR's added unit test GetToolEnvironmentVariablesKeepsConnectionStringsInRunMode, plus GetToolEnvironmentVariablesOmitsConnectionStringPlaceholdersInPublishMode). Not re-run end-to-end because the publish-mode path is the behavior the PR changes; run-mode behavior is unchanged.

Expected Unhappy-Path Outcome: In publish mode, a ConnectionStringReference env var (which resolves to a {db.connectionString} placeholder) is omitted from the EF tool process, so design-time DbContext creation does not fail. Confirmed: both bundles generated, publish exited 0.

Summary

Scenario Status Notes
1. Publish EF-migrations AppHost (happy path) ✅ Passed Both bundles generated; no init-string error; exit 0
2. Run-mode contrast (boundary) ✅ Passed Covered by PR unit tests; run-mode unchanged

Overall Result

✅ PR VERIFIED

The PR resolves the publish-time failure: aspire publish against an AddEFMigrations + PublishAsMigrationBundle AppHost now generates the migration bundles successfully because the connection-string placeholder env vars are omitted when the EF tool runs in publish mode. End-to-end behavior matches the PR's intent and unit tests.

Recommendations

  • No issues found. The change is narrow, well-commented, and matches the verified behavior.

@mitchdenny Mitch Denny (mitchdenny) left a comment

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.

Reviewed the publish-mode connection string filtering and focused tests. No actionable issues found. Follow-up E2E deployment coverage has been filed separately.

@mitchdenny
Mitch Denny (mitchdenny) merged commit 6c245a9 into main Jul 14, 2026
1004 of 1007 checks passed
@mitchdenny
Mitch Denny (mitchdenny) deleted the copilot/fix-connection-strings-publish branch July 14, 2026 01:19
@microsoft-github-policy-service microsoft-github-policy-service Bot added this to the 13.5 milestone Jul 14, 2026
@aspire-repo-bot

Copy link
Copy Markdown
Contributor

✅ No documentation update needed.

docs_optional → false positive signal

Triggered signal (1): pr_body_has_cli_flag_mention — fired on `--connection "$ConnectionStrings__<name>"` in the PR body. This is the EF Core bundle's own deploy-time CLI flag, not an Aspire CLI flag or option. The signal is a false positive.

The PR is a bug fix that corrects aspire publish behavior for projects using EF Core migrations: connection string placeholder expressions (e.g. {postgresdb.connectionString}) are now omitted when invoking dotnet ef, preventing a "Format of the initialization string" error at publish time. No new public API, CLI flags, configuration keys, or user-facing options were added. The existing EF migrations documentation at integrations/databases/efcore/migrations.mdx already covers the publish pipeline (PublishAsMigrationScript / PublishAsMigrationBundle) and this fix restores the documented behavior without requiring any docs update.

@github-actions github-actions Bot locked and limited conversation to collaborators Aug 17, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

area-integrations Issues pertaining to Aspire Integrations packages entityframework

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Postgres with PublishAsMigrationBundle fails to publish

5 participants