azure-pipelines - 如何在 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 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