Check previous build information in VSTS (VSTS API) - version-control

Are previous build variables accessible during execution of a VSTS build? For example, can I get $(Build.SourceVersion) or $(Build.QueuedBy) of the previous build?
I can get current build information through the build variables like $(Build.SourceVersion) but can I get something like $(Build.Previous.SourceVersion)?

There aren’t the built-in variables for previous build information, the workaround is that you can call Builds REST API (can be filter status, such as completed, inProgress) through PowerShell during this build. (The first item of the result is the newest one)
$base64authinfo = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(("{0}:{1}" -f $User, $Password)))
$responseFromGet = Invoke-RestMethod -Method Get -ContentType application/json -Uri $Uri -Headers #{Authorization=("Basic {0}" -f $base64authinfo)}
Some articles about calling REST API: Calling VSTS APIs with PowerShell, VSTS/TFS REST API: The basics and working with builds and releases
You can use value of System.AccessToken variable as password (Check Allow scripts to access OAuth token option in Options tab) and username can be anything.

No. "Previous" is a nebulous concept when you're talking about things that can run in parallel. What if you have 3 builds running concurrently?

Related

Azure cli: clone pipeline

Looking at az pipelines documentation it seems it's not possible to clone a pipeline using cli.
I've looked at getting the yaml (az pipelines show -name=x > x_orig.yaml) and then trying to change json and create pipeline from modified yaml, but that feels like a lot of work that could break after next update.
Is there a way to clone a pipline without going the the Web UI?
Currently, there indeed is not available Azure CLI that can clone or export/import a pipeline to create a new pipeline.
I also searched and tried the Azure DevOps REST API for Pipelines, but did not find the available API.
Ideally, the Azure CLI "az pipelines create" can provide an input parameter that allows users specify an existing pipeline as a starting point for the new pipeline.
If your projects really need this feature, I recommend that you can directly report a feature request on the "Azure/azure-cli" repository to ask adding the parameter like as above mentioned. That will allow you directly interact with the appropriate engineering team, and make it more convenient for the engineering team to collect and categorize your suggestions.
As a workaround, we could clone the build definition via power shell script to call REST API.
Note: We need to change the original build definition name.
REST API
Get build definition:
GET https://dev.azure.com/{organization}/{project}/_apis/build/definitions/{definitionId}?api-version=6.0
Create build definition
POST https://dev.azure.com/{organization}/{project}/_apis/build/definitions?api-version=6.0
Power shell script
$connectionToken="{pat}"
$base64AuthInfo= [System.Convert]::ToBase64String([System.Text.Encoding]::ASCII.GetBytes(":$($connectionToken)"))
$BuildDefinitionInfoURL = "https://dev.azure.com/{org name}/{project name}/_apis/build/definitions/386"
$BuildDefinitionInfo = Invoke-RestMethod -Uri $BuildDefinitionInfoURL -Headers #{authorization = "Basic $base64AuthInfo"} -Method Get
Write-Host $BuildDefinitionInfo.name
$BuildDefinitionInfo.name = $BuildDefinitionInfo.name +" clone"
Write-Host $BuildDefinitionInfo.name
$body = $BuildDefinitionInfo | ConvertTo-Json -Depth 99
$createBuildDefinitionURL = "https://dev.azure.com/{org name}/{project name}/_apis/build/definitions?api-version=6.0"
$response = Invoke-RestMethod -Uri $createBuildDefinitionURL -ContentType "application/json" -Body $body -Headers #{Authorization=("Basic {0}" -f $base64AuthInfo)} -Method POST
Write-Host $response.id
Result:

Retrieving info from Azure Devops with Powershell

