Search code examples
bashgrepcontinuous-integrationgithub-actions

Bash grep in github action always exits with status 1


In a github workflow I am trying to check if the version of my project is SemVer compliant by using grep to check if the version match the regexp for SemVer. I tried different ways to do it and never managed to reproduce the behaving of the script I developped on my local shell. For example the following bash script successfully detect whether the TAG_NAME variable hold a SemVer version number:

    TAG_EXISTS="v3.0.12"
    SEMVER="^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-        Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$"

    grep -oE "$SEMVER" <<< "$TAG_EXISTS"
    ISSEMVER="$?"
    echo "$ISSEMVER"

returns 1 ...and for TAG_EXISTS="3.0.12" returns 0

But if I transfer this the following github workflow it alway returns 1 and I cannot find a way to got the result of grep or to asses the exit code of this operation:

    checkVersion:
    needs: tests
    runs-on: ubuntu-latest
    steps:
      - name: Checkout Repository
        uses: actions/checkout@v3
      - name: Set up Python
        uses: actions/setup-python@v2
        with:
          python-version: 3.x

      .....some other not related steps

      - name: Check for Existing Tag
        id: check_tag
        run: |
          set +x
          TAG_EXISTS=3.0.14
          SEMVER="^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-        zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$"
          grep -oE "$SEMVER" <<< "$TAG_EXISTS"
          ISSEMVER="$?"
          echo "$ISSEMVER"
          

How can I make a github action fail if the grep does not find a match and make it pass if grep find a match?

I tried as well to grep in a subshell:

RESULT=$( echo "$TAG_EXISTS" | grep -oE "$SEMVER")

Like this the pipeline always fail and exits with status 1


Solution

  • The regex in the post has a copy-paste error, I assume that in your actual script the part [0-9a- zA-Z-] is actually [0-9a-zA-Z-].

    With the regex engine used by BSD grep -E, the pattern matches.

    With the regex engine used by GNU grep -E, the pattern won't match, because it has constructs that don't work in BRE and ERE engines, only in PCRE (= Perl regexes) (thanks @EdMorton for the clarification). GNU grep supports PCRE with -P, and with that the pattern matches:

    grep -qP "$SEMVER" <<< "$TAG_EXISTS"
    

    (I changed -o to -q because it seems that's all you need here.)

    However, since -P is only available in GNU implementations, at this point it's better to just use Perl, to have a portable solution:

    perl -wln -e "/$SEMVER/ or exit(1)" <<< "$TAG_EXISTS"