[SQLProjects] Add pipeline steps for DACPAC publishing, deployment reports, scripts, and schema deployment

Open
#2,342 5 comments 0 reactions 0 assignees View on GitHub

Maintainers usually reply within 1 day

Nobody has claimed this yet.

Assessment

Difficulty
5/5
Estimated time
Over a week
Newbie friendliness
30/100
Issue type
Feature
Clarity
Mostly clear
Activity status
Active
Tech stack
csharp, sql
Domain
databases, devops

Research direction

Start by reading the existing CommunityToolkit.Aspire.Hosting.SqlDatabaseProjects APIs named in the issue: WithDacpac, WithDacDeployOptions, and WithConfigureDacDeployOptions. Then trace how this integration registers Aspire pipeline steps and handles project-backed, file-backed, and package-backed resources. Done means the proposed publishing, report, script, and deployment behaviors work as specified, including safety, ordering, failures, and tests; several API and behavior decisions remain open for discussion.

Written by the indexing model from the issue text.

Description

feature request :mailbox_with_mail:
Related to an existing integration?

Yes

Existing integration

CommunityToolkit.Aspire.Hosting.SqlDatabaseProjects

Overview

Extend CommunityToolkit.Aspire.Hosting.SqlDatabaseProjects with native Aspire pipeline steps for preparing and publishing DACPAC artifacts, generating deployment reports and SQL scripts, and deploying database schemas.

Report, script, and schema deployment steps would always be registered and individually invocable. Participation in aggregate workflows would be explicit:

  • publish: PublishAsDacpac() opts into preparing and publishing the DACPAC, without requiring a live database.
  • deploy: schema deployment participates only when explicitly enabled.
  • Report and script generation: remain standalone operations, never included in publish or deploy.

For project-backed resources, PublishAsDacpac() builds the SQL project by default, with an option to use an already-built DACPAC. For file-backed and NuGet package-backed resources, it publishes the existing DACPAC without compilation.
Without PublishAsDacpac(), database operations assume the configured DACPAC already exists. Existing local startup and dashboard deployment behavior would remain unchanged.

Usage example

Proposed API names and signatures are open for discussion:

var database = builder.AddSqlServer("sql").AddDatabase("orders");
builder.AddSqlProject<Projects.OrdersDatabase>("orders-schema")
    .WithReference(database)
    .PublishAsDacpac()
    .WithDacpacPipelineOptions(options =>
    {
        options.IncludeInDeploy = true;
        options.OutputDirectory = "artifacts/database";
    });

For CI workflows that have already built the SQL project:

.PublishAsDacpac(options => options.Build = false)

Individual operations would remain available regardless of whether publishing or aggregate deployment is enabled:

aspire do dacpac-report-orders-schema
aspire do dacpac-script-orders-schema
aspire do deploy-orders-schema

The proposed configuration types are:

public sealed class DacpacPublishOptions
{
    public bool Build { get; set; } = true;
}
public sealed class DacpacPipelineOptions
{
    public bool IncludeInDeploy { get; set; }
    public string? OutputDirectory { get; set; }
    public string? TargetConnectionStringParameterName { get; set; }
}

Build applies only to project-backed resources. IncludeInDeploy defaults to false. OutputDirectory configures report and script output; published DACPACs use the Aspire publishing output directory. Secret parameter names follow a convention unless overridden.
Applicable overloads should support both SQL project and SQL package resources, with equivalent configuration available to polyglot AppHosts.

Breaking change?

No

Alternatives
  • CI/CD scripts invoking SqlPackage directly: requires separate management of build output paths, deployment options, credentials, artifacts, and diagnostics.
  • Custom Aspire pipeline steps in each AppHost: duplicates logic that could be shared by the existing integration.
  • A dedicated deployment container or worker: supports execution inside the target environment but introduces additional packaging and orchestration.
Additional context
  • Publishing: place the DACPAC in a predictable, resource-specific location under the Aspire publishing output directory without modifying the source artifact. Make its location available to downstream operations. Publishing must not resolve database credentials, connect to the target, generate reports or scripts, or apply schema changes.
  • Dependencies: when PublishAsDacpac() is enabled, report, script, and deployment steps share the DACPAC preparation prerequisite, rather than depending on the entire application publish workflow. Otherwise, they use the existing configured artifact. Missing artifacts and build failures must fail the step clearly.
  • Target resolution: reuse WithReference(...) and resolve its connection string at execution time. For a local SQL Server target that cannot supply a usable deployment connection, automatically expose a secret connection-string parameter rather than requiring users to replace their resource reference. Missing configuration must fail clearly, never fall back to the local container. Targets provisioned by the same pipeline require appropriate ordering before schema deployment.
  • Existing configuration: reuse WithDacpac, WithDacDeployOptions, and WithConfigureDacDeployOptions. Explicitly define how WithSkipWhenDeployed affects pipeline deployment; report and script generation must neither be skipped through that optimization nor update deployment checksums.
  • Safety: report and script generation must not modify the database. A subsequent deployment recalculates its plan and does not execute the previously generated script. Failures must fail the pipeline step, cancellation must be supported, and diagnostics must not expose credentials.
  • CI artifacts: transferring published artifacts between jobs remains the CI platform's responsibility. A separate job can use WithDacpac(...) to identify the downloaded DACPAC.
  • Related work: #595, #1124
Help us help you

Yes, I'd like to be assigned to work on this item

Dominant language
C#
Stars
632
Forks
204
Avg merge
2d 14h
Merged PRs (30d)
92

Getting set up

Open in Codespaces

Starts the project's dev container in your browser, under your own GitHub account.

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from CommunityToolkit/Aspire

All issues in CommunityToolkit/Aspire

Similar issues

More C# issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.