0

I have a GitLab job with a bash if statement that looks like this

script:
  - echo $NEW_VERSION
  - export STAGE=staging
  - |-
    if [[ $(expr match "$NEW_VERSION", '([0-9]+)\.([0-9]+)\.([0-9]+)$') != 0 ]]; then 
      export STAGE=production; 
    fi
  - echo $STAGE

The variable $NEW_VERSION comes from a previous step. The content of this variable is a semantic version string like 1.0.0 or 1.0.1-develop.1. If this variable is a prerelease (it contains the develop suffix) I want to set the $STAGE to staging otherwise to production.

My problem is that no matter which content the $NEW_VERSION variable has, $STAGE is always set to staging.

If I execute the script on my local mac the value is set right.

Here the log output:

$ echo $NEW_VERSION
11.0.0
$ export STAGE=staging
$ if [[ $(expr match "$NEW_VERSION", '([0-9]+)\.([0-9]+)\.([0-9]+)$') != 0 ]]; then  # collapsed multi-line command
staging

Has anyone experienced a similar problem or has an idea why this solution dosen't work?

Markus
  • 1,909
  • 4
  • 26
  • 54
  • if you just need to match on the string `develop` could you use `[[ "${NEW_VERSION}" == *develop* ]]` or `[[ "${NEW_VERSION}" =~ develop ]]`? – markp-fuso Aug 23 '21 at 12:47
  • Yeah, this was my first approach too but the =~ operator dose not exists for bash. Read here for more information: https://stackoverflow.com/a/63124383/10115037 – Markus Aug 23 '21 at 12:50
  • what does `bash --version` return? – markp-fuso Aug 23 '21 at 13:18
  • strange. It says `eval: line 120: bash: not found` – Markus Aug 23 '21 at 16:34
  • 1
    @Markus Sounds like you're not actually running under bash, or even have bash available. bash certainly does have `=~`, it was [added in version 3.0-alpha](https://wiki.bash-hackers.org/scripting/bashchanges#conditional_expressions_and_test_command)). The answer you linked about `=~` isn't actually about bash, but the BusyBox version of ash (which was apparently being passed off as bash?) – Gordon Davisson Aug 23 '21 at 18:34

3 Answers3

2

It's simpler to use grep.

if printf "%s\n" "$NEW_VERSION" | grep -xq '[0-9]\+\.[0-9]\+\.[0-9]\+'; then
KamilCuk
  • 120,984
  • 8
  • 59
  • 111
1

It seems to be caused by a wrong syntax in the regular expression and the extra comma after "$NEW_VERSION" (which is appended to the value of the variable). This version works as expected.

echo $NEW_VERSION
export STAGE=staging
if [ "$(expr match "$NEW_VERSION" '^[0-9]\+\.[0-9]\+\.[0-9]\+$')" != 0 ]; then
    export STAGE=production
fi
echo $STAGE
Davide Madrisan
  • 1,969
  • 2
  • 14
  • 22
0

I prefer the pure bash version with =~ operator. Verify that you are really use bash if does'nt work.

echo $NEW_VERSION
export STAGE=staging
if [[ "${NEW_VERSION}" =~ ([0-9]+)\.([0-9]+)\.([0-9]+)$ ]]; then
    export STAGE=production
fi
echo $STAGE

Remarks:

  • Use double brackets with =~ operator
  • Do not put regular expression in quotes

Bonus:

  • =~ is an internal operator, so it's faster than a expr call

(tested with GNU bash, version 5.0.17)

Arnaud Valmary
  • 2,039
  • 9
  • 14