I'm trying to automate the deployment of releases in Azure Devops using the Azure Devops API with Powershell. I'm able to retrieve the last release definition, but I'm not able to extract a release for a specific environment.
I'm looking to retrieve the last 'prod' release in order to obtain the 'release ID', and then deploy the release to UAT or DEV using a HTTP 'PATCH' request.
I can hit a URL manually (example below), which gives me the last release for DEV (definitionEnvironmentId=1), and I know I could easily changed the environment ID to '12' for production, but I'd like to get this via an API call.
https://{redacted url}/{redacted}/{redacted}/_apis/release/deployments?api-version=6.0&definitionId=1&definitionEnvironmentId=1&$top=1
Any ideas if this is possible as I can't find any info on it?
You were using the correct Deployments - List Rest api. The reason you didnot get any info from the api call via powershell is because you didnot escape the special character $ for $top parameter in the url.
$ is a special character in powershell. You should escape it by adding a back tick '`' in the url. See below:
#add ` to $top parameter
$url = "https://{redacted url}/_apis/release/deployments?definitionId=3&definitionEnvironmentId=5&`$top=1&api-version=6.0"
$connectionToken="PAT"
$base64AuthInfo= [System.Convert]::ToBase64String([System.Text.Encoding]::ASCII.GetBytes(":$($connectionToken)"))
$response= Invoke-RestMethod -Uri $url -Headers #{authorization = "Basic $base64AuthInfo"} -Method Get
$releaseId = $response.value[0].release.id

LUIS Azure DevOps pipeline, how to create any samples?

