如何解决JavaScript GitHub Action多行输出无法保存至GITHUB_ENV的问题?
问题:GitHub Action多行输出无法写入GITHUB_ENV
我实现了一个基于JavaScript的GitHub Action,功能是将.yml文件转换成特定格式的多行字符串,但无法将Action的输出保存到GITHUB_ENV。我已知多行输出处理存在问题,因此测试工作流使用了自定义EOF的解决方法,但仍失败。
JavaScript Action详情
输入的.yml文件示例:
all: options: - "--private-key /home/runner/.ssh/key" gather_info: options: # no extra options run: options: - "--extra-vars workspace=${{ github.workspace }}" - "--extra-vars path=/home/${{ secrets.USER }}/jars"
该Action预期输出:
<<all>> --private-key /home/runner/.ssh/key <<run>> --extra-vars workspace=${{ github.workspace }} --extra-vars path=/home/${{ secrets.USER }}/jars
JavaScript核心逻辑:
const outputString = convertYamlToString(file); core.setOutput('output', outputString);
测试工作流(尝试保存输出到GITHUB_ENV)
jobs: test: runs-on: ubuntu-latest steps: - name: Checkout code uses: actions/checkout@v3 - name: test id: test uses: ./ with: file: test-file.yml - name: save multiline output in github env run: | EOF=$(dd if=/dev/urandom bs=15 count=1 status=none | base64) echo "TEST_OUTPUT<<$EOF>>" >> "$GITHUB_ENV" ${{steps.test.outputs.output}} >> "$GITHUB_ENV" echo "$EOF" >> "$GITHUB_ENV" - name: print output run: echo "$TEST_OUTPUT"
运行错误信息
---- Step: 4_save multiline output in github env (failed) ---- ##[group]Run EOF=$(dd if=/dev/urandom bs=15 count=1 status=none | base64) EOF=$(dd if=/dev/urandom bs=15 count=1 status=none | base64) echo "TEST_OUTPUT<<$EOF>>" >> "$GITHUB_ENV" <<all>> --private-key /home/runner/.ssh/key <<run>> --extra-vars workspace=${{ github.workspace }} --extra-vars path=/home/${{ secrets.USER }} >> "$GITHUB_ENV" echo "$EOF" >> "$GITHUB_ENV" shell: /usr/bin/bash -e {0} ##[endgroup] /home/runner/work/_temp/123efec.sh: line 12: warning: here-document at line 4 delimited by end-of-file (wanted `all') /home/runner/work/_temp/123efec.sh: line 12: syntax error near unexpected token `newline' ##[error]Process completed with exit code 2. ##[error]Unable to process file command 'env' successfully. ##[error]Invalid value. Matching delimiter not found 'kim4lpoGcJjcupO'
解决方案
问题根源在于直接将多行输出插入bash脚本时,bash会把每行当成独立命令,且输出中的<<all>>会触发here文档解析,导致语法错误。以下是三种可行修复方案:
方案一:用printf统一输出内容
修改保存环境变量的步骤,通过printf一次性拼接所有内容,避免多行被bash拆分解析:
- name: save multiline output in github env run: | EOF=$(dd if=/dev/urandom bs=15 count=1 status=none | base64) printf 'TEST_OUTPUT<<%s>>\n%s\n%s\n' "$EOF" "${{steps.test.outputs.output}}" "$EOF" >> "$GITHUB_ENV"
方案二:在JavaScript Action中直接写入环境变量
无需在工作流中处理,直接在Action的JS代码里用core.exportVariable将结果写入GITHUB_ENV:
const outputString = convertYamlToString(file); core.setOutput('output', outputString); // 直接导出到环境变量 core.exportVariable('TEST_OUTPUT', outputString);
后续步骤可直接使用$TEST_OUTPUT,无需额外处理多行问题。
方案三:用cat加带引号的here文档
如果要保留原EOF方式,用引号包裹EOF标记,关闭bash的变量解析,避免输出中的特殊符号被误处理:
- name: save multiline output in github env run: | EOF=$(dd if=/dev/urandom bs=15 count=1 status=none | base64) echo "TEST_OUTPUT<<$EOF>>" >> "$GITHUB_ENV" cat <<"$EOF" >> "$GITHUB_ENV" ${{steps.test.outputs.output}} $EOF
内容的提问来源于stack exchange,提问作者SkogensKonung
相关产品推荐
相关产品推荐

