- 使用
script
中的特殊字符 - 忽略非零退出代码
- 为所有作业设置默认的
before_script
或after_script
- 如果作业被取消,跳过
after_script
命令 - 拆分长命令
- 向脚本输出添加颜色代码
- 故障排除
{{< details >}}
- Tier: 基础版, 专业版, 旗舰版
- Offering: JihuLab.com, 私有化部署
{{< /details >}}
你可以在 script
部分使用特殊语法来:
- 将长命令拆分为多行命令。
- 使用颜色代码使作业日志更容易查看。
- 创建自定义可折叠部分以简化作业日志输出。
使用 script
中的特殊字符
有时,script
命令必须用单引号或双引号括起来。例如,包含冒号 (:
) 的命令必须用单引号 ('
) 括起来。YAML 解析器需要将文本解释为字符串,而不是“键:值”对。
例如,下面的脚本使用了冒号:
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:
- false || exit_code=$?
- if [ $exit_code -ne 0 ]; then echo "Previous command failed"; fi;
为所有作业设置默认的 before_script
或 after_script
你可以将 before_script
和 after_script
与 default
一起使用:
- 使用
before_script
和default
定义一个默认的命令数组,这些命令应在所有作业的script
命令之前运行。 - 使用
after_script
和默认值定义一个默认命令数组,这些命令应在任何作业完成或被取消后运行。
通过在作业中定义不同的默认值可以覆盖默认值。要忽略默认值,请使用 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
命令
{{< history >}}
- 引入于极狐GitLab 17.0,使用名为
ci_canceling_status
的功能标志。默认启用。需要极狐GitLab 16.11.1。 - 在极狐GitLab 17.3 中 GA。功能标志
ci_canceling_status
被移除。
{{< /history >}}
after_script
命令在作业被取消时运行,而该作业的 before_script
或 script
部分正在运行。
作业在 UI 中的状态为 canceling
,而 after_script
正在执行,完成后状态更改为 canceled
。在 after_script
命令运行时,$CI_JOB_STATUS
预定义变量的值为 canceled
。
要防止在取消作业后运行 after_script
命令,请将 after_script
部分配置为:
- 在
after_script
部分开始时检查$CI_JOB_STATUS
预定义变量。 - 如果值为
canceled
,则提前结束执行。
例如:
job1:
script:
- my-script.sh
after_script:
- if [ "$CI_JOB_STATUS" == "canceled" ]; then exit 0; fi
- my-after-script.sh
拆分长命令
你可以将长命令拆分为多行命令,以通过 |
(文字)和 >
(折叠)YAML 多行块标量指示符提高可读性。
{{< alert type=”warning” >}}
如果多个命令合并为一个命令字符串,则仅报告最后一个命令的失败或成功。早期命令的失败被忽略,因为有一个错误。为了解决此问题,可以将每个命令作为单独的 script
项运行,或在每个命令字符串中添加一个 exit 1
命令。
{{< /alert >}}
你可以使用 |
(文字)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 here 文档也可以与 |
和 >
操作符一起使用。下面的例子将小写字母转写为大写字母:
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"
故障排除
使用 :
的脚本中的 Syntax is incorrect
如果在脚本中使用冒号 (:
),极狐GitLab 可能会输出:
Syntax is incorrect
script config should be a string or a nested array of strings up to 10 levels deep
例如,如果你在 cURL 命令中使用 "PRIVATE-TOKEN: ${PRIVATE_TOKEN}"
:
pages-job:
stage: deploy
script:
- curl --header 'PRIVATE-TOKEN: ${PRIVATE_TOKEN}' "https://gitlab.example.com/api/v4/projects"
environment: production
YAML 解析器认为 :
定义了一个 YAML 关键词,并输出 Syntax is incorrect
错误。
要使用包含冒号的命令,你应该将整个命令用单引号括起来。你可能需要将现有的单引号 ('
) 改为双引号 ("
):
pages-job:
stage: deploy
script:
- 'curl --header "PRIVATE-TOKEN: ${PRIVATE_TOKEN}" "https://gitlab.example.com/api/v4/projects"'
environment: production
使用 &&
的脚本作业未失败
如果在单个脚本行中使用 &&
将两个命令组合在一起,即使其中一个命令失败,作业也可能返回成功。例如:
job-does-not-fail:
script:
- invalid-command xyz && invalid-command abc
- echo $?
- echo "The job should have failed already, but this is executed unexpectedly."
&&
操作符返回的退出代码为 0
,即使两个命令失败,作业仍会继续运行。要强制脚本在任一命令失败时退出,请将整个行括在括号中:
job-fails:
script:
- (invalid-command xyz && invalid-command abc)
- echo "The job failed already, and this is not executed."
折叠的 YAML 多行块标量未保留多行命令
如果你使用 - >
折叠的 YAML 多行块标量来拆分长命令,额外的缩进会导致这些行被处理为单独的命令。
例如:
script:
- >
RESULT=$(curl --silent
--header
"Authorization: Bearer $CI_JOB_TOKEN"
"${CI_API_V4_URL}/job"
)
这会失败,因为缩进导致换行被保留:
$ RESULT=$(curl --silent # collapsed multi-line command
curl: no URL specified!
curl: try 'curl --help' or 'curl --manual' for more information
/bin/bash: line 149: --header: command not found
/bin/bash: line 150: https://gitlab.example.com/api/v4/job: No such file or directory
解决方法是:
-
删除多余的缩进:
script: - > RESULT=$(curl --silent --header "Authorization: Bearer $CI_JOB_TOKEN" "${CI_API_V4_URL}/job" )
-
修改脚本以便处理额外的换行,例如使用 shell 行继续符:
script: - > RESULT=$(curl --silent \ --header \ "Authorization: Bearer $CI_JOB_TOKEN" \ "${CI_API_V4_URL}/job")
作业日志输出格式不符合预期或包含意外字符
有时使用依赖于 TERM
环境变量进行着色或格式化的工具时,作业日志的格式显示不正确。例如,使用 mypy
命令:
极狐GitLab Runner 以非交互模式运行容器的 shell,因此 shell 的 TERM
环境变量被设置为 dumb
。要修复这些工具的格式,可以:
- 在运行命令之前添加一个额外的脚本行,以在 shell 的环境中设置
TERM=ansi
。 - 添加一个值为
ansi
的TERM
CI/CD 变量。
after_script
部分执行提前停止和不正确的 $CI_JOB_STATUS
值
在极狐GitLab Runner 16.9.0 到 16.11.0 版本中:
-
after_script
部分有时会提前停止执行。 -
$CI_JOB_STATUS
预定义变量的状态,在作业取消时错误地设置为failed
。