Reputation: 9715
We use Git repositories in VSTS with branches and Pull Requests model to allow Code Reviews.
We have a CI Build definition and following it Release definition for all commits pushed to master.
And it would be a huge bonus if we can do CI for all branches too. However Build definition for Git repos allows to setup only single branch to track.
And creating a Build per branch isn't feasible, as our branches are short-living aka feature branches and we delete them after PR merge to master.
Yes, there is an ability to specify to run CI build for PRs to master in Branch Policies page. But there are 2 issues with this:
this will build only PR, while we want to build all the individual commits in branches as soon as they are pushed there
CI build for PRs will trigger our Release too, but we obviously want it to be triggered only for master builds. Yes I can analyze $(Build.SourceBranch)
or $(Build.SourceBranchName)
in the Release definition and fail if it's not "master" but it will create a failed Release anyway, which I just want to avoid at all
So... how can we have CI builds in VSTS for any arbitrary branch?
Another idea wrt running Release only for master builds - is to trigger Release from the Build side, e.g. by using API if $(Build.SourceBranch)
equals to 'master', say by custom PowerShell script.
I can see there's even an extension for VSTS Trigger build step, but it will trigger even for non-master builds, although Microsoft is working on a feature to run steps conditionally.
Upvotes: 3
Views: 2124
Reputation: 1781
Very very easy.
Go to the Marketplace and install GitVersion
into VSTS/Azure DevOps
https://marketplace.visualstudio.com/items?itemName=gittools.gitversion
As what was described before, change your CI trigger to monitor all branches:
The reason I also add line #2 to monitor tags is because I leverage GitVersion and git tags to version the build artifact when I'm ready to release my product. When I apply and push a git tag the build doesn't detect it unless I explicitly tell it to watch for it. My format for git tag is "v1.2.3" starting with lower-case "v". Just in case I want to apply any other tag and not start a build.
Lastly change the build number format. You need to discern what branch is building. GitVersion uses semantic versioning thus this describes what is building.
Benefits:
The secret sauce: GitVersion reads the Git history, so the number increments for every git commit AFTER it is tagged. It creates build variables from the CI system it is using and makes them available. It derives these variables and creates a tag
or alias for the branch it is building depending on the mode
you are using GitVersion in. In the example above I had some commits (not shown), when it was version 0.1.0
then I tagged it version 1.0.0
and released it. The next commit predicted that the next version would be 1.1.0
and there were lots of commits (11 of them) into the develop
branch. The build name uses the alias alpha
since build artifacts are alpha candidates. There were 4 more commits. There was a feature branch build after that branched from commit #15, made a 16th commit and pushed that, and was built. I think you are getting the idea. It's all from one single build pipeline and using GitVersion to describe what branch is being build and the commit being built. Semantic versioning describes the build.
Upvotes: 0
Reputation: 29976
You can add a powershell script task at the end of your build definition to trigger the release via Rest API, I created a simple code sample for your reference:
if ($env:BUILD_SOURCEBRANCHNAME -eq "master")
{
$collectionuri = $env:SYSTEM_TEAMFOUNDATIONCOLLECTIONURI
$buildid = $env:BUILD_BUILDID
$project = $env:SYSTEM_TEAMPROJECT
$token = $env:SYSTEM_ACCESSTOKEN
$builddef = $env:BUILD_DEFINITIONNAME
$buildnum = $env:BUILD_BUILDID
$releaseid = 2;
#Generate API URL
$account = "";
$reg = "https://+(?<acc>\w+?).visualstudio+"
if ($collectionuri -match $reg)
{
$account = $Matches.acc;
}
else
{
Write-Host "Fail to get the account name from collection url";
}
$url= "https://" + $account + ".vsrm.visualstudio.com/"+ $project + "/_apis/release/releases?api-version=3.0-preview.2"
#Generate Auth info
$basicAuth= ("{0}:{1}"-f "anys",$token)
$basicAuth=[System.Text.Encoding]::UTF8.GetBytes($basicAuth)
$basicAuth=[System.Convert]::ToBase64String($basicAuth)
$headers= @{Authorization=("Basic {0}"-f $basicAuth)}
#Generate body content
$instanceRef = @{id = $buildID};
$artif = @{alias = $builddef; instanceReference = @{id = $buildnum}}
$content = @{
definitionId = $releaseid
description = "Triggered from CI Build"
artifacts = @($artif)
}
$json = $content | ConvertTo-Json -Depth 100
#Call Rest API to start the release
$responseBuild = Invoke-RestMethod -Uri $url -headers $headers -Method Post -Body $json -ContentType "application/json"
}
else
{
Write-Host "Not master branch, no release triggered"
}
You need to update the "releaseid" to the id of the release definition you'd like to trigger and in the security configuration of that definition, set the "Create releases" permission to "Allow" for "Project Collection Build Service" account.
Upvotes: 2
Reputation: 10227
However Build definition for Git repos allows to setup only single branch to track.
That's actually not true. (You may be confused by the fact that the Repository
tab has a Default branch
setting, which only accepts a single branch.)
On the build definition, go to the Triggers
tab. Check the Continuous Integration
box if it isn't already.
Under Branch filters
click Add new filter
and set the value to *
. (It will prompt you to select an existing branch, but you can ignore that and just hit Enter.)
Your build definition will now build commits on any branch in your repo.
Upvotes: 2