开发管道中的 SqlPackage

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

虚拟环境

注意

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

在 Windows 上,独立安装的 SqlPackage 可在路径 C:\Program Files\Microsoft SQL Server\160\DAC\bin (DacFx.msi) 或 %USERPROFILE%\.dotnet\tools(dotnet 工具)上获得。 在 Linux 上,独立安装的 SqlPackage可在路径 ~/.dotnet/tools(dotnet 工具)上获得。 在 Windows 和 Linux 环境中,如果下载适用于 .NET Core 的独立 .zip SqlPackage,可以将可执行文件提取到所选位置。

托管虚拟环境

用于 GitHub Actions 托管的运行程序和 Azure Pipelines VM 映像的虚拟环境在 runner-images GitHub 存储库中进行托管。 SqlPackage 包含在多个环境中,包括 windows-latestubuntu-latest。 在每次 SqlPackage 发布后的几个星期内,都会对 runner-images 中的映像进行更新。

自托管的虚拟环境

如果要在自托管的 Azure DevOps 代理等自托管的虚拟环境中使用 SqlPackage,建议定期更新应用程序,以使用最新版本维护环境。

跟踪部署

有一些与 SqlPackage 相关的文件,这些文件可作为管道项目捕获,以创建管道执行可再现性并改善部署跟踪。 实现和用例因特定体系结构和自动化环境而异。

  • Dacpac 文件
  • 任何操作的诊断文件输出:使用任何 SqlPackage 操作上的 /DiagnosticsFile: 参数,请见下面的示例
  • 发布操作之前的脚本操作输出:在调用发布操作之前,请使用脚本 SqlPackage 操作

其他 SqlPackage 示例

查看 SqlPackage 版本

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

Azure Pipelines

在 Azure 管道中使用 script 关键字时,可以向 Azure 管道添加一个步骤,用于输出 SqlPackage 版本号。

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

GitHub 操作

通过利用 GitHub 操作工作流中的 run 关键字,可以向 GitHub 操作添加一个步骤,用于输出 SqlPackage 版本号。

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

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

在管道代理中获取 SqlPackage 诊断

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

Azure Pipelines

在 Azure Pipeline SqlAzureDacpacDeployment 配置中将形参 /DiagnosticsFile 添加到“其他 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 操作

如果将 /DiagnosticsFile 形参添加到 GitHub Action sql-action 配置中的“实参”字段,则会将 SqlPackage 诊断信息写入指定的文件。 完成 sql-action 任务后,可以通过发布项目(如下面的示例所示),使诊断文件在虚拟环境外部可用。

- 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'

更新管道代理上的 SqlPackage

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

Azure Pipelines

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

- 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

后续步骤