We are using VSTS for our CI/CD environment. In our project we have multiple parts, like Database and Frontend1, which have a separate folder in our repository:
src/
Database
Frontend1
...
I have created a separate build for each of the components of our project, which are triggered if there changes pushed to the corresponding subfolder. I want this separation to easily control and check the version of each component.
Database --> Build Database
Frontend1 --> Build Frontend1
With this configuration there are two builds triggered if I check in changes for Database
and Frontend1
with a single commit.
Additionaly I have configured a single release with both artefacts linked. The release is also triggered for each build.
The problem now is, that if I check in a change for the Database
and Frontend1
, both builds are triggered and after every build there is also a release triggered. This means I have two releases for the same commit. I want to achive that there is only one release which combines both builds:
Database --> Build Database |
| --> Release Database and Frontend1
Frontend1 --> Builds Frontend1 |
Is there any possibility to achive such a configuration?
Finally, I have found a solution for my problem. I have created a VSTS task which add a label to the current build if there is no other build running/queued:
[CmdletBinding()]
param(
[string] $teamfoundationCollectionUri = $env:SYSTEM_TEAMFOUNDATIONCOLLECTIONURI,
[string] $teamfoundationProject= $env:SYSTEM_TEAMPROJECT,
[string] $accessToken = "Bearer $env:SYSTEM_ACCESSTOKEN",
[int] $currentBuildId = $Env:BUILD_BUILDID,
[string] $tag
)
if(!$tag)
{
$tag = Get-VstsInput -Name "tag"
}
$buildInformationUrl = "$teamfoundationCollectionUri$teamfoundationProject/_apis/build/builds/$currentBuildId"
Write-Host "Loading build information: " $buildInformationUrl
$buildInformationResponse = Invoke-RestMethod -uri $buildInformationUrl -Headers @{Authorization = "$accessToken"}
$buildSourceVersion = $buildInformationResponse.sourceVersion
$openBuildsUrl = "$teamfoundationCollectionUri$teamfoundationProject/_apis/build/builds?statusFilter=inProgress,notStarted"
Write-Host "Requesting open builds: " $openBuildsUrl
$builds = Invoke-RestMethod -uri $openBuildsUrl -Headers @{Authorization = "$accessToken"}
$otherBuildForCommitIsRunning = $false
ForEach( $currentBuild in $builds.value )
{
if($currentBuild.id -eq $currentBuildId) {
Write-Host "Build with Id " $currentBuild.id " skipped"
continue;
}
if($currentBuild.sourceVersion -eq $buildSourceVersion) {
Write-Host "Found other open build: " $currentBuild.id
$otherBuildForCommitIsRunning = $true
}
}
if($otherBuildForCommitIsRunning -eq $false) {
Write-Host "Tagging build with "$tag
Write-Host "##vso[build.addbuildtag]$tag"
}
Additionally I have added a tag condition for the release trigger:
At present, you can't really achieve what you want to do. A release can be configured to trigger off of multiple artifact sources (in this case, builds), but a release will be triggered any time any one of those artifacts is updated. If you have one change that triggers two builds, you're going to get two releases.
However, you can use Artifact Conditions on a given environment to only trigger a deployment of that environment.
So you'd break your release definition into two environments:
|-Dev-Database -> QA-Database -> etc
Start-|
|-Dev-FrontEnd -> QA-FrontEnd -> etc
The artifact condition would ensure that you only get a release of the Database for database changes, and a release of the front end for front end changes.
I'd like there to be a "batch" mode where it's smart enough to see multiple builds for the same commit and wait on them all to complete, but there isn't anything like that unfortunately.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With