The script keyword is one of the most fundamental parts of a GitLab CI/CD job. It defines the actual shell commands that the GitLab Runner will execute to perform the job’s tasks. This is where you put the core logic of your CI/CD process, like compiling code, running tests, building Docker images, or deploying applications.
Example .gitlab-ci.yml with script:
YAML
# .gitlab-ci.yml
default:
image: alpine:latest # Using a lightweight default image for our jobs
stages:
- build
- test
- report
# Job 1: Demonstrates basic single-line commands
build_project:
stage: build
script:
- echo "--- Starting Project Build ---" # Simple command to print a message
- echo "Current directory:"
- ls -la # Lists files in the current directory
- mkdir build_output # Creates a directory
- echo "Build files would be generated here." > build_output/info.txt
- echo "Project build process finished."
# Job 2: Demonstrates a sequence of commands and a multi-line command
run_tests:
stage: test
script:
- echo "--- Running Tests ---"
- echo "Setting up test environment..."
- sleep 2 # Simulate some setup time
- echo "Running test suite 1..."
- echo "Test 1.1: PASSED"
- echo "Test 1.2: PASSED"
- | # This is a YAML block scalar, allowing for a multi-line script block
echo "Running a multi-line command or a series of commands as one script step:"
echo " Detail 1: Checking component A"
echo " Detail 2: Verifying integration B"
echo "Test suite 2 completed."
- echo "All tests finished."
# Job 3: Demonstrates a script that might fail
generate_report:
stage: report
script:
- echo "--- Generating Report ---"
- echo "Creating report data..."
- echo "This is a report" > report.txt
- cat report.txt
# - cat non_existent_file.txt # Uncomment this line to see the job fail
- echo "Report generation successful (unless a command above failed)."
Code language: PHP (php)
Explanation:
script:Keyword:- The
scriptkeyword is required for any job that needs to execute commands. If a job definition doesn’t have ascriptsection, it might be considered a “no-op” job or a configuration error depending on other settings. - It takes an array of strings, where each string is a shell command.
- The
- Execution Environment:
- The commands in the
scriptsection are executed by a shell (likesh,bash, or PowerShell depending on the GitLab Runner’s configuration and the specified Docker image’s default shell). - In this example,
default:image: alpine:latestmeans all jobs will run inside a Docker container based on thealpine:latestimage, and the commands will be run by Alpine’ssh.
- The commands in the
build_projectJob:echo "--- Starting Project Build ---": A simple command to print a message to the job log.ls -la: Lists files and directories in the job’s working directory.mkdir build_output: Creates a new directory.echo "Build files..." > build_output/info.txt: Creates a file with some content.- Sequential Execution: The commands are executed one after the other, in the order they are listed.
run_testsJob:- This job also shows a sequence of
echocommands. |(YAML Literal Block Scalar):- The
|character at the start of the script block allows you to write multi-line strings more easily. Each line under it (preserving indentation) is treated as part of the same script command or a sequence of commands passed to the shell. - In this case, it’s used to group several
echostatements that logically belong together for readability. Each of theseechocommands is still executed individually by the shell. - You could also write a long single command that spans multiple lines in your YAML editor, and as long as it’s a valid shell command, it will work.
- The
- This job also shows a sequence of
generate_reportJob:- This job demonstrates a typical sequence.
- Failure Handling: If any command in a
scriptblock exits with a non-zero status code (which typically indicates an error), GitLab CI will, by default:- Stop executing subsequent commands in that
scriptblock. - Mark the job as failed.
- The pipeline might stop at that point, depending on its configuration (e.g.,
allow_failuresettings on the job or stage configurations).
- Stop executing subsequent commands in that
- If you uncomment
- cat non_existent_file.txt, thecatcommand will fail because the file doesn’t exist, causing thegenerate_reportjob to fail.
Key Concepts and Behavior:
- Heart of the Job: The
scriptsection defines the primary actions the job performs. - Array of Commands: Always an array, even if there’s only one command. YAML
my_job: script: "echo 'Single command still needs to be in an array or be the only item'" # Or more commonly: my_job: script: - "echo 'Single command'" - Working Directory: Commands are executed in the context of the cloned repository, specifically
$CI_PROJECT_DIR. - Shell Interpreter: The specific shell used depends on the Docker image and the GitLab Runner configuration. You can often find out which shell is used by adding
echo $SHELLorps -p $$to your script. - Exit Codes: The success or failure of each command (and thus the job) is determined by its exit code.
0usually means success, and any non-zero value means failure. - Environment Variables: You can use predefined CI/CD variables (like
$CI_PROJECT_DIR,$CI_COMMIT_SHA) and user-defined variables within your script commands.
The script section is where you’ll spend most of your time defining the logic for your CI/CD jobs, whether it’s building, testing, deploying, or automating any other task.