我在VSTS中有一个代理队列,有几个代理,我有一个分配给这个队列的构建。有没有办法告诉VSTS一次只能运行一个构建实例,其他实例(在其他代理上安排)应该等到上一个实例完成?
我需要这个,因为测试会创建一个运行集成测试的临时数据库,如果多个实例针对同一个数据库运行,那么它们会相互干扰。
我们实现了一个自定义VSTS任务来执行此操作。它运作良好。这是代码。
如果您不想创建自定义VSTS任务 - 您可以删除PowerShell。只需将值作为参数传递即可。
/ Project-Folder
- extension-icon.png
- extension-manifest.json
/ Tasks
/ KeepBuildSynchronous
- icon.png
- task.json
- task.ps1
{
"manifestVersion": 1,
"id": "your-task-name",
"name": "your-package-name",
"version": "0.0.1",
"publisher": "your-publisher-account",
"targets": [
{
"id": "Microsoft.VisualStudio.Services"
}
],
"description": "your-description",
"categories": [
"Build and release"
],
"icons": {
"default": "extension-icon.png"
},
"files": [
{
"path": "Tasks/KeepBuildSynchronous"
}
],
"contributions": [
{
"id": "12345678-0000-0000-0000-000000000000", <-- must match task.json id
"type": "ms.vss-distributed-task.task",
"targets": [
"ms.vss-distributed-task.tasks"
],
"properties": {
"name": "Tasks/KeepBuildSynchronous"
}
}
]
}
{
"id": "12345678-0000-0000-0000-000000000000",
"name": "keepBuildSynchronous",
"friendlyName": "Keep Build Synchronous",
"description": "Only allow one build with the same build definition to run at a time",
"helpMarkDown": "",
"category": "Utility",
"visibility": [
"Build"
],
"runsOn": [
"Agent",
"DeploymentGroup"
],
"author": "-your team-",
"version": {
"Major": 1,
"Minor": 1,
"Patch": 1
},
"releaseNotes": "Initial release",
"minimumAgentVersion": "1.91.0",
"inputs": [
{
"name": "waitTimeinMinutes",
"type": "int",
"label": "How many minutes do you want to wait before cancelling the build",
"defaultValue": "15",
"required": true,
"helpMarkDown": ""
}
],
"instanceNameFormat": "Keep Build Synchronous",
"execution": {
"PowerShell3": {
"target": "task.ps1"
}
}
}
[CmdletBinding()]
Param ()
Trace-VstsEnteringInvocation $MyInvocation
try {
Import-VstsLocStrings "$PSScriptRoot\Task.json"
# Get agent/build variables
[string]$teamFoundationCollectionUri = Get-VstsTaskVariable -Name "system.teamFoundationCollectionUri"
[string]$teamProjectId = Get-VstsTaskVariable -Name "system.teamProjectId"
[string]$buildId = Get-VstsTaskVariable -Name "build.buildId"
[int]$definitionId = Get-VstsTaskVariable -Name "system.definitionId" -AsInt
[string]$accessToken = Get-VstsTaskVariable -Name "system.accessToken"
# Get task inputs
[int]$waitTimeinMinutes = Get-VstsInput -Name waitTimeinMinutes -AsInt
[Object[]]$global:buildsByDefinition = $null
[Object[]]$global:runningBuilds = $null
function Get-Builds-By-Definition([int]$definitionId) {
$url = "$teamFoundationCollectionUri/$teamProjectId/_apis/build/builds?api-version=2.0&definitions=$definitionId"
$type = "application/json"
$headers = @{
Authorization = "Bearer $accessToken"
}
$global:buildsByDefinition = (Invoke-RestMethod -Uri $url -ContentType $type -Method Get -Headers $headers).value
$global:runningBuilds = $buildsByDefinition | Where-Object -Property "status" -Value "inProgress" -EQ
}
[datetime]$startedAt = Get-Date
[datetime]$waitUntil = $startedAt.AddMinutes($waitTimeinMinutes)
Get-Builds-By-Definition -definitionId $definitionId
[string]$buildDefinitionName = $buildsByDefinition[0].definition.name
Write-Host ""
Write-Host "Build definition ..... $buildDefinitionName"
Write-Host "Current build ........ $buildId"
Write-Host ""
Write-Host "Started at ........... $startedAt"
Write-Host "Willing to wait until $waitUntil"
Write-Host ""
while (1 -eq 1) {
if ((Get-Date) -gt $waitUntil) {
Write-Host "Waited too long (cancelling)"
throw "Waited longer than $waitTime minutes to start. Cancelling."
}
if ($global:runningBuilds -eq $null) {
Write-Host "No build running (weird, but ok...)"
break
}
[int]$firstToGo = ($global:runningBuilds | Sort-Object -Property "Id")[0].Id
if ($global:runningBuilds.Count -le 1 -or $buildId -le $firstToGo) {
Write-Host "Your turn to shine"
break
} else {
Write-Host "$($global:runningBuilds.Count) builds running. $firstToGo is next. (checking again)"
Start-Sleep -Seconds 15
}
Get-Builds-By-Definition -definitionId $definitionId
}
}
finally {
Trace-VstsLeavingInvocation $MyInvocation
}
tfx extension create --manifest-globs extension-manifest.json --rev-version
我将留下一些神秘感,让您了解如何将其发布到市场并将其安装到您的构建代理上
你不能在Build级别(You can vote for this feature here)配置它,但也许你可以在阶段级别完成你想要的。
查看每个阶段下的Parallelism选项。看起来如果你看到行为相反,你会想要将其设置为“无”。 “无”是新构建的默认选项。
不,没有这样的设置来控制它,它由管道控制:Concurrent build and release pipelines in VSTS。
您可以禁用其他代理:
另一方面,您可以创建名为include build number的临时数据库,然后它们不会相互干扰。