Unexpected "(" (expecting "then")

I do not understand the error message. What exactly is the problem here?

$ if [[ $CI_COMMIT_TAG =~ (v[0-9]+\.[0-9]+\.[0-9]+)_(dev|prod) ]] ; then export VERSION=${BASH_REMATCH[1]};export STAGE=${BASH_REMATCH[2]}; fi
/busybox/sh: eval: line 127: syntax error: unexpected "(" (expecting "then")
Cleaning up project directory and file based variables

We use our own Gitlab installation with version 15.5.2. Unfortunately, I can’t say what kind of runner we use.

 before_script:
    - if [[ $CI_COMMIT_TAG =~ (v[0-9]+\.[0-9]+\.[0-9]+)_(dev|prod) ]] ; then export VERSION=${BASH_REMATCH[1]};export STAGE=${BASH_REMATCH[2]}; fi

My first regex try was

if [[ "${CI_COMMIT_TAG}" =~ (v[[:digit:]]{1,3}.[[:digit:]]{1,3}.[[:digit:]]{1,3})_(dev|prod)$ ]]; then

But generates the same error message

I suspect the busybox/sh impl does not support the Bash RE matching via the [[ ]] test. As in my Bash 4.4.20, your syntax is correct (for my version of Bash). IHTH. I’ll try the busybox after my 10am call…

Yep: using the latest busybox docker image:

/ # /bin/sh --help
/bin/sh --help
BusyBox v1.34.1 (2022-11-17 19:57:29 UTC) multi-call binary.
/ # tag='v11.99.00_dev'
tag='v11.99.00_dev'
/ # if [[ $tag =~ (v[0-9]+\.[0-9]+\.[0-9]+)_(dev|prod) ]] ; then
if [[ $tag =~ (v[0-9]+\.[0-9]+\.[0-9]+)_(dev|prod) ]] ; then
/bin/sh: syntax error: unexpected "(" (expecting "then")
/ # 
1 Like

What @SteveHespelt said is that you running in busybox (you’ll have to ask the administrator of your local GitLab runner(s) why, there’s several possibilities), and as a consequence you have ther implementation of sh, and that does not support the [[ syntax (that is a bash-invention - it is also supported in other shells these days, but that doesn’t help you).

You’ll need to either

  • find a way to express your test in a way that busybox’ sh understands.
  • run this in a shell that supports your syntax (you’ll have to talk to someone with knowledge of your local setup to find out if that is even possible)

I’m not good at shell scripting (and don’t have a busybox at hand), so suggesting a way to express your test would involve a lot of guessing from my side, so if you can’t fix it yourself, you’re (probably) better off hoping someone else sees this.

1 Like

Thanks for the input. I have now solved it as follows.

I use a bash image and write the values in a file (build.env).

Init:
  image: bash:5.2.12
  stage: initialise
  rules:
    - if: $CI_COMMIT_TAG =~ /(v\d{1,3}\.\d{1,3}\.\d{1,3})_(dev|prod)$/
      exists:
        - Dockerfile
  script:
    - echo ${CI_COMMIT_TAG}
    - >
      if [[ "${CI_COMMIT_TAG}" =~ (v[[:digit:]]{1,3}.[[:digit:]]{1,3}.[[:digit:]]{1,3})_(dev|prod)$ ]]; then
        echo "VERSION=${BASH_REMATCH[1]}" >> build.env
        echo "STAGE=${BASH_REMATCH[2]}" >> build.env
      fi
  artifacts:
    reports:
      dotenv: build.env

I define dipendency to init block and use now the two variables $VERSION and $STAGE.

create-publish-image:
  stage: publish
  rules:
    - if: $CI_COMMIT_TAG =~ /(v\d{1,3}\.\d{1,3}\.\d{1,3})_(dev|prod)$/
      exists:
        - Dockerfile
  dependencies:
    - Init
    - Build_Code
  image:
    name: kaniko-project/executor:v1.6.0-debug
    entrypoint: [ "" ]
  script:
    - echo "$VERSION"
    - echo "$STAGE"
   .......................