Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Combine multiple builds into one release

Tags:

azure-devops

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?

like image 554
boindiil Avatar asked Jul 14 '17 10:07

boindiil


2 Answers

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:

enter image description here

like image 89
boindiil Avatar answered Nov 14 '22 02:11

boindiil


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.

like image 1
Daniel Mann Avatar answered Nov 14 '22 02:11

Daniel Mann