Azure DevOps Tips: Handling Strings in YAML Pipelines

August 18, 2021
Cover Image

Yesterday I wrote a post about an error I was getting in an Azure DevOps YAML Pipeline script. The gist was that I had a long string in the YAML file and I was running into a problem using the YAML string literal pipe '|' syntax. Well, in my effort to understand what the specification was for that YAML syntax, I learned some stuff about managing strings in YAML -- especially, long and unwieldy string values.

In this article, I'm going to go over some techniques for handling long strings in Azure DevOps YAML Pipeline scripts. Here's the list of tips:

  1. How to Escape Double-Quotes in YAML
  2. Multi-line String Literals in YAML using '|'
  3. Concatenating Long Values in String Literals using '>'

Tip 1: How to Escape Double-Quotes in YAML

Let's say that you want to set a string value in a YAML pipeline script such as the "displayName" property.

stages:
- stage: build
  jobs:
    - job: build
      steps:
      - script: dotnet tool restore
        displayName: "dotnet tool restore"

Right now the value for displayName is set to "dotnet tool restore". But let's say that we want to set it to say the following:

  • dotnet tool restore for the "awesome" project

There are two options:

  1. Make the string value single quoted
  2. Escape the double quotes

Changing the displayName assignment to use a single-quoted string is arguably the easiest option. In the code below, I've changed the outer quotes to be single-quotes (') instead of double-quotes ("). Once I do that, I can have double-quotes inside of the string value without having to escape anything.

stages:
- stage: build
  jobs:
    - job: build
      steps:
      - script: dotnet tool restore
        displayName: 'dotnet tool restore for the "awesome" project'

But sometimes, changing to double-quotes doesn't help and you simply need to escape the double-quotes inside of an already double-quoted string. If you need to do this, then the escape character for in YAML is a backslash \.

stages:
- stage: build
  jobs:
    - job: build
      steps:
      - script: dotnet tool restore
        displayName: "dotnet tool restore for the \"awesome\" project"

If you're using escape characters, then the value goes from being "awesome" to \"awesome\".

Tip 2: Multi-line String Literals in YAML using '|'

Let's say that you need to set a multi-line string value as part of your Azure DevOps YAML Pipeline. A great example of where you'd want to do this is for a Manual Validation step. A manual validation step puts a pause in the execution of the pipeline so that a person (or persons) can be notified to do something like testing the application before resuming the pipeline or aborting the pipeline.

As part of the ManualValidation step, you can supply instructions that are displayed to the user. It's very common to need this instruction text to have multiple lines.

Instructions displayed for the user during a manual validation

Here's the YAML for the manual validation including the instructions value that's shown in the screenshot above.

- stage: wait_for_approval
  pool: server
  jobs:
  - job: waitForApproval
    displayName: 'wait for approval'
    timeoutInMinutes: 4320
    steps:
    - task: ManualValidation@0
      # displayName: 'manual validation'
      timeoutInMinutes: 1440 # task times out in 1 day
      inputs:
        notifyUsers: |
          benday@benday.com
        instructions: |
          Hi.
          This pipeline is waiting for your approval before continuing.
          Please validate the test env deployment and then click 'reject' or 'resume'.
        onTimeout: 'reject'

In order to get this multi-line text working, you're going to use the YAML literal string pipe | operator. Put the | after the variable name (in this case, "instructions: |") and then everything under that line becomes the value as long as it's indented by one space (' ') character. Each line in the value is preserved as a line in the value.

Tip 3: Concatenating Long Values in String Literals using '>'

Sometimes you need to build a string value that can get quite long. I run into this all the time when I need to update Azure App Service settings during my deployment using the AzureAppServiceSettings task. All the values you need to change get set on to the task's "appSettings" property and those values get set as a big string of JSON. If you need to set one value, it's not a big deal. But if you need to set a bunch of values, the YAML can get ugly and hard to manage.

The solution is to use a string literal with the "folded style". This is very similar to the multi-line string literal style that uses the pipe |, except that this approach combines all the lines into a single-line string. The operator you use is the greater than ('>') character.

- task: AzureAppServiceSettings@1
  inputs:
    azureSubscription: 'connection-to-yaml-test'
    appName: 'bdcyaml'
    resourceGroupName: 'rg-yamltest'
    appSettings: >
      [
      { "name": "MiscSettings__BuildVersionMessage", 
      "value": "$(Build.DefinitionName) - $(Build.BuildNumber)", 
      "slotSetting": true }, { "name": "ConnectionStrings__default", 
      "value": "$(connectionstring-prod)", "slotSetting": true }
      ]

Even though that literal has 6 lines in it, the '>' operator combines those lines into a single string. So that appSettings value becomes

[{ "name": "MiscSettings__BuildVersionMessage", "value": "$(Build.DefinitionName) - $(Build.BuildNumber)","slotSetting": true }, { "name": "ConnectionStrings__default", "value": "$(connectionstring-prod)", "slotSetting": true }]

(NOTE: if that value line wraps on your screen, trust me...that value will become one single line when executed by the Azure DevOps Pipeline Agent.)

One of the giant upsides of this technique is that the values are MUCH easier to read.

Summary

The big things to remember:

  • Strings in YAML don't have to be double-quoted...they can be single-quoted and that can save you some headaches
  • If you need to escape double-quotes in a string, the escape character in YAML is a backslash '\'
  • If you need multi-line string property values, use the pipe '|' operator to describe a string literal in YAML
  • If you need to build a long string property value but you want to keep the value readable, use the greater-than '>' sign to turn multiple lines of text into a single line value.

I hope this helps.

-Ben

-- Looking for help with your Azure DevOps Pipelines? Trying to figure out your CI/CD release pipelines? Want to find out how Azure DevOps Pipelines can help your Scrum and Kanban teams to be more productive? We can help. Drop us a line at info@benday.com.

Tags: azure-devops azure-devops-pipelines yaml