【问题标题】:Share file between release stages in Azure DevOps (VSTS)在 Azure DevOps (VSTS) 中的发布阶段之间共享文件
【发布时间】:2018-11-14 13:11:36
【问题描述】:

大图:我们正在使用 Azure DevOps 发布流程(到目前为止,我们在设计器中创建步骤,而不是 YAML 管道)。我们发布到具有 3 个不同数据库的 3 个环境。该版本的一部分是从 DACPAC 文件部署数据库。由于使用 SqlPackage.exe 直接发布到数据库不是很透明(您没有看到和查看实际的 SQL 脚本),我们希望分两个阶段进行发布:

  1. 从 DACPAC 创建 SQL 脚本并查看它
  2. 批准后从之前生成的脚本运行应用和数据库部署。

问题:如何在各个阶段之间共享 sql 脚本文件以及如何查看它以供审批。可以在不同的代理上触发阶段。

我的尝试

  1. 将脚本发布为构建工件 - 这将无法生成脚本我需要连接到数据库并且连接到它不应该是构建过程的一部分,尤其是连接到生产数据库。
  2. 将工件作为发布步骤发布到 Azure Pipelines - 发布时不允许这样做,仅适用于构建 发布
  3. 将工件发布到文件共享 - 我不确定这到底是如何工作的,文档做得不是很好。此外,在我们的基础架构中很难设置常规 Windows 文件共享,我宁愿避免它。

还有其他建议吗?

【问题讨论】:

标签: azure-devops azure-pipelines azure-pipelines-release-task


【解决方案1】:

虽然您不能使用管道人工制品,但您 could use Universal Packages in Package Management to publish arbitrary files for later retrieval。将文件内容转储到管道日志是允许人们检查它的最简单方法。

您还可以创建一个带有占位符的文件作为构建工件,并在每个阶段从管道变量的最终设置中合并,这样您就可以将它们保留为构建工件。这就是我倾向于对这种性质的任何文件做的事情。听起来这不适用于您生成的 SQL 文件。

或者,如果“等待批准”部分很重要,您可以生成它并将其写入日志,然后将其上传到通用包管理。然后在阶段结束时请求批准。在下一阶段,您可以从 Universal Package Management 下载脚本,或者在执行前使用完全相同的任务配置重新生成它。

【讨论】:

  • 我被告知未来版本的“Publish Pipeline Artefact”很可能会实现我们都想要的场景。
  • 感谢您的想法,我们终于解决了将脚本发送到 SFTP 服务器的问题,我们可以在其中访问和查看它,然后在第二阶段我们下载脚本并运行。但理想的情况是发布人工制品
  • 是的,通用包管理允许类似的事情。从 SFTP 检索脚本后,您检查脚本的 sha 吗?否则,您最终可能会使用与生成的脚本不同的脚本。在您的场景中,安全性似乎很重要;)。
  • 再次感谢您的想法 :) 您说得对,我们应该检查 SHA 总和,目前我们没有这样做。
【解决方案2】:

Azure DevOps 现在允许下载在管道早期阶段已作为工件发布的文件。

在我分享的代码中,我通过数据库更改实现了 SQL 模式生成,然后发布了这些更改(在批准后)。一些备注:

  • 如果更改会导致数据丢失,这将不起作用。
  • sqlpackage 的路径仅在安装 Visual Studio 2019 时正确,例如在 windows-2019 图像中。
  • 我通过组变量传递了以下变量(有关如何创建组变量的更多信息here):
    • targetDBConnectionString
    • servername
    • databasename
    • adminlogin
    • adminPassword
  • 我已将approval 添加到ApplyChanges 阶段(在Pipelines 菜单中,选择环境,然后选择ApplyChanges 环境,然后从右上角的三个点按钮中选择approvals and checks)。这样,在手动批准之前,更改不会应用于数据库。

