The before_script keyword in GitLab CI/CD allows you to define a list of shell commands that should be executed before the main script commands of a job. This is commonly used for setup tasks like:
- Logging information.
- Setting up environment variables.
- Installing dependencies.
- Authenticating to services.
You can define before_script at two main levels:
- Globally (as a default): Using
default:before_script:. These commands will run before every job unless a job overrides it. - Job-level: Defined within a specific job. This overrides any global
before_scriptfor that particular job.
Example .gitlab-ci.yml with before_script:
YAML
# .gitlab-ci.yml
# 1. Default before_script: Applied to all jobs unless overridden
default:
image: alpine:latest # Using a common default image
before_script:
- echo "--- Default before_script (Global) ---"
- echo "Current date: $(date)"
- echo "Setting up common environment..."
- export COMMON_SETUP_VAR="Set by default before_script"
stages:
- setup
- build
- test
# Job 1: Uses the default before_script
job_with_default_before_script:
stage: setup
script:
- echo "--- Main script for job_with_default_before_script ---"
- echo "COMMON_SETUP_VAR is: $COMMON_SETUP_VAR"
- echo "This job used the global before_script."
# Job 2: Overrides the default before_script with its own
job_with_custom_before_script:
stage: build
before_script: # Job-level before_script overrides the default one
- echo "--- Custom before_script for job_with_custom_before_script ---"
- echo "Performing specific setup for this job..."
- apk add --no-cache curl # Example: installing a tool
- curl --version
script:
- echo "--- Main script for job_with_custom_before_script ---"
- echo "This job used its own custom before_script."
- echo "COMMON_SETUP_VAR is: $COMMON_SETUP_VAR (This will be empty as default before_script didn't run)"
# Job 3: Disables before_script (even the default one)
job_without_any_before_script:
stage: test
before_script: [] # Explicitly set to an empty array to disable
# You could also use `before_script: null` in some GitLab versions, but `[]` is safer.
script:
- echo "--- Main script for job_without_any_before_script ---"
- echo "No before_script (neither default nor custom) was executed for this job."
- echo "COMMON_SETUP_VAR is: $COMMON_SETUP_VAR (This will be empty)"
Code language: PHP (php)
Explanation:
default:before_script:- The
default:block allows you to set default configurations for all jobs. before_script:withindefault:defines a list of commands that will be executed before the mainscriptof every job in the pipeline, provided the job doesn’t have its ownbefore_scriptor explicitly disables it.- In this example:
- It prints some introductory lines.
- It prints the current date.
- It simulates setting up a common environment variable
COMMON_SETUP_VAR.
- The
job_with_default_before_script:- This job does not have its own
before_scriptkeyword. - Therefore, it inherits and executes the commands from the
default:before_script:section before its ownscriptblock runs. - You’ll see the output from the default
before_script, and theCOMMON_SETUP_VARwill be available in its main script.
- This job does not have its own
job_with_custom_before_script:- This job defines its own
before_script:block. - This job-level
before_scriptcompletely overrides (replaces) thedefault:before_script:. The commands fromdefault:before_script:will not run for this job. - Only the commands listed in this job’s
before_script(e.g., installingcurl) will execute before its mainscript. - Consequently,
COMMON_SETUP_VAR(set in the defaultbefore_script) will not be defined or will be empty when this job’s main script runs.
- This job defines its own
job_without_any_before_script:- This job explicitly sets
before_script: [](an empty array). - This tells GitLab CI not to run any
before_scriptcommands for this job, not even the ones defined in thedefault:before_script:section. - The job will proceed directly to its
scriptblock. COMMON_SETUP_VARwill be undefined or empty.
- This job explicitly sets
Key Concepts and Behavior:
- Purpose:
before_scriptis intended for setup tasks that prepare the environment for the mainscript. It’s not for the core logic of your job. - Execution Order: For any given job, if a
before_scriptis active (either default or job-specific), its commands run first. If all commands inbefore_scriptsucceed, then the commands in the job’sscriptsection are executed. - Failure Handling: If any command in
before_scriptfails (exits with a non-zero status), the job is typically marked as failed immediately. The mainscriptsection for that job will not be executed. - Array of Commands:
before_scripttakes an array of strings, where each string is a shell command to be executed sequentially. - Inheritance and Overriding:
- Job-level
before_scriptoverridesdefault:before_script. - To prevent any
before_script(including a global one) from running for a specific job, setbefore_script: []orbefore_script: null(though[]is generally preferred for clarity and consistency).
- Job-level
- Common Use Cases:
- Printing debug information (versions of tools, environment variables).
- Logging into private repositories or services.
- Installing required software packages or dependencies that are not part of the Docker image.
- Setting dynamic environment variables needed by the main
script. - Fetching configuration files.
Using before_script helps keep your main script section clean and focused on the primary task of the job, while common or job-specific setup steps are neatly organized.