Build & Deployment Warnings in Azure DevOps

It's all in the details...

Posted by Niall Langley on Sunday, September 15, 2024

I use Azure DevOps with clients a lot, mostly for deploying data platforms. Sometimes have a task within our pipeline that fails, but the failure is actually something that is a problem, but not something that should stop a build or a deployment. Some examples of this situation might be

  • Deploying to an environment and configuring a user or group to have access to the table and the user or group does not exist
  • Sending an alert from a build or deployment, and the code to send the alert fails
  • Catching specific known errors, and dropping them down to a warning. I have come across situations where a tool has generated an error, but actually deployed the code cleanly due to a bug in the tool.

In these situations it can be useful to flag the build with a warning, to say someone should have a quick look and see if this is ok. If a build task goes red on a regular basis, and a team just ignores it and allows the error, trust in the whole CI/CD process is eroded.

Logs Formatting

When we run a pipeline, we can write messages to the logs for a task. For those of you who use a terminal a lot, the logs contain everything sent to the stdout and stderr streams. However there are some magic formatting strings we can use to change how the logs are displayed in the Azure DevOps UI. The following formatting commands can be be used to format a message in the output, for example changing the output colour or creating sections of output.

##[group]Beginning of a group
##[warning]Warning message
##[error]Error message
##[section]Start of a section
##[debug]Debug text
##[command]Command-line being run
##[endgroup]

So for example we can use these with echo in a bash task or Write-Host in a PowerShell task to make it easier to see messages write during the execution of our tasks. Yo can also use this from the T-SQL PRINT statement when running a post deployment script in a DacPac deployment. The following example shows the options available:

steps:
  - powershell: |
      Write-Host "##[group]Group the errors and warnings together"
      Write-Host "##[warning]Warning message"
      Write-Host "##[error]Error message"
      Write-Host "##[debug]Some debug info..."
      Write-Host "##[section]Start of a section"
      Write-Host "##[command]A command we will run"
      Write-Host "##[endgroup]"
      Write-Host "##[section]Start of another section"
      Write-Host "##[command]Another command we will run"

In the logs this will look like the animation below, where the grouped sections are collapsible.

The little triangle icon allows collapsing the group.
Logs can be formatted many ways, including into collapsible groups.

The problem with the formatting syntax is that the pipeline has green ticks against all the tasks, which means the stages and the overall pipeline will have green success ticks too.

The task is successful, but we formatted a warning and error.
Just because we formatted the output to look like a warning or error, doesn't mean we change the green success tick

Task Warnings & Errors

If we want to make the warnings or errors show on the main page like a unit test failure, we need to use a different syntax.

steps:
  - powershell: |
      Write-Host "##vso[task.logissue type=error]Here's an error log"
      Write-Host "##vso[task.logissue type=warning]Here's an warning log"
      Write-Host "##vso[task.logissue type=warning; sourcepath=some_file.py;linenumber=10; columnnumber=20; code=12345;]Here's another warning with some extra details!"

Here we have used the log issue command to log an issue into the pipeline execution results. The output is nicely coloured like before, but an errors or warnings we raise are shown on the main pipeline execution page.

The errors and on the main page for the build.
The errors show on the main page for the build.
The warnings show on the main page for the build too.
The warnings show on the main page for the build too.

However, we still have a green success tick against the task on the overall build. And if the build is linked to a pull request, the green tick will be there too.

Despite the errors and warnings showing on the main page, the task still has a green tick for success.
Despite the errors and warnings showing on the main page, the task still has a green tick for success.

Task Warning Status

What would be nice is if we could make the green tick change into something else when we have a warning. We don’t want a big red error cross, because it’s a warning not an error, but it would be nice to have some kind of visual notification that something was not quite as we expected. This can be done with another logging syntax, which we can combine with the one above.

##vso[task.complete result=SucceededWithIssues;]

This syntax can be used to set the result of a task without having to return a non zero return value from the process running. When we combine this with the previous example, adding the new syntax to the bottom, we get the following code.

steps:
  - powershell: |
      Write-Host "##vso[task.logissue type=error]Here's an error log"
      Write-Host "##vso[task.logissue type=warning]Here's an warning log"
      Write-Host "##vso[task.logissue type=warning; sourcepath=some_file.py;linenumber=10; columnnumber=20; code=12345;]Here's another warning with some extra details!"
      Write-Host "##vso[task.complete result=SucceededWithIssues;]"

When we run this we get the result below, which looks much better. The task has gone orange to represent the warning, and the pipeline execution has inherited that too and it shows on the main page. It would also show on a linked pull request if this ws a PR validation build. This makes it super easy to see when there are non-fatal problems with a build or deployment quickly and easily.

Now with the task status set to SucceededWithIssues, the icon looks like a warning and the pipeline execution bubbled that up to the overall status.
Now with the task status set to SucceededWithIssues, the icon looks like a warning and the pipeline execution bubbled that up to the overall status.

The pipeline execution page shows the warning status, and the individual warnings are listed too. Clicking a warning takes you directly to the task it was raised from.
The pipeline execution page shows the warning status, and the individual warnings are listed too. Clicking a warning takes you directly to the task it was raised from.

With this approach the next task in the job will still run, as the default condition is that it runs when the previous task has a status of either Success or SucceededWithIssues.

Roundup

There are a number of way to format warnings in the output from an Azure DevOps pipeline task. Depending on what you need, you can:

  • Colour and group output based on pre-defined format settings
  • Colour warnings and errors and promote them to show on the from page for a build.
  • Mark a tasks status as SucceededWithIssues to have it show with an orange warningicon, which will bubble up to the pipeline run status and will be visible from linked pull requests.

Any output from a task can be used to format the logging in this way, including from other terminals like bash (use echo), or other apps. For more information on the various logging commands and syntax check out the documentation.