How to capture a Cake build failure within an Azure DevOps task? - powershell

For the reasons that are beyond the scope of this discussion, I have the following Azure DevOps setup which is being used to build some .NET library:
An Azure DevOps Powershell task:
- task: PowerShell#2
displayName: 'My task'
inputs:
targetType: filePath
filePath: 'build_cake.ps1'
arguments: '<my arguments>'
The build_cake.ps1 script, executed by the DevOps task, which invokes Cake passing it the build.cake script:
try {
Invoke-Expression "& <invoke Cake with build.cake>"
}
catch {
exit 1;
}
The build.cakescript which sets up some parameters and calls Build.RunDotNetCore:
Build.SetParameters(...);
Build.RunDotNetCore();
The RunDotNetCore call internally executes the dotnet build command. When that build fails for whatever reason, the error is not captured and/or propagated all the way back, so the Azure DevOps task (1) still happily reports successful execution.
I'm looking for a way to fix this.
At this point I'm not even sure whether the issue/solution is on the Cake side or on the Powershell side.
As my example shows, I have tried to wrap Invoke-Expression in a try/catch block but that didn't fix anything. I have also tried checking the $LASTEXITCODE code right after the Invoke-Expression call. (I guess $LASTEXITCODE is not supposed to be set anyway, since I'm invoking an external application and not a commandlet.)
To be clear, I'm not looking for an alternative solution (for example, to replace the existing setup with an equivalent Cake Azure DevOps task). I need to fix this particular setup with minimal changes, if possible.

The boostrapper I'm using looks like this and is confirmed working with Azure DevOps
$ErrorActionPreference = 'Stop'
dotnet tool restore
if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE }
dotnet cake #args
if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE }
Above assumes your using a .NET tool manifest to version Cake, if you have Cake installed already on the agent you can skip the dotnet tool restore part.
Versioning Cake with a tool-manifest is preferred though as that ensures same version of Cake used locally and remote.
Installing Cake via tool manifest is done using dotnet cli in your repository root.
dotnet new tool-manifest
dotnet tool install Cake.Tool
and then add & commit in the .config/dotnet-tools.json file created.
Then when cloning the repo it's
dotnet tool restore
dotnet cake
And it'll fetch and execute the right version of Cake.

Related

Azure Devops CLI Task - show output

I am using the Azure CLI task Version 2. The only problem, i need some output so that it´s showed as part of the pipeline run. The task however wraps all inline scripts in a script file so that i can´t see the output. How can I achieve that?
Thank you. It works now, you are right, I used the Bash#3 task instead. I use the output from the AzCLI task to define a pipeline variable and the bash task to print it.
service=$(kubectl get service --namespace $(aks-namespace) -o jsonpath='{.items[0].status.loadBalancer.ingress[0]}')
echo "##vso[task.setvariable variable=serviceip]$service"

Azure DevOps Pipeline - Using YAML, how can I have the build number set to dynamically change, based on the version defined in a different file? [duplicate]

In Azure DevOps, I created a Build. In that Build I created a ProjectBuildNumber Pipeline variable that is Settable at queue time. That variable is then used under Options -> Build number format to set my build number displayed in Azure.
However, I am trying to make that ProjectBuildNumber variable settable in the code I am building/deploying. Is there a way I can have a Task in my Build to update that ProjectBuildNumber and update the Build number in Azure DevOps?
Is there a way I can have a Task in my Build to update that ProjectBuildNumber and update the Build number in Azure DevOps?
The answer is yes.
You could add a Inline Power-Shell task in your build definition to update the value of ProjectBuildNumber and then update the build number base on the it:
Write-Host "##vso[task.setvariable variable=ProjectBuildNumber;]YourUpdateValue"
Write-Host "##vso[build.updatebuildnumber]xxx.$(ProjectBuildNumber).xxx.xxx"
Check the Logging Command during the build for some more details:
Besides, if you want to update the value of a Pipeline Variable on the UI/web portal, you need the REST API (Definitions - Update) to update the value of the build pipeline definition variable from a build task.
There is a very similar thread, you can check the answer for the details:
How to modify Azure DevOps release definition variable from a release task?
Note:Change the API to the build definitions:
PUT https://dev.azure.com/{organization}/{project}/_apis/build/definitions/{definitionId}?api-version=5.0
Hope this helps.
We can update Build Number in Azure Devops via two ways .
One from Option Section/Tab and 2nd Via PowerShell Scripts.
To update the build number from Power shell Script.. We need to add following script..
Write-Host "##vso[build.updatebuildnumber]$(VersionNumber).$(VersionRevision)"
Here we have used 2 variables : VersionNumber and VersionRevision.
We need to add 2 variables in PipeLine Configurations..
VersionNumber will be the desired number and VersionRevision is the counter number that will be updated every time, when ever we will create a new build.
Please check the complete demonstration from You tube video
https://youtu.be/WBmFTmzopiQ
Have created power shell task for that
# replace existing Build.BuildNumber with
# NAME_2.1.2.54_20211220.16_345
- task: PowerShell#2
displayName: 'Update Version Number'
inputs:
targetType: 'inline'
script: |
$lines = Get-ChildItem ".\Project\My Project\AssemblyInfo.vb"
$match = $lines | Select-String -Pattern "\<Assembly\:\s+AssemblyVersion\(""(\d+\.\d+\.\d+\.\d+)""\)\>"
$version = $match.Matches[0].Groups[1].Value
[Version]::Parse($version) # validate
$tag = "NAME_$($version)_$(Build.BuildNumber)_$(Build.BuildId)"
Write-Host "##vso[build.updatebuildnumber]$tag"
Check out the Microsoft documentation on this: Variables
Depending on your operating system you can add a Powershell/Batch/Bash Task and change the variable.
Edit: After some research it appears that the change of the variable will show up in the following task. Take a look at this issue Update environment variables using task.setvariable in a bash script does not work

