Wandalen / wretry.action

Retry action for Github CI
MIT License
93 stars 20 forks source link

Multiline bash command with if statement is not working #127

Closed frjtrifork closed 5 months ago

frjtrifork commented 7 months ago

We have a number of existing workflows we would like to use the wretry.action for. Some of them are using if-statements in a standard run: | block - which is working fine and have been for a long time.

When I convert one of the simpler ones to a command block and run it - I get an error saying the if statement is not closed.

      - name: Test mvn command
        uses: Wandalen/wretry.action@master
        with:
          attempt_limit: 2
          command: |
            if ${{ inputs.deploy-package }}; then
              CMD="release:prepare release:perform"
            else
              CMD="release:prepare"
            fi
            echo "mvn command = $CMD"

The ${{ inputs.deploy-package }} is defined and evaluates to false.

The workflow output:

Run Wandalen/wretry.action@master
  with:
    attempt_limit: [2](https://github.com/my-repo/actions/runs/7795743091/job/21262558660#step:9:2)
    command: if false; then
    CMD="release:prepare release:perform"
  else
    CMD="release:prepare"
  fi
  echo "mvn command = $CMD"

    attempt_delay: 0
  env:
    JAVA_HOME: /opt/hostedtoolcache/Java_Temurin-Hotspot_jdk/21.0.2-13/x64
    JAVA_HOME_21_X64: /opt/hostedtoolcache/Java_Temurin-Hotspot_jdk/21.0.2-13/x64
Run Wandalen/wretry.action@v1.3.0_js_action
  with:
    command: if false; then
    CMD="release:prepare release:perform"
  else
    CMD="release:prepare"
  fi
  echo "mvn command = $CMD"

    attempt_limit: 2
    attempt_delay: 0
    env_context: {
    "JAVA_HOME": "/opt/hostedtoolcache/Java_Temurin-Hotspot_jdk/21.0.2-1[3](https://github.com/my-repo/actions/runs/7795743091/job/21262558660#step:9:3)/x6[4](https://github.com/my-repo/actions/runs/7795743091/job/21262558660#step:9:4)",
    "JAVA_HOME_21_X[6](https://github.com/my-repo/actions/runs/7795743091/job/21262558660#step:9:6)4": "/opt/hostedtoolcache/Java_Temurin-Hotspot_jdk/21.0.2-[13](https://github.com/my-repo/actions/runs/7795743091/job/21262558660#step:9:13)/x64"
  }

....
github context dump removed
....
sh: 1: Syntax error: end of file unexpected (expecting "fi")
sh: 1: Syntax error: end of file unexpected (expecting "fi")
Error: Process returned exit code 2
Launched as "if false; then"
Launched at "/home/runner/work/my-repo/my-repo"
Attempts exhausted, made 2 attempts :
Attempt #1 started at : 08:45:56 GMT+0000 (Coordinated Universal Time)
Attempt #2 started at : 08:45:56 GMT+0000 (Coordinated Universal Time)

Do I need to specify something about the shell in order to be able to run such a command block with an if-statement?

dmvict commented 7 months ago

Hello @frjtrifork

I need to check it. And maybe, update the action. I don't have much time for additional work, sorry for it.

You can try backslashes at the end of command lines. I think it should help https://github.com/Wandalen/wretry.action/issues/79

frjtrifork commented 7 months ago

ok, thank you for the suggestion. I can confirm that the if-statement does work if I escape newlines (and add a ; after each command) when running in Github actions. 👍

I tried reproducing the problem locally. But for some reason locally it works fine both with and without the escaped line endings. The commandsForm function called in the block below is the one from the src/Common.js file

const commandEscapedNewlines = [
    '|',
    'if false; then \\',
    'export FOO1=foo;\\',
    'else \\',
    'export BAR1=bar; \\',
    'fi; \\',
    'echo Result with escaped line endings=$FOO1$BAR1',
]
const commands1 = commandsForm( commandEscapedNewlines );
fs.writeFileSync('script-escaped.sh', commands1.join('\n')); // emulate what Retry.js writes to script.sh
console.log('bash --noprofile --norc -eo pipefail script-escaped.sh');

Output:
Result with escaped line endings=bar

const commandNoEscapes = [
    '|',
    'if false; then',
    'export FOO2=foo',
    'else',
    'export BAR2=bar',
    'fi',
    'echo Result=$FOO2$BAR2',
]
const commands2 = commandsForm( commandNoEscapes );
fs.writeFileSync('script-not-escaped.sh', commands2.join('\n')); // emulate what Retry.js writes to script.sh
console.log('bash --noprofile --norc -eo pipefail script-not-escaped.sh');

Output:
Result=bar

Maybe it is due to the github runner having another bash version or something.

When running locally on macOS I have bash --version GNU bash, version 3.2.57(1)-release (arm64-apple-darwin23)

and the version in the ubuntu@latest runner currently is bash --version GNU bash, version 5.1.16(1)-release (x86_64-pc-linux-gnu)

UPDATE: I did a very small test running the scripts, using bash-5 in docker - and both scripts work just fine:

docker run -v ${PWD}:/app -w /app bash:5.1-alpine3.19 bash --noprofile --norc -eo pipefail script-escaped.sh
Result with escaped line endings=bar
docker run -v ${PWD}:/app -w /app bash:5.1-alpine3.19 bash --noprofile --norc -eo pipefail script-not-escaped.sh
Result=bar

I'm running out of ideas as to why it only fails when running in a Github actions workflow.

Now that I have a workaround it is fine with me if this issue is closed. 👍

dmvict commented 6 months ago

Hello @frjtrifork

You can try new version v1.4.5. It should solve your issue.

dmvict commented 6 months ago

Hello @frjtrifork . Please, try new version and give me a feedback. I'll wait for a while and close the issue.