【发布时间】:2020-12-30 00:37:42
【问题描述】:
我正在开发一个 TFS 构建过程,其中包括从 Artifactory 存储库下载一个大型 ZIP 存档。下载通常需要 20 分钟以上,有效地使我的构建执行时间加倍。
为了加快我的构建速度,我想从 PowerShell 构建步骤启动一个异步过程,以请求工件下载并在后台执行下载的同时进入下一个构建步骤。
我已经成功地管理了这个(Start-Process powershell -WindowStyle Hidden 等...);工件确实下载成功,而且至关重要的是,在 PowerShell 步骤完成并且构建继续到后续步骤后,下载会继续并完成。
现在,下载的存档将需要在构建的后期进行处理。因此,为了确保在下载完成之前不会开始处理,我想将构建环境变量“IsDownloadComplete”从“False”更新为“True”。
用于环境变量更新的常用 PowerShell 不起作用(我怀疑是因为从孤立的异步进程执行?):
"##vso[task.setvariable variable='IsDownloadComplete';]'True'"
那么,该怎么办?如何从异步进程中更新环境变量?
更新: 我的 TFS 构建步骤中的异步进程调用如下所示:
$cmd = "$(SupportFunctionsLocation)\[script].ps1 -artifactUrl '$(artifactUrl)' -artifactoryApiKey '$(ArtifactoryApiKey)' -baseDir '$(Build.BinariesDirectory)\[base_dir]' -envVarName 'IsDownloadComplete' -envVarValue 'true'"
try {
Start-Process PowerShell.exe -ArgumentList "-NoProfile -WindowStyle Hidden -Command $cmd"
Start-Sleep -s 10
} catch {
Write-Host $_.ErrorMessage
}
在工件拉取完成后,更新构建环境变量的调用位于“$(SupportFunctionsLocation)[script].ps1”脚本中:
param (
[parameter(mandatory=$true)][string]$artifactUrl,
[parameter(mandatory=$true)][string]$apiKey,
[parameter(mandatory=$true)][string]$baseDir,
[parameter(mandatory=$true)][string]$envVarName,
[parameter(mandatory=$true)][string]$envVarValue
)
function Pull-FromArtifactory ($url, $apiKey, $dir) {
if (-not (Test-Path -Path $dir)) {
New-Item -Path $dir -ItemType "Directory"
}
$archive = $null
Write-Host "Pulling archive from Artifactory repository (this may take a minute or two)..."
try {
$archive = Split-Path $url -leaf
$headers = @{"X-JFrog-Art-Api" = $apiKey}
Invoke-RestMethod -Uri $url -Headers $headers -OutFile "$dir\$archive"
}
catch {
Write-Host "Failed to retrieve archive from Artifactory repository..."
Write-Host $_.Exception.Message
Exit 1
}
}
Pull-FromArtifactory $artifactUrl $apiKey $baseDir
# Update 'IsDownloadComplete' build environment variable
Write-Host "##vso[task.setvariable variable=$envVarName;]$envVarValue"
我随后执行的调试构建步骤如下所示:
if (Test-Path ("$(Build.BinariesDirectory)\[base_dir]")) {
do {
Get-ChildItem "$(Build.BinariesDirectory)\[base_dir]" -Include "test.zip" -Force -Recurse
Write-Host "Download complete: " $env:IsDownloadComplete
Start-Sleep -s 30
} while ($env:IsDownloadComplete -ne 'true')
}
当我的构建执行时,异步进程从 PowerShell 步骤中的 Start-Process 调用成功启动。步骤不等待;它终止并且异步进程继续在后台执行。
随着调试步骤中的脚本循环,Get-ChildItem 调用的每次执行都会显示文件大小随着异步过程的继续而增加,直到下载完成(我们知道文件大小)。
但是,即使下载完成,构建环境变量也无法更新;调试脚本步骤继续无限循环。
调试步骤的日志输出:
2020-09-11T13:46:23.5557526Z 目录:C:\BuildAgent_work\15\b[base_dir]
2020-09-11T13:46:23.5557526Z
2020-09-11T13:46:23.5687526Z 模式 LastWriteTime 长度名称
2020-09-11T13:46:23.5707484Z ---- ------------- ------ ----
2020-09-11T13:46:23.5737531Z -a---- 9/11/2020 9:46 AM 3572999 test.zip
2020-09-11T13:46:23.6027538Z 下载完成:false
2020-09-11T13:46:53.6214501Z -a---- 2020 年 9 月 11 日上午 9:46
30362999 test.zip
2020-09-11T13:46:53.6224502Z 下载完成:false
2020-09-11T13:47:23.6271640Z -a---- 2020 年 9 月 11 日上午 9:46
56742999 test.zip
2020-09-11T13:47:23.6291560Z 下载完成:false
2020-09-11T13:47:53.6328511Z -a---- 2020 年 9 月 11 日上午 9:46
83072999 test.zip
2020-09-11T13:47:53.6338508Z 下载完成:false
2020-09-11T13:48:23.6377761Z -a---- 2020 年 9 月 11 日上午 9:48
95577750 test.zip
2020-09-11T13:48:23.6387762Z 下载完成:false
2020-09-11T13:48:53.6424119Z -a---- 2020 年 9 月 11 日上午 9:48
95577750 test.zip
2020-09-11T13:48:53.6434120Z 下载完成:false
2020-09-11T13:49:23.6473880Z -a---- 9/11/2020 9:48 AM 95577750 test.zip
2020-09-11T13:49:23.6483867Z 下载完成:false
2020-09-11T13:49:53.6519497Z -a---- 9/11/2020 9:48 AM 95577750 test.zip
2020-09-11T13:49:53.6529503Z 下载完成:false
2020-09-11T13:50:23.6560150Z -a---- 9/11/2020 9:48 AM 95577750 test.zip
注意每次迭代都会增加“test.zip”文件的大小。
【问题讨论】:
标签: powershell asynchronous tfsbuild