stages:
- stage: 'Build'
  displayName: 'Build the web application'
  jobs: 

  (...)

  - job: BuildDacpac
    pool:
      vmImage: 'windows-2019'
    steps:
    - task: DotNetCoreCLI@2
      displayName: 'Build the database project'
      inputs:
        command: 'custom'
        custom: 'build'
        projects: 'FQDN\For\The\DB\Project\DBProjectName.sqlproj'
    - task: CopyFiles@2
      displayName: 'Copy dacpac file to a staging directory'
      inputs:
        contents: |
          FQDN\For\The\DB\Project\bin\**\*.dacpac
        targetFolder: '$(Build.StagingDirectory)'
    - task: PublishBuildArtifacts@1
      displayName: 'Publish build artifact'
      inputs:
        pathToPublish: '$(Build.ArtifactStagingDirectory)'
        artifactName: dropDacpac
      condition: succeededOrFailed()

- stage: VerifyScript
      displayName: 'Script database schema changes'
      dependsOn: 
        - Build
      jobs:
      - deployment: VerifyScript
        pool:
          vmImage: 'windows-2019'
        variables:
        - group: 'Timeline CV - Release'
        environment: 'scriptverification'
        strategy:
          runOnce:
            deploy:
              steps:
              - download: current
                artifact: dropDacpac
                patterns: '**/*'

          - task: CmdLine@2
            displayName: 'Generate schema changes script'
            inputs:
              script: |
                "c:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\Common7\IDE\Extensions\Microsoft\SQLDB\DAC\140\sqlpackage.exe"    ^
                /action:script ^
                /diagnostics:true ^
                /sourcefile:$(Pipeline.Workspace)\dropDacpac\path\to\the\dacpacFile\package.dacpac    ^
                /targetConnectionString:$(targetDBConnectionString) ^
                /outputpath:$(Build.StagingDirectory)\changesScript.sql

          - task: PublishPipelineArtifact@1
            inputs:
              targetPath: '$(Build.StagingDirectory)'
              artifactName: dropSqlSchemaChangesScript
            condition: succeededOrFailed()

          - task: PowerShell@2
            displayName: Show Auto Generated SQL Script
            inputs: 
              targetType: 'inline'
              script: | 
                Write-Host "Auto Generated SQL Update Script:"
                Get-Content $(Build.StagingDirectory)\changesScript.sql | foreach {Write-Output      $_}

- stage: ApplyChanges
  displayName: 'Apply database schema changes'
  dependsOn: VerifyScript
  jobs:
  - deployment: ApplyChanges
    pool:
      vmImage: 'windows-2019'
    variables:
    - group: 'Timeline CV - Release'
    environment: 'applyChanges'
    strategy:
      runOnce:
        deploy:
          steps:
          - download: current
            artifact: dropSqlSchemaChangesScript
          - task: SqlDacpacDeploymentOnMachineGroup@0
            displayName: 'Deploy SQL schema changes script'
            inputs:
              taskType: 'sqlQuery'
              sqlFile: '$(Pipeline.Workspace)\dropSqlSchemaChangesScript\changesScript.sql'
              targetMethod: 'server'
              authScheme: 'sqlServerAuthentication'
              serverName: '$(servername)'
              databaseName: '$(databasename)'
              sqlUsername: '$(adminlogin)'
              sqlPassword: '$(adminPassword)'

【讨论】:

  • 这是否适用于发布管道?在我的发布管道中,$(Build.ArtifactStagingDirectory) 未设置。
  • 您是否在发布管道(经典视图)中尝试过下载管道工件任务?我相信这应该是可能的。检查这个:docs.microsoft.com/en-us/azure/devops/pipelines/artifacts/…
  • 我收到以下错误:“无法从发布环境上传到管道工件。”
  • 看来您的问题在于上传/发布工件,而不是下载它。如果它在您的用例中有意义,我建议您创建一个构建管道,该管道通过发布工件来完成。然后,只要在构建管道中发布工件,就会触发您正在处理的发布管道
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-11-09
相关资源
最近更新 更多