Run CURL GET commands in Azure Pipeline Task

I am looking to run some CURL commands (GET mainly) in an Azure Pipeline Task to list/download some artifacts from a few sources. Would appreciate some help with any examples of how I can achieve this through a Pipeline Task using CURL, Powershell, Windows Command or any other appropriate method.
Thanks
The easiest way to do this is to use the Command Line task. For a YAML pipeline, this would look like
- task: CmdLine#2
displayName: Curl Example
inputs:
script: 'curl google.com'
For a "Classic UI" pipeline, it would look like
Note that for either of these options you must be using a Linux build agent. If you are using a Windows build agent, you should use Invoke-WebRequest.
curl in PowerShell uses Invoke-WebRequest. From PowerShell 3.03.0 and above, we could use Invoke-WebRequest, which is equivalent to curl. You could refer to this doc for more details
Sample script in the power shell
Invoke-WebRequest -URI https://www.educative.io/
In addition, in the Azure DevOps Artifacts, the URL contain special characters, we need use "" contain it. Such as
https://dev.azure.com/{Org name}/{project name}/_packaging?_a=feed+"&"+feed={feed name}

azure pipelines - how to break / cancel a release based on a conditional task result

I have a release pipeline which is triggered by CI where I want to push a new version of a nuget package if that version does not exist yet.
For that I have a simple command line task which checks whether that nuget is present on nuget.org and stores the result in an environment variable.
I can then set the condition for next steps which will only execute the step if that value variable is true.
This works all fine, however I wonder how can I simply stop the release process and skip all subsequent steps, without setting their condition one by one.
Also, to that, how can I set the build status to 'Cancelled' by a task?
You can cancel current Build or Release with a PowerShell task:
Write-Host "##vso[task.setvariable variable=agent.jobstatus;]canceled"
Write-Host "##vso[task.complete result=Canceled;]DONE"
So in the release pipeline add a Powershell task with the above code and in the custom condition configure it to run only if you don't want to upload the NuGet, after this task all the tasks after it will be canceled.
PS - The status will be "Succeeded" but in fact the Build/Release will be canceled.
If you want must to see the status "Canceled" you need to use Rest API, check this PowerShell script.

How to use output variable of Deploy to Kubernetes task in Azure pipeline (VSTS)

I am new to VSTS and Azure Kubernetes. I am building a VSTS CD pipeline. I have added a Deploy to Kubernetes task in my pipeline. I am executing the get command and trying to store the output in the output variables (which is available at the bottom of the Deploy to kubernetes task). I have set the variable name.
I am trying to fetch the value of the above output variable. I have used command line task to set a value to the variable as mentioned below
echo '##vso[task.setvariable variable=myStatusVar;isSecret=false;]$(myvar)'
where myvar is the variable, which is set in the Deploy to kubernetes task as output variable.
After that in another command line task, I am trying to access the myStatusVar variable value, but when I execute the release pipeline, it shows the message:
myvar command not found
Can anyone let me know, how to use the output variable of the Deploy to kuberentes task of VSTS pipeline?
As stated in the comments your variable is 'exposed' as 'myvar.KubectlOutput'
the way you are able to use it in scripts differs based on type of scripting you are doing:
Batch script: %MYVAR_KUBECTLOUTPUT%
PowerShell script: $env:MYVAR_KUBECTLOUTPUT
Bash script: $MYVAR_KUBECTLOUTPUT
Azure Devops 'designer view': $(myvar.KubectlOutput)
For more details on this see the documentation on using variables in Azure DevOps: https://learn.microsoft.com/en-us/azure/devops/pipelines/process/variables?view=azure-devops&tabs=yaml%2Cbatch