0

We have just migrated our code from on-site TFS to Azure DevOps.

With TFS, I use a powershell script to build and deploy the application. The deployment part still works fine, but I don't know how to trigger the build. The command line I used with the old TFS is:

& "F:\Program Files (x86)\Microsoft Visual Studio 12.0\Common7\IDE\TFSBuild" start [repository URL] [project] "[build definition]" 

I know that DevOps has a REST API https://learn.microsoft.com/en-us/rest/api/azure/devops/build/builds/queue?view=azure-devops-rest-5.0 but there are many options and no examples there. I also saw this post: How to QUEUE a new build using VSTS REST API but the solution there does not wait for the build to finish and it uses API 4.1 - not sure if it's valid for DevOps? I already configured the build definitions in DevOps.

The URL to where the build is configured in DevOps is of this format: DevOps URL

All I need is to queue a build from a powershell script and wait for the build to complete, i.e. equivalent of my TFSBuild script above. Can someone help please?

4
  • 3
    Possible duplicate of How to QUEUE a new build using VSTS REST API Commented Apr 1, 2019 at 18:18
  • 1
    @Matt: Yes I've seen this post and it is helpful, but it does not wait for the build to complete, it returns as soon as it's queued. I need to know when it has finished with success/error. Commented Apr 1, 2019 at 21:44
  • There's no easy way to wait for build completion - you have to poll the devops server and query the build status. I've found this Gist which should get you started. Commented Apr 1, 2019 at 22:08
  • So you want trigger build and wait to response? Commented Apr 2, 2019 at 10:34

2 Answers 2

3

You can use the following script which trigger new build and waiting till build completed.

$tfsUrl = "http://{tfsServer}:{Port}/{Organization}/{Collection}/{Project}"
$buildsURI = $tfsUrl + '/_apis/build/builds?api-version=2.0'
$BuildDefsUrl = $tfsUrl + '/_apis/build/definitions?api-version=2.0'
$buildLog =  "$tfsUrl/_apis/build/builds"

$allbuildDefs = (Invoke-RestMethod -Uri ($BuildDefsUrl) -Method GET -UseDefaultCredentials).value | Where-Object {$_.name -eq "BuildName"} | select id,name ## get all relevant builds

foreach ($build in $allbuildDefs)
{
    $body = "
    { 
        definition: { 
            id: $($buildDef.id) 
        }, 
        reason: 'Manual', 
        priority: 'Normal',
        parameters: ""{
            'system.debug':'true'
        }""
    }" # build body
   
   Write-Output "Queueing $($build.name)" # print build name

   $buildOutput = Invoke-RestMethod -Method Post -Uri $buildsURI -UseDefaultCredentials -ContentType 'application/json' -Body $body -Verbose # trigger new build 
   $buildID = $buildOutput.id

   $buildInfo =  (Invoke-RestMethod -Uri "$buildLog/$buildID"  -UseDefaultCredentials -Method get)  # get build info by build ID
   while($buildInfo.status -eq "inProgress" -or $buildInfo.status -eq "notStarted") # keep checking till build completed
   {
      Write-Output "Build is $($buildInfo.status)... Sleep for 5 seconds.."
      Start-Sleep -Seconds 5 # Start sleep for 5 seconds
      $buildInfo =  (Invoke-RestMethod -Uri "$buildLog/$buildID"  -UseDefaultCredentials -Method get) ## get status 
   }

   Write-Output "Build Status : $($buildInfo.status)" # print build status
   Write-Output "Build Result : $($buildInfo.result)" # print build result
}

Be aware that i'm working with TFS 2017 and not Azure DevOps Services REST API 5.0.So,there might be some small changes you need to implement .

Sign up to request clarification or add additional context in comments.

7 Comments

Amit, this is very close to what I'm doing in Azure DevOps, the problem I'm experiencing is how to pass in parameters to the build. I was looking here, but this failed for me. stackoverflow.com/questions/50838651/…
Please open a new question and i would help you with that. this is hard to know where is your problem when you don't provide any information
Sorry about that, happy to make a new q, I'll update here shortly
Amit please see the following : stackoverflow.com/questions/61235103/…
If the build queue is full, the status will be "notStarted". The while statement needs to check for that status too.
|
1

I ended up doing this and it works:

Function Queue-Build ($definitionName, $branchName)
{
    Write-Host "Building $definitionName - $branchName"
    $build = (vsts build queue --project [project_name] --instance [server_name] --definition-name $definitionName --branch $branchName) | Out-String | ConvertFrom-Json

    #wait for the build to complete
    while ($build.status -ne "completed") {
        Start-Sleep -s 5
        $build = (vsts build show --id $build.id --instance [server_name] --project [project_name]) | Out-String | ConvertFrom-Json
        #Write-Host $build.status
    }
}

vsts login --token PAT_created_in_DevOps

$sourceBranch = [branch_name]
Queue-Build [build_definition_name] $sourceBranch 

2 Comments

Personally,i would suggest to use $build.status -eq "inProgress" instead of $build.status -ne "completed". Cause,you can never know what status might be in the future.
@AmitBaranes I tried that initially but it initially goes to notStarter, so with $build.status -eq "inProgress" it immediately goes out of the while loop. I guess ideally I should also check if the build outcome was a success.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.