Reputation: 13
Does VSTS support cascading merges? Our team is looking to switch from Stash to VSTS but one of the features we use extensively is cascading merges which VSTS doesn't seem to support.
For example let's say I have branches Release_1, Release_2 and Develop. I branch off of Release_1 and create a pull request to merge my branch with Release_1. In Stash it is possible to use semantic branch names to have it automatically merge with newer releases and Develop. In this scenario a merge to Release_1 would automatically trigger a merge to Release_2 and Develop.
Is this possible to setup in VSTS or would it require a git hook of some sort?
Upvotes: 1
Views: 387
Reputation: 13
Kind of necroing my own question here but I meant to post this awhile ago but just forgot about it.
Here is the Inline Powershell task that I ended up writing to use in the build step in VSTS. It is important to make sure that "Don't Sync Sources" is checked in the "Get sources" step. You should also set your CI triggers to include the branches based on a semantic wildcard. In our case it is rc/*. You also need to ensure that "Allow scripts to access OAuth token" is checked.
I figured I would post my solution here just in case anyone happens to stumble across this from a Google search. It's definitely not perfect and doesn't really have good error handling but it gets the job done.
# Change the output of the git commands so that the output doesn't cause the builds to fail even when there are no errors.
$env:GIT_REDIRECT_STDERR = '2>&1'
# Flag that gets set to true if a merge has conflicts
$mergeConflict = $false
# Initialize the empty repository
git init
git config --global user.email "[email protected]"
git config --global user.name "BuildAgent"
# Clone the repository
git clone https://buildAgent:$($env:SYSTEM_ACCESSTOKEN)@YOURDOMAINHERE.visualstudio.com/YOUR/REPO/HERE
cd YOURREPOHERE
# Get the branches that we want to cascade merges through
$versionList = git branch -r --list '*/rc/*'
$versionArray = @()
# Fix up the branch names so they are easier to work with
foreach ($branch in $versionList) {
$versionArray += $branch.Replace('origin/','').Trim()
}
# Add the Sprint branch to the end of the array
$versionArray += 'Sprint'
# Get the branch that triggered the cascade
$currentBranch = $env:BUILD_SOURCEBRANCH
# Fix up the branch name so it is easier to work with
$currentBranch= $currentBranch.Replace('refs/heads/','')
# Checkout the branch that triggered the cascade
git checkout $currentBranch
# Find the branch in our list of branches that we want to cascade through so that we skip any that we don't want to cascade to.
$currentBranchIndex = $versionArray.indexof($currentBranch)
# For each branch in the array checkout the next version and merge the previous version into it. Add ***NO_CI*** to the commit message so that the push to VSTS does not trigger
# another build which would trigger another cascade. If there is a conflict abort otherwise push the branch after merging.
for ($i=$currentBranchIndex; $i -lt $versionArray.length-1; $i++)
{
git checkout $versionArray[$i+1]; git merge $versionArray[$i] --no-ff -m "Merge $($versionArray[$i]) to $($versionArray[$i+1]) ***NO_CI***"
if($LastExitCode -ne 0){
'conflict merging: ' + $versionArray[$i] + ' into ' + $versionArray[$i+1]
$mergeConflict = $true
break
}
else{
git push origin $versionArray[$i+1]
}
}
# There was a merge conflict. Create a pull request with the appropriate source and target so that we can resolve the merge conflict.
if($mergeConflict){
$uri = 'https://YOURDOMAINHERE.visualstudio.com/YOURPROJECTHERE/_apis/git/repositories/REPOIDHERE/pullrequests?api-version=4.1'
$user = "buildAgent"
$Base64AuthInfo = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(("{0}:{1}" -f $User,$env:SYSTEM_ACCESSTOKEN)))
$params = @{"sourceRefName"="refs/heads/$($versionArray[$i])";
"targetRefName"="refs/heads/$($versionArray[$i+1])";
"title" = "Automatic Merge Failure";
"description" = "There was a merge conflict merging $($versionArray[$i]) into $($versionArray[$i+1])";
}
try{
Invoke-RestMethod -uri $uri -body ($params|ConvertTo-Json) -method 'Post' -contentType "application/json" -Headers @{Authorization=("Basic {0}" -f
$Base64AuthInfo)}
}
catch{
$result = $_.Exception.Response.GetResponseStream()
$reader = New-Object System.IO.StreamReader($result)
$reader.BaseStream.Position = 0
$reader.DiscardBufferedData()
$responseBody = $reader.ReadToEnd();
$responseBody
}
"##vso[task.complete result=Failed;]DONE"
}
Upvotes: 0
Reputation: 38096
The cascading merge is not available for VSTS recently.
But there has an user voice Cascading Merge which suggest this feature for VSTS, you can vote and follow up.
The workaround for now is using web hook or CI build to merge other branches sequentially as jessehouwing mentioned.
Upvotes: 1