'In Azure Pipelines how to post a dynamic, multi-line comment generated in a previous step using GitHubComment task?

In an Azure Pipeline, the following will post a multi-line comment to a GitHub PR:

stages:
  - stage: MyStage
    jobs:
      - job: CommentOnPR
        steps:
          - task: GitHubComment@0
            displayName: Post comment to PR
            inputs:
              gitHubConnection: MyGitHubConnection
              repositoryName: $(build.repository.name)
              comment: |
                Here is a comment
                
                with multiple lines

The following will also post a multi-line comment:

variables:
  myComment: "Here is a comment\nwithmultiplelines"

stages:
  - stage: MyStage
    jobs:
      - job: CommentOnPR
        steps:
          - task: GitHubComment@0
            displayName: Post comment to PR
            inputs:
              gitHubConnection: MyGitHubConnection
              repositoryName: $(build.repository.name)
              comment: $(myComment)

The multi-line comment I am wanting to post is dynamically generated in a script kind of like the following located at scripts/my-script:

#!/bin/bash
output="# Changes

The following packages were updated:
"
for package_name in $(git diff --name-only origin/main packages/ | cut -d'/' -f2 | sort -u)
do
    output+="\n- $package_name"
done

export output

The output of this script then looks something like the following:

# Changes

The following packages were updated:

- some-package
- another-package
- etc.

(Note, my actual script is different, and is doing a few other things in addition to generating a multi-line string. I'm not asking about the contents of this script specifically.)

Given that setup, I would like my pipeline to run the scripts/my-script and use the output from it in the GitHub PR comment. However, everything I've tried either ends up with just the first line as the comment or a single line comment where all the \ns are shown literally.

I tried this:

stages:
  - stage: MyStage
    jobs:
      - job: CommentOnPR
        steps:
          - bash: |
             source scripts/my-script
             echo "##vso[task.setvariable variable=myComment]$output" 
          - task: GitHubComment@0
            displayName: Post comment to PR
            inputs:
              gitHubConnection: MyGitHubConnection
              repositoryName: $(build.repository.name)
              comment: $(myComment)

But the comment in GitHub was just the first line:

# Changes

I then tried changing scripts/my-script to only use \ns:

#!/bin/bash
output="# Changes\n\nThe following packages were updated:\n"
for package_name in $(git diff --name-only origin/main packages/ | cut -d'/' -f2 | sort -u)
do
    output+="\n- $package_name"
done

export output

The comment in GitHub was all a single line:

# Changes\n\nThe following packages were updated:\n\n- some-package\n- another-package \n- etc.

I can't find the magic combination where I can dynamically generate a multi-line string in a step and then have the subsequent GitHubComment task display it properly. I'm fairly new to bash scripting and Pipelines. Any ideas? Thank you.



Solution 1:[1]

I had a colleague point me to https://developercommunity.visualstudio.com/t/multiple-lines-variable-in-build-and-release/365667 which linked out to VSTS Release multi-line variable. For one workaround, we can add a string substitution in the pipeline that replaces \ns with %0D%0As:

stages:
  - stage: MyStage
    jobs:
      - job: CommentOnPR
        steps:
          - bash: |
             source scripts/my-script
             formatted_output=${output//\\n/%0D%0A}
             echo "##vso[task.setvariable variable=myComment]$formatted_output" 
          - task: GitHubComment@0
            displayName: Post comment to PR
            inputs:
              gitHubConnection: MyGitHubConnection
              repositoryName: $(build.repository.name)
              comment: $(myComment)

I'm not going to mark this answer as accepted, because I'm still hoping someone has a better way...

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 robertwbradford