首页 > 解决方案 > 如何在 azure piplines 中交换之前将文件从生产复制到暂存槽

问题描述

我们有一个具有 CMS 上传功能的网站。当我们发布一个版本时,我们配置的 Azure 管道将该版本部署到暂存槽,然后交换暂存和生产。但是,任何上传的文件现在都在暂存,而不是在生产中。我想上传到 CDN 可以解决这个问题,但目前这不是一个选项。所以我想也许我可以在交换之前将该文件夹下载到暂存槽。这是可能的吗?关于如何做到这一点的任何想法?

编辑:这是构建管道:

trigger:
- development
- release

pool:
  vmImage: 'windows-latest'

variables:
  solution: '**/*.sln'
  projects: '**/*.csproj'
  buildPlatform: 'any cpu'
  buildConfiguration: 'Release'

steps:

- task: UseDotNet@2
  displayName: 'Use .NET Core sdk'
  inputs:
    packageType: sdk
    version: 2.2.401
    installationPath: $(Agent.ToolsDirectory)/dotnet

- task: DotNetCoreCLI@2
  displayName: Restore
  inputs:
    command: 'restore'
    projects: '$(projects)'
    feedsToUse: 'config'
    nugetConfigPath: '$(build.sourcesDirectory)\nuget.config'

- task: DotNetCoreCLI@2
  displayName: Build
  inputs:
    command: 'build'
    projects: '$(solution)'
    arguments: '--configuration $(BuildConfiguration) --no-incremental'

- task: DotNetCoreCLI@2
  displayName: Test
  inputs:
    command: 'test'
    projects: '**/*Tests/*.csproj'
    arguments: '--configuration $(buildConfiguration)'

- task: DotNetCoreCLI@2
  displayName: Publish
  inputs:
    command: publish
    publishWebProjects: True
    arguments: '--configuration $(BuildConfiguration) --output $(build.artifactstagingdirectory)'

- task: PublishBuildArtifacts@1
  displayName: 'Publish Artifact'
  inputs:
    PathtoPublish: '$(Build.ArtifactStagingDirectory)'
    ArtifactName: 'drop'
    publishLocation: 'Container'

这是发布管道: 发布管道

基本上在发布到接受槽之后,有人可以通过暂存批准发布以在生产槽上部署。批准后,完成以下步骤。

使用具有以下自定义设置的 webdeploy 部署 Azure 应用服务: Azure 应用服务部署在这里

然后使用默认选项使用 Azure App Service Manage 交换暂存和生产槽

所以我想从生产槽下载上传的文件文件夹并将其上传到暂存槽上的同一文件夹

