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. |
Beta Was this translation helpful? Give feedback.
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. |
Beta Was this translation helpful? Give feedback.
-
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 “”. |
Beta Was this translation helpful? Give feedback.
-
Sorry, I just noticed your reply! Thanks very much for this, it resolves the issue. |
Beta Was this translation helpful? Give feedback.
-
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. |
Beta Was this translation helpful? Give feedback.
-
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 ? |
Beta Was this translation helpful? Give feedback.
-
@andreasplesch Thank you for your further investigation. I would recommand you to create an issue in the action toolkit repo . You could ask for adding an example for set-env and set-output with multiline values in this document. |
Beta Was this translation helpful? Give feedback.
-
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 at https://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: |
Beta Was this translation helpful? Give feedback.
-
Escaping of special characters already happened for javascript actions but does not for bash scripts. There is a plan to update documentation. |
Beta Was this translation helpful? Give feedback.
-
I have bumped into this exact issue, and found another solution: we can use For example: the variable - id: mystep
run: |
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 |
Beta Was this translation helpful? Give feedback.
-
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 to nuget.org or any nuget feeds). |
Beta Was this translation helpful? Give feedback.
-
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). |
Beta Was this translation helpful? Give feedback.
-
Thanks a lot for sharing, this unblocked me :slight_smile: |
Beta Was this translation helpful? Give feedback.
-
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
|
Beta Was this translation helpful? Give feedback.
-
Has this been fixed? I built a function to work around this, and now it displays the escape sequences. |
Beta Was this translation helpful? Give feedback.
-
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
|
Beta Was this translation helpful? Give feedback.
-
Note: You can change the output variable name by using |
Beta Was this translation helpful? Give feedback.
-
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 |
Beta Was this translation helpful? Give feedback.
-
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 |
Beta Was this translation helpful? Give feedback.
-
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 |
Beta Was this translation helpful? Give feedback.
-
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 |
Beta Was this translation helpful? Give feedback.
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.