0

Given a GitHub Action file:

name: Pull Request

on:
  pull_request:
    branches: [main]
    types: [opened, reopened, ready_for_review]

jobs:
  build_and_test:
    runs-on: ubuntu-latest

    steps:
      - name: Check out code
        uses: actions/checkout@v3

      - name: Run bash script
        run: |
          sh build.bash --a 3 --b 4

I'm unable to run the following build.bash file through GitHub Actions, instead getting the error build.bash: 17: 4: not found where line 17 corresponds with the line: while (( "$#" ));

#!/bin/sh
REPO_NAME="my-repo"

# Set defaults up top for clarity and define only once
A="1"
B="2"

usage()
{
    echo "Usage: build.sh [--a version] [--b version]"
    echo ""
    echo "--a 'a' version to use. Defaults to $A."
    echo "--b 'b' version to use. Defaults to $B"
    exit 1
}

while (( "$#" ));
do
    case "$1" in
        -h|--help)
            usage
        ;;

        --a)
            shift
            A="$1"
            shift
        ;;

        --b)
            shift
            B="$1"
            shift
        ;;

        # Unknown option
        *)
            echo "Unrecognized option: $1"
            usage
        ;;
    esac
done



echo CLI args: --a=$A --b=$B

When ran locally, everything prints out as expected:

sh build.bash --a 3 --b 4
# CLI args: --a=3 --b=4

How do I ensure that running the same command in GitHub Actions returns the same value while maintaining a similar logic for parsing CLI arguments

Jamie.Sgro
  • 821
  • 1
  • 5
  • 17
  • 3
    That looks like it's running in dash rather than bash, so bash extensions like `(( ))` aren't available. I don't know if it works in GitHub Actions, but try adding a shebang to the script. – Gordon Davisson Dec 14 '22 at 19:58
  • That's great insight @GordonDavisson, I'll have to look into dash more. I've added the shebang to the original question. After testing it, it still failed using `#!/bin/sh` – Jamie.Sgro Dec 14 '22 at 20:04
  • 2
    Use `#! /bin/bash` – Diego Torres Milano Dec 14 '22 at 20:12
  • @DiegoTorresMilano I've added that shebang, but it still returns `build.bash: 17: 4: not found`. The variable never gets updated within the switch statement, so if I ran `sh build.bash --a 3 --b 4` in GHA, it'll print out `CLI args: --a=1 --b=2` – Jamie.Sgro Dec 14 '22 at 20:42
  • The issue resolves if I run `bash build.bash --a 3 --b 4` instead of `sh build.bash --a 3 --b 4` in GHA however – Jamie.Sgro Dec 14 '22 at 20:44
  • You also need to add `shift` to your `*)` case -- otherwise a bad option is never shifted from the positional parameter list... Or simply move `shift` out of your `case` to below it in the loop so it will execute on all but `-h|--help)` which calls `exit` and never returns to the `case` statement. – David C. Rankin Dec 14 '22 at 20:50
  • 2
    If you have shebang and execute permission you don't need to invoke it as `bash build.bash`, just `build.bash` or `/path/to/build.bash` if the dir is not in PATH – Diego Torres Milano Dec 14 '22 at 20:52

1 Answers1

0

The issue resolves if we run bash build.bash --a 3 --b 4 instead of sh build.bash --a 3 --b 4 in the GHA .yml file. Correspondingly, we should update the shebang with #! /bin/bash at the top of the .bash file.

Shoutout to @GordonDavisson and @DiegoTorresMilano for helping resolve this issue

Jamie.Sgro
  • 821
  • 1
  • 5
  • 17
  • Do you mean `sh build.bash` where you typed `ba build.bash`? – Charles Duffy Dec 14 '22 at 21:42
  • No no, in GHA `sh build.bash` seems to use dash instead of bash. Either way it's failed because of that. It has only worked with explicitly `bash build.bash` – Jamie.Sgro Dec 14 '22 at 21:43
  • 1
    (mind, when you run _either_ `sh build.bash` or `bash build.bash`, you're overriding the shebang, forcing either `sh` or `bash` to be used instead; better practice is to drop the file extension _and_ the explicit interpreter and invoke the script itself as an executable so it chooses its own interpreter via the shebang) – Charles Duffy Dec 14 '22 at 21:44
  • Yes, `sh build.sh` _does_ use dash; that's what it's supposed to do on Debian-derived operating systems. This answer says "instead of `ba build.bash`". I don't know of `ba` as a standard command, so I assume it's a thinko. – Charles Duffy Dec 14 '22 at 21:44
  • And bash extensions like `(( ))` aren't available in dash, causing the above .bash file to fail when it hits the while loop – Jamie.Sgro Dec 14 '22 at 21:45
  • Yes, I know all of that. (This answer is correct: `bash` needs to be used!). My point is just that when you describe what the old code does you say it used `ba`. – Charles Duffy Dec 14 '22 at 21:45
  • Ohhhh, I was looking at the wrong aspect of the response. It's a typo for sure. Thanks for the heads up Charles – Jamie.Sgro Dec 14 '22 at 21:46
  • Another note: [commandname extensions considered harmful](https://www.talisman.org/~erlkonig/documents/commandname-extensions-considered-harmful/) – Charles Duffy Dec 14 '22 at 21:47
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/250423/discussion-between-jamie-sgro-and-charles-duffy). – Jamie.Sgro Dec 14 '22 at 21:47