Set-output Truncates Multiline Strings#26288
-
Hi, I am using this code to create a release for one of our repositories: This works without any errors. However, the problem is, the description (the body parameter of the create_release action) is basically a small markdown document, so it’s a multiline string. The problem is that ::set-output is truncating everything except the first line. I can confirm that by echoing the description in the same action where it’s assigned and then referencing the description output variable in the next action. Could someone please advise how I can get this to work with a multiline string? Thanks. |
BetaWas this translation helpful?Give feedback.
All reactions
I got response from the team.
% and \n and \r can be escaped like below, the runner will unescape in reverse.
content="${content//'%'/'%25'}"content="${content//$'\n'/'%0A'}"content="${content//$'\r'/'%0D'}"Please try to add next three red lines to your yml, kindly let me know whether this could help.
- shell: bash id: release_description run: | description=$(./resources/get_release_description.sh ${{ steps.versioning.outputs.cli_version }}) echo $description<font color="#FF0000"> description="${description//'%'/'%25'}" description="${description//$'\n'/'%0A'}" description="${description//$'\r'/'%0D'}"</font>echo "::set-output…Replies: 20 comments 13 replies
-
I have reported your question to the appropriate engineering team for further evaluation. The team will review the feedback and notify me about the next steps. I will update here in time. Thank you for your understanding. |
BetaWas this translation helpful?Give feedback.
All reactions
-
I got response from the team. % and \n and \r can be escaped like below, the runner will unescape in reverse. Please try to add next three red lines to your yml, kindly let me know whether this could help. I tested in my side, after adding these lines, I can use echo" ${{ steps.release_description.outputs.description1 }}" to output multiple line value. Please pay attention to“”. |
BetaWas this translation helpful?Give feedback.
All reactions
❤️ 1
-
Sorry, I just noticed your reply! Thanks very much for this, it resolves the issue. |
BetaWas this translation helpful?Give feedback.
All reactions
-
It took me an hour to realize that multi-line strings were the issue for me, and then a few more hours to find this solution. It would be great if multi-line strings as values could be better supported, and documented. Here are a few observation. First, it is important to suppress word-splitting upon expansion in bash. This is easiest done by enclosing with double quotes: Similarly, word splitting also has to be suppressed when reading back: The double quotes are necessary. However, Workflows gets confused/truncates when dealing with an expanded multi-line value: This does not work for multi-line variables. The solution above uses a standard bash feature to expand and substitute characters: This essentially makes the value into a single line string. The github engineers then also knew that when reading back the variable in the workflow these escape values get substituted back to the actual characters: This results actually in a multi-line string. Unfortunately, this is not documented anywhere and comes across a bit as magic. If there are other substitutions it would be good to also document those. |
BetaWas this translation helpful?Give feedback.
All reactions
❤️ 6
-
Thanks so much posting this. I came across the same issue and found this rather obscure solution, after a lot of trial and error. A couple observation dealing with multiline values, mostly as a reminder on how this works. If using bash, it is important to suppress word splitting upon parameter expansion, to keep the line breaks. It is easiest with double quotes: Accessing the variable also invokes word splitting, which needs to be suppressed: However, set-output or set-env does not work with expanded multiline values: This does does not work, as Workflows somehow truncates or ignores the value. The solution above is to escape the newlines and other apparently unhandled characters using bash expansion and substitution. This makes the value effectively single line. The thing to notice is that Workflows substitutes the escaped characters back when the parameters is used in ${{ }}: Here the final value includes actual newlines. It would be great if this behaviour cold be documented somewhere. For example, are there other substitutions happening ? |
BetaWas this translation helpful?Give feedback.
All reactions
-
@andreasplesch Thank you for your further investigation. I would recommand you to create an issuein the action toolkit repo . You could ask for adding an example forset-env andset-output with multiline values inthis document. |
BetaWas this translation helpful?Give feedback.
All reactions
-
Thanks. Good to know that there is more in depth documentation available in the toolkit repo. I think a link from the main help page athttps://help.github.com/en/actions to this documentation could be helpful. Hm, it looks like newlines should already be escaped automatically: https://github.com/actions/toolkit/blob/master/packages/core/src/command.ts#L76 Anyways, here is the new issue in the repo: and a related issue: |
BetaWas this translation helpful?Give feedback.
All reactions
-
Escaping of special characters already happened for javascript actions but does not for bash scripts. There is a plan to update documentation. |
BetaWas this translation helpful?Give feedback.
All reactions
Uh oh!
There was an error while loading.Please reload this page.
Uh oh!
There was an error while loading.Please reload this page.
-
I have bumped into this exact issue, and found another solution: we can use For example: the variable -id:mysteprun:| mystr=$(< myfile) msg=$(printf '%s' "$mystr" | jq --raw-input --slurp '.') echo "::set-output name=msg::$msg"-run:| echo "${{ fromJSON(steps.mystep.outputs.msg) }}" Notice that this isn’t fool-proof, either: if the expanded string contains double quotes, the |
BetaWas this translation helpful?Give feedback.
All reactions
-
I also have an issue where I would like to output a list of paths and other data only if the action processes multiple files (to push them tonuget.org or any nuget feeds). |
BetaWas this translation helpful?Give feedback.
All reactions
-
Here is yet another potential work-around. This is working in a CI Action job of mine, which takes the content of a text file that contains test results and posts the whole content (which is multiline content) back to the relevant PR as a comment. The resulting comment accurately reflects the original newlines of the test result output.
This was inspired by the approach posted by @bewuethr. As far as I can tell in a couple days of usage, the python-based solution I am sharing does manage to handle double-quotes in the text (in addition to newlines). |
BetaWas this translation helpful?Give feedback.
All reactions
-
Thanks a lot for sharing, this unblocked me :slight_smile: |
BetaWas this translation helpful?Give feedback.
All reactions
-
For completeness, I want to point out that you can also use an environment variable via environment files for multiline text:Workflow commands for GitHub Actions - GitHub Docs |
BetaWas this translation helpful?Give feedback.
All reactions
-
Thanks alot, this worked for me. |
BetaWas this translation helpful?Give feedback.
All reactions
-
Has this been fixed? I built a function to work around this, and now it displays the escape sequences. |
BetaWas this translation helpful?Give feedback.
All reactions
-
Here’s my multi-line output solution which requires no changing of the data, however you do have to write it to a text file first. In this example I’m using it for stderr, but you can adapt it to any kind of multi-line output too
|
BetaWas this translation helpful?Give feedback.
All reactions
-
Note: You can change the output variable name by using |
BetaWas this translation helpful?Give feedback.
All reactions
-
For any lost souls in the future: If you’re setting output in a Docker container (like if your action is a .NET binary), not in the action YML, by just printing |
BetaWas this translation helpful?Give feedback.
All reactions
-
Also for anyone in the future with this issue, I JSON-encoded the content I needed to put into I kept getting errors with the multiline |
BetaWas this translation helpful?Give feedback.
All reactions
-
Wow, I had this problem for a year and I couldn't solve it. I believed this one the problem with slack action that wasn't supporting multiline comments. Now I have finally found this thread and found a solution for a problem in my script that existed more than a year |
BetaWas this translation helpful?Give feedback.
All reactions
Uh oh!
There was an error while loading.Please reload this page.
Uh oh!
There was an error while loading.Please reload this page.
-
For future reference: delimiter="$(openssl rand -hex 8)"echo"output-name<<${delimiter}">>"${GITHUB_OUTPUT}"echo"Some\nMultiline\nOutput">>"${GITHUB_OUTPUT}"echo"${delimiter}">>"${GITHUB_OUTPUT}" Note I'm using |
BetaWas this translation helpful?Give feedback.
All reactions
👍 21❤️ 33
-
It would be really nice to add those instractions tohttps://docs.github.com/en/actions/using-jobs/defining-outputs-for-jobs |
BetaWas this translation helpful?Give feedback.
All reactions
-
It's documented inworkflow commands. |
BetaWas this translation helpful?Give feedback.
All reactions
👍 1
-
When I used this in a composite action and created an output with it, my mutliline string lost all of its new lines. When I tried to echo it later, it was all on one line. How do I preserve the new lines? Or did I do something wrong? In the composite action it echos as a multiline string: outputs:TEXT:description:'Text from action'value:${{ steps.text_output.outputs.TEXT }}# Lower down in a step in a jobid:text_outputrun:| echo "$TEXT" echo 'TEXT<<EOF' >> $GITHUB_OUTPUT echo $TEXT >> $GITHUB_OUTPUT echo 'EOF' >> $GITHUB_OUTPUT In the workflow that uses the composite action, it echos the right text, but all on a single line: run:| echo "TEXT=${{ steps.the_text.outputs.TEXT }}" >> $GITHUB_ENV When I put it in the body of an issue using the GitHub cli, it also appears as just one line of text. |
BetaWas this translation helpful?Give feedback.
All reactions
-
This is probably because you don't quote the Try using |
BetaWas this translation helpful?Give feedback.
All reactions
Uh oh!
There was an error while loading.Please reload this page.
Uh oh!
There was an error while loading.Please reload this page.
-
See this Stack Overflow Q&A:I just assigned a variable, but echo $variable shows something else Else, any time you have multi-line values you want to set in the environment or as an output, youhave to use the |
BetaWas this translation helpful?Give feedback.
