Help us learn about your current experience with the documentation. Take the survey.

脚本和作业日志

  • Tier: Free, Premium, Ultimate
  • Offering: GitLab.com, GitLab Self-Managed, GitLab Dedicated

您可以在 script 部分使用特殊语法来:

script 中使用特殊字符

有时,script 命令必须用单引号或双引号括起来。 例如,包含冒号 (:) 的命令必须用单引号 (') 括起来。 YAML 解析器需要将文本解释为字符串,而不是 “key: value” 键值对。

例如,以下脚本使用了冒号:

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

为了被视为有效的 YAML,您必须用单引号将整个命令括起来。如果 命令已经使用了单引号,应尽可能将它们更改为双引号 ("):

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

您可以使用 CI Lint 工具验证语法是否有效。

使用以下字符时也要小心:

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

忽略非零退出码

当脚本命令返回非零退出码时,作业会失败,并且后续命令不会执行。

将退出码存储在变量中以避免这种行为:

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

为所有作业设置默认的 before_scriptafter_script

您可以将 before_scriptafter_scriptdefault 一起使用:

  • 使用 before_scriptdefault 来定义一个默认的命令数组,这些命令应在所有作业的 script 命令之前运行。
  • 使用 after_scriptdefault 来定义一个默认的命令数组,这些命令应在任何作业完成或被取消后运行。

您可以通过在作业中定义不同的默认值来覆盖默认值。要忽略默认值,请使用 before_script: []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: []

如果作业被取消,则跳过 after_script 命令

如果作业在 before_scriptscript 部分运行时被取消,则会运行 after_script 命令。

after_script 执行期间,作业在 UI 中的状态为 canceling,在 after_script 命令完成后更改为 canceled。在 after_script 命令运行时,$CI_JOB_STATUS 预定义变量的值为 canceled

要防止在取消作业后运行 after_script 命令,请将 after_script 部分配置为:

  1. after_script 部分的开头检查 $CI_JOB_STATUS 预定义变量。
  2. 如果值为 canceled,则提前结束执行。

例如:

job1:
  script:
    - my-script.sh
  after_script:
    - if [ "$CI_JOB_STATUS" == "canceled" ]; then exit 0; fi
    - my-after-script.sh

拆分长命令

您可以使用 | (字面量) 和 > (折叠) YAML 多行块标量指示符 将长命令拆分为多行命令以提高可读性。

如果多个命令被组合成一个命令字符串,只会报告最后一个命令的失败或成功。 由于一个 bug,早期命令的失败被忽略。 要解决此问题,请将每个命令作为单独的 script 项运行,或向每个命令字符串添加一个 exit 1 命令。

您可以使用 | (字面量) YAML 多行块标量指示符在作业描述的 script 部分中编写多行命令。 每一行都被视为一个单独的命令。 只有第一个命令会在作业日志中重复,但其他命令仍然会执行:

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

前面的示例在作业日志中呈现为:

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

> (折叠) YAML 多行块标量指示符将部分之间的空行视为新命令的开始:

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

      echo "Second command line."

这与没有 >| 块标量指示符的多行命令的行为类似:

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

      echo "Second command line."

前面的两个示例在作业日志中呈现为:

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

当您省略 >| 块标量指示符时,GitLab 会连接非空行以形成命令。请确保这些行在连接后可以运行。

Shell 此处文档 也与 |> 运算符一起使用。以下示例将小写字母音译为大写字母:

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

结果为:

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

为脚本输出添加颜色代码

可以使用 ANSI 转义码 为脚本输出着色,或者通过输出 ANSI 转义码的命令或程序来实现。

例如,使用 带有颜色代码的 Bash

job:
  script:
    - echo -e "\e[31mThis text is red,\e[0m but this text isn't\e[31m however this text is red again."

您可以在 Shell 环境变量中定义颜色代码,甚至可以在 CI/CD 变量 中定义,这使得命令更易于阅读和重用。

例如,使用前面的示例和在 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"

或者使用 PowerShell 颜色代码

job:
  before_script:
    - $esc="$([char]27)"; $TXT_RED="$esc[31m"; $TXT_CLEAR="$esc[0m"
  script:
    - Write-Host $TXT_RED"This text is red,"$TXT_CLEAR" but this text isn't"$TXT_RED" however this text is red again."
    - Write-Host "This text is not colored"