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 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.
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.
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.
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.
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.