开发管道中的 SqlPackage

SqlPackage 是一个命令行实用工具,可自动处理多个数据库开发任务,并可合并到 CI/CD 管道中。

注意

建议使用独立安装的 SqlPackage 来实现管道自动化,而不是使用与其他应用程序(包括 SQL Server Management Studio 或 Visual Studio)捆绑的 SqlPackage 可执行文件。 SqlPackage 的独立安装会更频繁地更新,并且不会绑定到其他应用程序的发布节奏。

如果将 SqlPackage 安装为全局 dotnet 工具(建议),只需从任何目录即可在管道 sqlpackage 中调用它。 如果将 SqlPackage 安装为独立可执行文件,则必须在管道中指定可执行文件的完整路径。 在 Windows 上,SqlPackage 的独立安装可在路径 C:\Program Files\Microsoft SQL Server\170\DAC\bin (DacFx.msi)上使用。 在 Windows 和 Linux 环境中,如果下载适用于 .NET 的自包含 .zip SqlPackage,则可以将可执行文件提取到所选位置。

托管虚拟环境

用于 GitHub Actions 托管运行器和 Azure Pipelines 虚拟机镜像的虚拟环境在 runner-images GitHub 存储库中管理。 SqlPackage 包含在多个环境windows-latestubuntu-22.04中,但在ubuntu-24.04ubuntu-latest中默认情况下不再包含。 在每次 SqlPackage 发布后的几个星期内,都会对 runner-images 中的映像进行更新。

在托管虚拟环境中,你将在管道的运行时安装 SqlPackage。 安装作为 Azure Pipelines 和 GitHub Actions 中的单独步骤执行,并在安装发生时为每个管道运行添加短暂延迟。 要在运行时安装 SqlPackage,可以在管道中添加一个步骤,该步骤使用 dotnet CLI 将 SqlPackage 安装为全局工具。 此步骤应在管道中的任何 SqlPackage 操作之前运行。

dotnet tool install --global Microsoft.SqlPackage

安装 SqlPackage 之前,可能需要在管道中执行 .NET 安装步骤,错误消息指出找不到 .NET。 使用集成操作来进行配置,例如 Azure Pipelines 中的 UseDotNet 任务或 GitHub Actions 中的 setup-dotnet 操作。

(可选)可以通过追加 --version <version> 到 install 命令来指定要安装的 SqlPackage 版本,也可以使用 --prerelease 标志来安装预览版本。

示例:在 Azure DevOps Pipelines 中安装 SqlPackage 的步骤

在 Azure DevOps Pipelines 中,可以使用 UseDotNet 任务来安装 .NET SDK,然后将 SqlPackage 安装为全局工具。 如果使用的是由 Microsoft 提供的 Windows 代理,则 SqlPackage 已安装在内 C:\Program Files\Microsoft SQL Server\170\DAC\bin。 如果使用自承载代理,还可以在主机环境中安装 SqlPackage,并在管道中跳过此步骤。

- task: UseDotNet@2
  inputs:
    packageType: 'sdk'
    version: '8.x'
- script: dotnet tool install --global Microsoft.SqlPackage --version <version>
  displayName: 'Install specific version of SqlPackage'

示例:在 GitHub Actions 中安装 SqlPackage 的步骤

在 GitHub Actions 中,可以使用 setup-dotnet 作来安装 .NET SDK,然后将 SqlPackage 安装为全局工具。 如果使用的是 GitHub 提供的 Windows 运行程序,那么 SqlPackage 已经安装在 C:\Program Files\Microsoft SQL Server\170\DAC\bin。 如果使用自承载运行程序,还可以在主机环境中安装 SqlPackage,并在工作流中跳过此步骤。

- name: Setup .NET
  uses: actions/setup-dotnet@v4
  with:
    dotnet-version: '8.x'
- name: Install SqlPackage
  run: dotnet tool install --global Microsoft.SqlPackage --version <version>

检查 SqlPackage 版本

在故障排除过程中,必须了解所使用的 SqlPackage 版本。 若要获得此信息,可以在管道中添加一个步骤,以使用 /version 参数运行 SqlPackage。 本文中提供了基于 Azure DevOps 和 GitHub 托管环境的示例,自承载环境可能具有不同的工作目录安装路径。

Azure Pipelines

在 Azure 管道中,script 关键字会返回 SqlPackage 版本号。

- script: SqlPackage /version
  workingDirectory: 'C:\Program Files\Microsoft SQL Server\170\DAC\bin\'
  displayName: 'get sqlpackage version'

GitHub Actions

在 GitHub Action 工作流中,run 关键字会返回 SqlPackage 版本号。

- name: get sqlpackage version
  working-directory: 'C:\Program Files\Microsoft SQL Server\170\DAC\bin\'
  run: ./SqlPackage /version

显示生成号 15.0.4897.1 的 GitHub 操作输出

更新管道代理上的 SqlPackage

在某些情况下,管道环境中安装的 SqlPackage 的当前版本可能不足。 如果环境无法直接修改,则可以使用额外的步骤在管道运行期间安装较新版本的 SqlPackage。 在管道中运行任何 DacPac 或 BacPac 操作之前,应先运行安装步骤。 在完成此任务时可以执行检查版本的步骤,以确保升级按预期完成。

基于 Windows 的 Azure Pipelines 代理

在 Azure Pipeline 中使用 PowerShell 任务时,可将一个步骤添加到 Azure Pipeline 中,该管道下载所需的 DacFx 安装程序并静默安装它。

