Gitlab-ci docker executor before_script as shell executor

Is it possible to run before/after_script as shell executor
i wrote shell script which should upload/load “assets” from gitlab generic package repository
but gitlab runner is set as docker executor which runs Cypress/browsers docker image
and this doesn’t work any more i am not exactly sure if my approach still would work as i am new to docker and gitlab even if before/after_script would run in shell as i am not sure if docker would load the “assets”

Hi,

before_script is no different to script section - it’s only for readability purposes (to logically separate your script). So, you can use it with a shell executor.

I’m not sure what you’re trying to achieve - it would be the best if you post your .gitlab-ci.yml file and desired behavior.

Just remember - one job is run by 1 executor (either docker or shell - your job will be picked up by runner based on tag) - more on executors you can find on official docs. (You cannot run your before_script with one type of executor and script with another)

That being said, docker executor does not limit you on executing bash/shell scripts. However, which type of shell will be used depends on your docker image (on linux based distros, it’s normally either /bin/bash or /bin/sh). So, you can use your docker executor, with cypress docker image, and download your assets in before_script without issues, assuming you have the right tools installed in your docker image (e.g. wget or curl).

Thank you for reply
the Cypress/browsers docker image has ENTRYPOINT [“npx”,“cypress”, “run”]
so i am not exactly sure how i can execute my shell script there i expect i would need to write my own Dockerfile is that correct ?
my gitlab-ci.yml looks like this

stages:
  - test

test_base:
  image: cypress/browsers:node-22.14.0-chrome-133.0.6943.53-1-ff-135.0-edge-133.0.3065.59-1
  stage: test
  script:
    # curl packages and get package_id
    # - |
    #   PACKAGE_ID="$(curl --header "JOB-TOKEN: $CI_JOB_TOKEN" \
    #            "https://gitlab.COMPANY.sk/api/v4/projects/46/packages" | jq '.[0] | .id')"
    # - echo "PACKAGE_ID $PACKAGE_ID"
    # # remove package
    # - |
    #   curl --request DELETE --header "JOB-TOKEN: $CI_JOB_TOKEN" \
    #            "https://gitlab.COMPANY.sk/api/v4/projects/46/packages/$PACKAGE_ID"
    # install dependencies
    - npm i
    # run Cypress tests
    - npx cypress run --browser chrome
    # - ls
    # - ls cypress/snapshots/
    # - ls cypress/snapshots/signIn.spec.cy.ts
    # - |
    #   for file in ./cypress/snapshots/signIn.spec.cy.ts/*; do
    #     if [ -f "$file" ]; then
    #       filename=$(basename "$file")
    #       echo "${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/packages/generic/base_image/1.0.0/$filename"
    #       curl --header "JOB-TOKEN: $CI_JOB_TOKEN" \
    #            --upload-file "$file" \
    #            "${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/packages/generic/base_image/1.0.0/$filename"
    #       echo "Uploaded: $filename"
    #     fi
    #   done
  only:
    variables:
      - $SCHEDULE_NIGHTLY_VARIABLE_X
  artifacts:
    when: always
    paths:
      - cypress/screenshots/**/*.png
      - cypress/videos/**/*.mp4
    expire_in: 1 day

test:
  image: cypress/browsers:node-22.14.0-chrome-133.0.6943.53-1-ff-135.0-edge-133.0.3065.59-1
  stage: test
  script:
    # - |
    #   FILES=("HomePage375x667.snap.png" "HomePage768x1024.snap.png" "HomePage1440x900.snap.png")
    #   for file in "${FILES[@]}"; do
    #     curl --location --header  "JOB-TOKEN: $CI_JOB_TOKEN" \
    #          --output "$file" \
    #          --create-dirs \
    #          "${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/packages/generic/base_image/1.0.0/$file"
    #     echo "Downloaded: $file"
    #   done
    # - ls
    # - mkdir ./cypress/snapshots/
    # - mkdir ./cypress/snapshots/signIn.spec.cy.ts/
    # - mv HomePage375x667.snap.png HomePage768x1024.snap.png HomePage1440x900.snap.png cypress/snapshots/signIn.spec.cy.ts/
    # - ls
    # - ls cypress/snapshots/signIn.spec.cy.ts
    # install dependencies
    - npm i
    # run Cypress tests
    - npx cypress run --browser chrome
  only:
    variables:
      - $SCHEDULE_VARIABLE_X
  artifacts:
    paths:
      - cypress/reports/mocha/**/*.html
      - cypress/screenshots/**/*.png
      - cypress/snapshots/**/*.png
    expire_in: 2 hours

Every docker image normally has also a default shell, no matter of entrypoint :slight_smile: And GitLab Runner uses this shell to execute your commands in the script section, exactly the same as it executes your npx cypress run --browser chrome. Therefore, your curl commands should work, if curl and jq exist in the image - have you even tried uncommenting and let it run?

If they produce an error, then make a screenshot and paste it here.

jq is does not exist in the image so i tried sudo apt install it but i get /usr/bin/bash: line 151: sudo: command not found

i tried apt install jq -y
output:

$ apt install jq -y
WARNING: apt does not have a stable CLI interface. Use with caution in scripts.
Reading package lists...
Building dependency tree...
Reading state information...
W: Target Packages (main/binary-amd64/Packages) is configured multiple times in /etc/apt/sources.list.d/microsoft-edge-stable.list:1 and /etc/apt/sources.list.d/microsoft-edge.list:3
W: Target Packages (main/binary-all/Packages) is configured multiple times in /etc/apt/sources.list.d/microsoft-edge-stable.list:1 and /etc/apt/sources.list.d/microsoft-edge.list:3
E: Unable to locate package jq

Firstly - use without sudo. There is no sudo in default docker images
Secondly - you have to download package index first. apt update && apt install -y jq should work.

1 Like

Looking at the output, the image only seems to have microsoft edge repositories, so depending on whether this is a Debian image or Ubuntu image, it would also need the default repositories adding - perhaps /etc/apt/sources.list is empty? Unless I’m mistaken :slight_smile:

1 Like

Thanks this worked!

2 Likes