There is a requirement, to create Azure Devops pipeline which could support version, add file into application, train, test & publish application into Stage & production.
How it can be done through Azure Devops Pipeline. Any documentation or steps could be helpful.
Thanks
A.Prabhuram
I have done something similar through Azure CLI (PowerShell version 2.X) tasks, but it is not straight forward. I haven't done all of the steps as you mention above, but hopefully this will give you what you need to further build on it.
As a baseline, the functions you need are outlined in the LUIS Programmatic API. You will need the LUIS key and app id for most requests, which you can get via
$LUISKEY= & az cognitiveservices account keys list -g "resourceGroupName" --name "LUISauthoringKeyName" --query key1 -o tsv
$header = #{"Ocp-Apim-Subscription-Key"="$LUISKEY"}
$res = Invoke-RestMethod -Uri "https://westus.api.cognitive.microsoft.com/luis/authoring/v3.0-preview/apps/?take=1" -Method 'Get' -Headers $header
$appid = $res.id
For brevity, I'm not repeating this code. But if you have separate tasks and/or agent jobs in your pipeline (as opposed to doing this as one script, which I do not recommend), you'll need to repeat these statements for each task. Do take note of the region and modify as needed for your authoring resource.
Obviously, to update your LUIS version, you need to have the model definition. I don't do this often since we are set up to use the same LUIS app in QA and PROD. So I just add a new version to the project repo if I need to run it through DevOps. Then I add the repo as an artifact for the release pipeline. But you should be able to use the Export Application Version API to get it programmatically, though I haven't tried personally. Here is what I did to add the new version:
$body = Get-Content '$(System.DefaultWorkingDirectory)/_AveryCreek_OEM_CSC_Bot/models/luis/AveryCreek OEM_CSC Team.json' | Out-String
Invoke-RestMethod -Uri "https://westus.api.cognitive.microsoft.com/luis/authoring/v3.0-preview/apps/$appid/versions/import" -Method 'Post' -Body $body -Headers $header
Note that this version is not additive and will completely replace your previous version (though you can revert). In other words, if you have changes to the previous version that are NOT incorporated into the version you are importing, they will be lost. This is one of the main reasons we do not use separate LUIS apps per environment (sidebar - you can use separate predicition resources so you don't use production capacity while testing, but all of the endpoint utterances still go through to the one application).
Once the version is imported, you need to train and publish it. I personally don't have any testing built in, but I'm sure you could build some calls via the LUIS Prediction API and check for expected results. To train, you first need to grab the version, then call the training endpoint.
$res = Invoke-RestMethod -Uri "https://westus.api.cognitive.microsoft.com/luis/authoring/v3.0-preview/apps/$appid/versions" -Method 'Get' -Headers $header
$version = $res[0].version
Invoke-RestMethod -Uri "https://westus.api.cognitive.microsoft.com/luis/authoring/v3.0-preview/apps/$appid/versions/$version/train" -Method 'Post' -Headers $header
The next part is the most tricky. You can't publish the app until it is done training. To mitigate the risk of trying to publish before it is ready, I have created a separate agent job in my "Train and Publish" task to delay it.
This is typically enough delay, but I also have a check on training status and throw an error if it is not ready. Here is the snippet to get and check status and then publish.
$status = Invoke-RestMethod -Uri "https://westus.api.cognitive.microsoft.com/luis/authoring/v3.0-preview/apps/$appid/versions/$version/train" -Method 'Get' -Headers $header
if ($status.details[0].status -ne "Success" -and $status.details[0].status -ne "UpToDate") { throw }
Invoke-RestMethod -Uri "https://westus.api.cognitive.microsoft.com/luis/authoring/v3.0-preview/apps/$appid/publish" -Method 'Post' -Body $body -Headers $header
And that should do it! As I mentioned, take care to make sure you define things like the LUIS Key and App ID in each task, as I have not repeated all of those values here. And you can add additional tasks to programmatically export the version (make sure you get the right key for your source app) and test the model as desired.

VSTS - Where has 'Allow Scripts to Access OAuth Token' gone?

I have VSTS builds that use the Powershell script to access the VSTS API, similar to that detailed in Microsoft's Documentation.
The document states:
To enable your script to use the build process OAuth token, go to the Options tab of the build definition and select Allow Scripts to Access OAuth Token.
After you've done that, your script can use to SYSTEM_ACCESSTOKEN
environment variable to access the VSTS REST API. For example:
Example:
$url = "$($env:SYSTEM_TEAMFOUNDATIONCOLLECTIONURI)$env:SYSTEM_TEAMPROJECTID/_apis/build-release/definitions/$($env:SYSTEM_DEFINITIONID)?api-version=2.0"
Write-Host "URL: $url"
$definition = Invoke-RestMethod -Uri $url -Headers #{
Authorization = "Bearer $env:SYSTEM_ACCESSTOKEN"
}
Write-Host "Definition = $($definition | ConvertTo-Json -Depth 1000)"
As detailed in Microsofts Documentation, I'm sure you used to go to Build > Options and click 'Allow Scripts to Access OAuth Token', but it is no longer there (see pic below).
When I try a build I get the following (which doesn't happen for my old builds):
Invoke-RestMethod :
{"$id":"1","innerException":null,"message":"TF400813: The user '' is
not authorized to access this
In addition, when I clone a build (which worked nicely when I did it 3 months ago), the property is set to false (it's set to true on the original).
UPDATE: If I export from VSTS, change that property and import again, it works, but I really need a solution without this sort of manual intervention.
How should this be done now please?
It is available in the agent phase now

How to use Release Definition REST API for VSTS?

I have been successfully able to use Release Definition API on our TFS 2015 Update 3 on prem instance using API Version "3.0-preview.1". But ever since I started testing this on VSTS, I am continuously getting a 404 error stating
Page not found And a long block of HTML.
I am using PowerShell to call the API. And I am creating the API request as mentioned in the documentation using Personal Access Token and Alternate credential method.
https://fabfiber.vsrm.visualstudio.com/DefaultCollection/ff213d65-d61d-447c-b39d-d16f21b18364/_apis/release/definitions?api-version=3.0-preview.1
Can someone let me know if I am missing something.
Try this code:
$vstsAccount = "[your vsts name]"
$user = "test"
$accessToken="[personal access token]"
$teamProject="[team project name]"
Function QueryWorkItem{
$base64AuthInfo = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(("{0}:{1}" -f $user,$accessToken)))
$uri="https://$vstsAccount.vsrm.visualstudio.com/defaultcollection/$teamProject/_apis/release/definitions?api-version=3.0-preview.1"
$result = Invoke-RestMethod -Uri $uri -Method Get -Headers #{Authorization=("Basic {0}" -f $base64AuthInfo)}
}
You may refer the blog :-
https://blogs.msdn.microsoft.com/chandananjani/2016/04/15/using-releasemanagement-rest-apis/
https://blogs.msdn.microsoft.com/chandananjani/2016/04/27/using-releasehttpclient-for-interacting-with-releasemanagement-service/
as well to know as how to use the release management REST API's.