编辑 2,这是我到目前为止的脚本。

    param(
        [string]$resourceGroupName,
        [string]$webAppName,
        [string]$appPath="wwwroot",
        [string]$slotName="staging", 
        [string]$kuduPath,
        [string]$localPath,
        [bool]$recursive=$true
    )
    function Get-AzureRmWebAppPublishingCredentials($resourceGroupName, $webAppName, $slotName = $null) {
        if ([string]::IsNullOrWhiteSpace($slotName)) {
            $resourceType = "Microsoft.Web/sites/config"
            $resourceName = "$webAppName/publishingcredentials"
        }
        else {
            $resourceType = "Microsoft.Web/sites/slots/config"
            $resourceName = "$webAppName/$slotName/publishingcredentials"
        }
        $publishingCredentials = Invoke-AzureRmResourceAction -ResourceGroupName $resourceGroupName -ResourceType $resourceType -ResourceName $resourceName -Action list -ApiVersion 2015-08-01 -Force
        Write-Host $publishingCredentials   
        return $publishingCredentials
    }
    function Get-KuduApiAuthorisationHeaderValue($resourceGroupName, $webAppName, $slotName = $null) {
        $publishingCredentials = Get-AzureRmWebAppPublishingCredentials $resourceGroupName $webAppName $slotName
        Write-Host $publishingCredentials.Properties.PublishingUserName
        return ("Basic {0}" -f [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(("{0}:{1}" -f $publishingCredentials.Properties.PublishingUserName, $publishingCredentials.Properties.PublishingPassword))))
    }
    function Get-ApiUrl($webAppName, $appPath, $slotName, $kuduPath, $recursive, $api = "vfs") {
        if ($recursive -eq $true) {
            if (-not ($kuduPath.endswith("recursive=true"))) {
               if (-not ($kuduPath.endswith("/"))) {
                  $kuduPath += "/"
               }
               $kuduPath += "?recursive=true"
            }
        }
        if ($slotName -eq "") {
            $kuduApiUrl = "https://$webAppName.scm.azurewebsites.net/api/$api/site/$appPath/$kuduPath"
        }
        else {
            $kuduApiUrl = "https://$webAppName`-$slotName.scm.azurewebsites.net/api/$api/site/$appPath/$kuduPath"
        }
        Write-Host $kuduApiUrl
        return $kuduApiUrl
    }
    function Get-KuduZipFile($resourceGroupName, $webAppName, $appPath, $slotName, $kuduPath, $recursive, $localPath) {
        $kuduApiAuthorisationToken = Get-KuduApiAuthorisationHeaderValue $resourceGroupName $webAppName $slotName
        $kuduApiUrl = Get-ApiUrl $webAppName, $appPath, $slotName, $kuduPath, $recursive, "zip"
        try
        {
            Invoke-RestMethod -Uri $kuduApiUrl `
                            -Headers @{"Authorization"=$kuduApiAuthorisationToken;"If-Match"="*"} `
                            -Method GET `
                            -OutFile $localPath `
                            -ContentType "multipart/form-data"
        } catch {
            Write-Host "StatusCode:" $_.Exception.Response.StatusCode.value__ 
            Write-Host "StatusDescription:" $_.Exception.Response.StatusDescription
            if (-not ($_.Exception.Response.StatusCode.value__ -eq 404)) {
                throw $PSItem
            }
        }    
    }
    function Put-KuduZipFile($resourceGroupName, $webAppName, $appPath, $slotName, $kuduPath, $recursive, $localPath){
        $kuduApiAuthorisationToken = Get-KuduApiAuthorisationHeaderValue $resourceGroupName $webAppName $slotName
        $kuduApiUrl = Get-ApiUrl $webAppName $appPath $slotName $kuduPath $recursive "zip"
        try
        {
            Invoke-RestMethod -Uri $kuduApiUrl `
                            -Headers @{"Authorization"=$kuduApiAuthorisationToken;"If-Match"="*"} `
                            -Method PUT `
                            -InFile $localPath `
                            -ContentType "multipart/form-data"
        } catch {
            Write-Host "StatusCode:" $_.Exception.Response.StatusCode.value__ 
            Write-Host "StatusDescription:" $_.Exception.Response.StatusDescription
            if (-not ($_.Exception.Response.StatusCode.value__ -eq 404)) {
                throw $PSItem
            }
        }    
    }

    Write-Host "resourceGroupName: $resourceGroupName"
    Write-Host "webAppName: $webAppName"
    Write-Host "appPath: $appPath"
    Write-Host "slotName: $slotName"
    Write-Host "kuduPath: $kuduPath"
    Write-Host "localPath: $localPath"
    Write-Host "recursive: $recursive"

    Get-KuduZipFile $resourceGroupName $webAppName $appPath "" $kuduPath $recursive $localPath
    Put-KuduZipFile $resourceGroupName $webAppName $appPath $slotName $kuduPath $recursive $localPath

输出是(删除了一些敏感部分):

resourceGroupName: resourceGroupName
webAppName: webAppName
appPath: wwwroot
slotName: staging
kuduPath: Downloads
localPath: d:\a\r1\a
recursive: True


https://webAppName wwwroot  Downloads True zip-.scm.azurewebsites.net/api/vfs/site//

但是,如果我在本地 shell 中尝试,我会得到以下信息

PS N:\> Get-ApiUrl "webAppName" "appPath" "staging" "kuduPath" $true "zip"
https://webAppName-staging.scm.azurewebsites.net/api/zip/site/appPath/kuduPath/?recursive=true

所以我不明白为什么在管道中结果是错误的。我在管道中使用以下任务: https ://marketplace.visualstudio.com/items?itemName=petergroenewegen.PeterGroenewegen-Xpirit-Vsts-Build-InlinePowershell

标签: azure-pipelinesswap

解决方案


推荐阅读