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?

PiotrS
  • 180
  • 3
  • 16
  • 3
    Possible duplicate of [How to QUEUE a new build using VSTS REST API](https://stackoverflow.com/questions/50483072/how-to-queue-a-new-build-using-vsts-rest-api) – Matt Apr 01 '19 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. – PiotrS Apr 01 '19 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](https://gist.github.com/HockeyJustin/f5613f059cfd6f6e98a730393c044524) which should get you started. – Peter Schneider Apr 01 '19 at 22:08
  • So you want trigger build and wait to response? – Amit Baranes Apr 02 '19 at 10:34

2 Answers2

2

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 .

kevinpo
  • 1,853
  • 19
  • 20
Amit Baranes
  • 7,398
  • 2
  • 31
  • 53
  • 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. https://stackoverflow.com/questions/50838651/vsts-use-api-to-set-build-parameters-at-queue-time – Jeff Patton Apr 15 '20 at 16:48
  • 1
    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 – Amit Baranes Apr 15 '20 at 16:52
  • Sorry about that, happy to make a new q, I'll update here shortly – Jeff Patton Apr 15 '20 at 17:02
  • Amit please see the following : https://stackoverflow.com/questions/61235103/user-powershell-to-queue-a-build-in-azure-devops – Jeff Patton Apr 15 '20 at 17:41
  • If the build queue is full, the status will be "notStarted". The `while` statement needs to check for that status too. – kevinpo Sep 16 '21 at 12:53
  • @kevinpo feel free to update as this is an old answer. – Amit Baranes Sep 17 '21 at 13:06
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 
PiotrS
  • 180
  • 3
  • 16
  • 2
    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. – Amit Baranes Apr 03 '19 at 14:52
  • 1
    @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. – PiotrS Apr 08 '19 at 18:13