- task: PowerShell@2
  displayName: 'upgrade sqlpackage'
  inputs:
    targetType: 'inline'
    script: |
      # use evergreen or specific dacfx msi link below
      wget -O DacFramework.msi "https://aka.ms/dacfx-msi"
      msiexec.exe /i "DacFramework.msi" /qn

GitHub Actions,基于 Linux 的运行程序

在 GitHub Action 工作流中,可以使用 run 关键字执行 dotnet tool 命令来安装、卸载或更新 SqlPackage。 以下示例演示如何将 SqlPackage 更新为最新的预览版本:

- name: Update SqlPackage
  run: dotnet tool update --global Microsoft.SqlPackage --prerelease

自托管的虚拟环境

在自承载虚拟环境中(例如自承载 Azure DevOps 代理或 GitHub Actions 运行程序)中,可以在主机环境中安装 SqlPackage,也可以在运行时安装 SqlPackage,如 托管虚拟环境中所述。 如果在主机环境中安装 SqlPackage,则在该主机上运行的管道无需在运行时安装 SqlPackage,这可以加快管道运行速度。 在主机上安装 SqlPackage 时,应定期 更新 SqlPackage ,以使用最新版本维护环境。

Azure 容器应用作业 可用于根据每次工作流调用的需要,在容器中部署自托管运行程序。 使用容器应用作业,可以控制 Dockerfile 中定义的环境,并根据需要安装 SqlPackage 和其他工具。 可以通过在容器映像中包含安装步骤,将自承载运行程序配置为在特定版本的 SqlPackage 上运行。 例如,本教程包括一个用于安装curljq 的 Dockerfile。

我们可以修改此示例以生成安装 .NET 8.0 和 SqlPackage 的容器映像:

FROM ghcr.io/actions/actions-runner:2.323.0

USER root

# install dotnet sdk and sqlpackage
RUN apt-get update && apt-get install -y dotnet-sdk-8.0 && \
    dotnet tool install --tool-path /usr/local/bin/ Microsoft.SqlPackage

COPY entrypoint.sh ./entrypoint.sh
RUN chmod +x ./entrypoint.sh

USER runner

ENTRYPOINT ["./entrypoint.sh"]

跟踪部署

可以捕获一些与 SqlPackage 相关的文件来重现管道并改进部署跟踪。 实现和用例取决于特定架构和自动化环境。

  • Dacpac 文件

  • 任何操作的诊断文件输出: 在任何 SqlPackage 操作中使用/DiagnosticsFile:参数。 有关详细信息,请参阅 管道代理中的“获取 SqlPackage 诊断”

  • 发布操作之前的脚本操作输出:在调用发布操作之前,请使用脚本 SqlPackage 操作

在流水线代理中获取 SqlPackage 诊断信息

SqlPackage 的诊断信息可通过参数 /DiagnosticsFile 在命令行中获得,可以在 Azure Pipelines 和 GitHub Actions 等虚拟环境中使用该信息。 诊断信息将写入工作目录中的文件。 文件名由 /DiagnosticsFile 参数指示。

Azure Pipelines

/DiagnosticsFile 参数添加到 Azure Pipeline SqlAzureDacpacDeployment 配置中的“其他 SqlPackage 参数”字段会导致将 SqlPackage 诊断信息写入指定的文件。 在 SqlAzureDacpacDeployment 任务之后,通过发布管道工件(如以下示例所示),诊断文件可以在虚拟环境之外使用。

- task: SqlAzureDacpacDeployment@1
  inputs:
    azureSubscription: '$(azuresubscription)'
    AuthenticationType: 'server'
    ServerName: '$(servername)'
    DatabaseName: '$(databasename)'
    SqlUsername: '$(sqlusername)'
    SqlPassword: '$(sqladminpassword)'
    deployType: 'DacpacTask'
    DeploymentAction: 'Publish'
    DacpacFile: '$(Build.Repository.LocalPath)\$(dacpacname).dacpac'
    AdditionalArguments: '/DiagnosticsFile:$(System.DefaultWorkingDirectory)/output.log'
    IpDetectionMethod: 'AutoDetect'

- task: PublishPipelineArtifact@1
  inputs:
    targetPath: '$(System.DefaultWorkingDirectory)/output.log'
    artifact: 'Diagnostic File'
    publishLocation: 'pipeline'

管道运行后,可以从“已发布项目”下的运行摘要页下载诊断文件。

GitHub Actions

/DiagnosticsFile 参数添加到 GitHub Action sql-action 配置中的“arguments”字段会导致将 SqlPackage 诊断信息写入指定的文件。 在 SQL 操作任务之后,可以通过发布如以下示例所示的工件,在虚拟环境之外提供诊断文件。

- name: Azure SQL Deploy
  uses: Azure/sql-action@v2
  with:
    # The connection string, including authentication information, for the Azure SQL Server database.
    connection-string: ${{ secrets.AZURE_SQL_CONNECTION_STRING }}
    # Path to DACPAC file to deploy
    path: .\DatabaseProjectAdventureWorksLT\bin\Release\DatabaseProjectAdventureWorksLT.dacpac
    action: publish
    # additional SqlPackage arguments
    arguments: /DiagnosticsFile:DatabaseProjectAdventureWorksLT/DiagnosticLog.log

- uses: actions/upload-artifact@v2
  with:
    name: 'DiagnosticLog.txt'
    path: 'DatabaseProjectAdventureWorksLT/DiagnosticLog.log'