Format scripts and job logs

You can use special syntax in script sections to:

Use special characters with script

Sometimes, script commands must be wrapped in single or double quotes. For example, commands that contain a colon (:) must be wrapped in single quotes ('). The YAML parser needs to interpret the text as a string rather than a “key: value” pair.

For example, this script uses a colon:

job:
  script:
    - curl --request POST --header 'Content-Type: application/json' "https://gitlab/api/v4/projects"

To be considered valid YAML, you must wrap the entire command in single quotes. If the command already uses single quotes, you should change them to double quotes (") if possible:

job:
  script:
    - 'curl --request POST --header "Content-Type: application/json" "https://gitlab/api/v4/projects"'

You can verify the syntax is valid with the CI Lint tool.

Be careful when using these characters as well:

  • {, }, [, ], ,, &, *, #, ?, |, -, <, >, =, !, %, @, `.

Ignore non-zero exit codes

When script commands return an exit code other than zero, the job fails and further commands do not execute.

Store the exit code in a variable to avoid this behavior:

job:
  script:
    - false || exit_code=$?
    - if [ $exit_code -ne 0 ]; then echo "Previous command failed"; fi;

Set a default before_script or after_script for all jobs

You can use before_script and after_script with default:

  • Use before_script with default to define a default array of commands that should run before the script commands in all jobs.
  • Use after_script with default to define a default array of commands that should run after the job completes.

You can overwrite a default by defining a different one in a job. To ignore the default use before_script: [] or after_script: []:

default:
  before_script:
    - echo "Execute this `before_script` in all jobs by default."
  after_script:
    - echo "Execute this `after_script` in all jobs by default."

job1:
  script:
    - echo "These script commands execute after the default `before_script`,"
    - echo "and before the default `after_script`."

job2:
  before_script:
    - echo "Execute this script instead of the default `before_script`."
  script:
    - echo "This script executes after the job's `before_script`,"
    - echo "but the job does not use the default `after_script`."
  after_script: []

Split long commands

You can split long commands into multiline commands to improve readability with | (literal) and > (folded) .

You can use the | (literal) YAML multiline block scalar indicator to write commands over multiple lines in the script section of a job description. Each line is treated as a separate command. Only the first command is repeated in the job log, but additional commands are still executed:

job:
  script:
    - |
      echo "First command line."
      echo "Second command line."
      echo "Third command line."

The example above renders in the job log as:

$ echo First command line # collapsed multiline command
First command line
Second command line.
Third command line.

The > (folded) YAML multiline block scalar indicator treats empty lines between sections as the start of a new command:

job:
  script:
    - >
      echo "First command line
      is split over two lines."

      echo "Second command line."

This behaves similarly to multiline commands without the > or | block scalar indicators:

job:
  script:
    - echo "First command line
      is split over two lines."

      echo "Second command line."

Both examples above render in the job log as:

$ echo First command line is split over two lines. # collapsed multiline command
First command line is split over two lines.
Second command line.

When you omit the > or | block scalar indicators, GitLab concatenates non-empty lines to form the command. Make sure the lines can run when concatenated.

| and > operators as well. The example below transliterates lower case letters to upper case:

job:
  script:
    - |
      tr a-z A-Z << END_TEXT
        one two three
        four five six
      END_TEXT

Results in:

$ tr a-z A-Z << END_TEXT # collapsed multiline command
  ONE TWO THREE
  FOUR FIVE SIX

Add color codes to script output

Script output can be colored using , or by running commands or programs that output ANSI escape codes.

For example, using :

You can define the color codes in Shell environment variables, or even custom CI/CD variables, which makes the commands easier to read and reusable.

For example, using the same example as above and environment variables defined in a before_script:

job:
  before_script:
    - TXT_RED="\e[31m" && TXT_CLEAR="\e[0m"
  script:
    - echo -e "${TXT_RED}This text is red,${TXT_CLEAR} but this part isn't${TXT_RED} however this part is again."
    - echo "This text is not colored"

Or with :

Troubleshooting

Syntax is incorrect in scripts that use :

If you use a colon (:) in a script, GitLab might output:

  • Syntax is incorrect
  • script config should be a string or a nested array of strings up to 10 levels deep

For example, if you use "PRIVATE-TOKEN: ${PRIVATE_TOKEN}" as part of a cURL command:

pages-job:
  stage: deploy
  script:
    - curl --header 'PRIVATE-TOKEN: ${PRIVATE_TOKEN}' "https://gitlab.example.com/api/v4/projects"

The YAML parser thinks the : defines a YAML keyword, and outputs the Syntax is incorrect error.

To use commands that contain a colon, you should wrap the whole command in single quotes. You might need to change existing single quotes (') into double quotes ("):

pages-job:
  stage: deploy
  script:
    - 'curl --header "PRIVATE-TOKEN: ${PRIVATE_TOKEN}" "https://gitlab.example.com/api/v4/projects"'