GitLab CI 脚本之 CI_COMMIT_AUTHOR

GitLab执行CI脚本时报了这样的错误:

bash 复制代码
Running with gitlab-runner 19.3.1 (a27f5034)
  on Test-Machine abc123xyz, system ID: s_xxxxxxxxxxxx
Resolving secrets
Preparing the "shell" executor
00:00
Using Shell (powershell) executor...
Preparing environment
00:00
Running on Test-Machine...
Getting source from Git repository
00:02
At line:274 char:29
+ ${CI_COMMIT_REF_PROTECTED}="true"
+                             ~~~~~
Unexpected token 'true"
${env:CI_COMMIT_REF_PROTECTED}=${CI_COMMIT_REF_PROTECTED}
${CI_COMMIT_TIMESTAMP}="2026-10-10T21:40:55+08:00"
${env:CI_COMMIT_TIMESTAMP}=${CI_COMMIT_TIMESTAMP}
${CI_COMMIT_AUTHOR}="user' in expression or statement.
At line:278 char:34
+ ${CI_COMMIT_AUTHOR}="user <user@example.com>"
+                                              ~
The '<' operator is reserved for future use.
At line:332 char:104
+ ... \builds\abc123xyz\0\user\automationtest\.git\index.lock"
+                                                             ~
The string is missing the terminator: ".
At line:1 char:3
+ & {
+    ~
Missing closing '}' in statement block or type definition.
    + CategoryInfo          : ParserError: (:) [], ParentContainsErrorRecordException
    + FullyQualifiedErrorId : UnexpectedToken

Gitaly correlation ID: 01MXXXXXXXXXXXXXXXXXXXXXX
Cleaning up project directory and file based variables
00:01
At line:272 char:29
+ ${CI_COMMIT_REF_PROTECTED}="true"
+                             ~~~~~
Unexpected token 'true"
${env:CI_COMMIT_REF_PROTECTED}=${CI_COMMIT_REF_PROTECTED}
${CI_COMMIT_TIMESTAMP}="2026-10-10T21:40:55+08:00"
${env:CI_COMMIT_TIMESTAMP}=${CI_COMMIT_TIMESTAMP}
${CI_COMMIT_AUTHOR}="user' in expression or statement.
At line:276 char:34
+ ${CI_COMMIT_AUTHOR}="user <user@example.com>"
+                                              ~
The '<' operator is reserved for future use.
At line:336 char:110
+ ... \builds\abc123xyz\0\user\automationtest.tmp\gitlab_runner_env"
+                                                                 ~
The string is missing the terminator: ".
At line:1 char:3
+ & {
+    ~
Missing closing '}' in statement block or type definition.
    + CategoryInfo          : ParserError: (:) [], ParentContainsErrorRecordException
    + FullyQualifiedErrorId : UnexpectedToken

At line:1 char:1
+ }
+ ~
Unexpected token '}' in expression or statement.
    + CategoryInfo          : ParserError: (:) [], ParentContainsErrorRecordException
    + FullyQualifiedErrorId : UnexpectedToken

ERROR: Job failed: exit status 1

公司服务器用的powershell版本是5.1,这里面有个坑,CI_COMMIT_AUTHOR 自动获取的值包含了邮箱:xxx<xxx@wwww.com>。

在 PowerShell 中,< 和 > 是保留的重定向符号。当 GitLab Runner 自动把这个变量转换成 PowerShell 脚本注入时,由于内部引号或转义处理不当,导致 PowerShell 把 < 当成了语法错误,并且把整段字符串的引号截断了(The string is missing the terminator: ")。

连锁解析崩溃:

因为前面某一个环境变量(如包含空格、单双引号、尖括号的 Author 或 Commit Message)破坏了 PowerShell 的字符串闭合,导致后面生成的 PowerShell 临时环境脚本直接语法报错(ParserError),最终引发整个 Job 失败。

pwsh (powershell7)可以解决这个问题,但是我不想升级,所以采用了另外的方法:

在全局 variables 里面显式声明并覆盖 CI_COMMIT_AUTHOR:

bash 复制代码
variables:
  CI_COMMIT_AUTHOR: "xxx"

因为GitLab CI 允许在 YAML 的 variables 中直接重写默认的内置环境变量。通过把带有尖括号 <...> 的邮箱地址去掉,只保留纯文本名字 xxx,就能彻底避开 PowerShell 对 < 符号的语法审查和引号截断错误。

再具体说下CI_COMMIT_AUTHOR,它是GitLab的内置属性,是 GitLab 在每次触发 Pipeline 时自动生成并注入的系统变量,用来记录当前触发这次提交(Commit)的作者信息。它的默认格式是:作者名字 <邮箱地址>。

通过在全局 variables 中显式声明后,实际上是给 GitLab 发了一条指令:"不要使用系统默认那个带尖括号和邮箱的复杂字符串来初始化这个环境变量,请直接用我给你的这个纯文本(没有特殊符号)来代替它!"这样一来,Runner 注入到 PowerShell 里的语句就变成了干净的 $env:CI_COMMIT_AUTHOR="xxx",从而完美避开了 PowerShell 的语法拦截。

相关推荐
宋明河2 小时前
开发工作流程思考
ci/cd·代码复审
赵大仁18 小时前
开源清单怎么维护才不烂掉?GitHub Actions 每周查死链 + 软 404 检测实录
python·ci/cd·自动化·开源项目·踩坑·github actions·json schema
_可乐无糖19 小时前
GitLab CI 脚本之 dependencies 和 needs
ci/cd·gitlab
MZZ骏马21 小时前
centos7安装gcc 4.9.2
ci/cd
Fan_5582 天前
4核8G云服务器部署GitLab内存耗尽解决方案
gitlab
洋就在江州2 天前
gitlab-cicd 离线集成——springboot-cicd (非docker形式,shell形式)
java·spring boot·后端·ci/cd·gitlab·gitlab-runner
oicola2 天前
【运维】CI/CD是什么,合格的规范应该怎么设置
运维·ci/cd
tianyuanwo2 天前
【软考高级系统架构设计师】05 - DevOps & CI/CD专题备考
ci/cd·系统架构·devops