作业故障排除
- Tier: Free, Premium, Ultimate
- Offering: GitLab.com, GitLab Self-Managed, GitLab Dedicated
在使用作业时,你可能会遇到以下问题。
使用 changes: 时,作业或流水线意外运行
当使用 rules: changes 或 only: changes 而没有 merge request pipelines 时,你的作业或流水线可能会意外运行。
没有明确关联合并请求的分支或标签上的流水线,使用先前的 SHA 来计算差异。这个计算等同于 git diff HEAD~,可能导致意外行为,包括:
- 当向 GitLab 推送新分支或新标签时,
changes规则总是评估为 true。 - 当推送新提交时,变更的文件通过使用先前的提交作为基础 SHA 来计算。
此外,在 scheduled pipelines 中,带有 changes 的规则总是评估为 true。当计划流水线运行时,所有文件都被认为已更改,因此使用 changes 的作业可能会总是被添加到计划流水线中。
CI/CD 变量中的文件路径
在 CI/CD 变量中使用文件路径时要小心。在变量定义中,尾部斜杠可能看起来正确,但在 script:、changes: 或其他关键字中展开时可能会变得无效。例如:
docker_build:
variables:
DOCKERFILES_DIR: 'path/to/files/' # 此变量不应有尾部 '/' 字符
script: echo "A docker job"
rules:
- changes:
- $DOCKERFILES_DIR/*当 DOCKERFILES_DIR 变量在 changes: 部分展开时,完整路径变为 path/to/files//*。根据使用的关键字、运行程序的 shell 和操作系统等因素,双斜杠可能会导致意外行为。
“您不允许从此项目下载代码。“错误消息
当 GitLab 管理员在私有项目中运行受保护的手动作业时,你可能会看到流水线失败。
CI/CD 作业通常在作业开始时克隆项目,这使用 运行作业的用户权限。所有用户,包括管理员,都必须是私有项目的直接成员才能克隆该项目的源代码。存在一个问题 来改变这种行为。
要运行受保护的手动作业:
- 将管理员添加为私有项目的直接成员(任何角色)
- 模拟用户身份,该用户是项目的直接成员。
再次运行 CI/CD 作业时不使用较新的配置
流水线的配置仅在创建流水线时获取。当你重新运行作业时,每次都使用相同的配置。如果你更新配置文件,包括使用 include 添加的单独文件,你必须启动一个新流水线才能使用新配置。
“作业可能允许对单个操作运行多个流水线"警告
当你使用带有 when 子句但没有 if 子句的 rules 时,可能会运行多个流水线。这通常发生在你向有关联的开放合并请求的分支推送提交时。
要防止重复流水线,使用 workflow: rules 或重写你的规则来控制哪些流水线可以运行。
变量表达式的"This GitLab CI configuration is invalid"错误
在使用 CI/CD 变量表达式 时,你可能会收到几个 “This GitLab CI configuration is invalid” 错误之一。这些语法错误可能是由引号字符使用不当引起的。
在变量表达式中,字符串应该加引号,而变量不应该加引号。例如:
variables:
ENVIRONMENT: production
job:
script: echo
rules:
- if: $ENVIRONMENT == "production"
- if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH在此示例中,两个 if: 子句都是有效的,因为 production 字符串加了引号,而 CI/CD 变量没有加引号。
另一方面,这些 if: 子句都是无效的:
variables:
ENVIRONMENT: production
job:
script: echo
rules: # 这些规则都会导致 YAML 语法错误:
- if: ${ENVIRONMENT} == "production"
- if: "$ENVIRONMENT" == "production"
- if: $ENVIRONMENT == production
- if: "production" == "production"在此示例中:
if: ${ENVIRONMENT} == "production"无效,因为${ENVIRONMENT}不是if:中 CI/CD 变量的有效格式。if: "$ENVIRONMENT" == "production"无效,因为变量被引号包围。if: $ENVIRONMENT == production无效,因为字符串没有加引号。if: "production" == "production"无效,因为没有要比较的 CI/CD 变量。
get_sources 作业部分因 HTTP/2 问题而失败
有时,作业会因以下 cURL 错误而失败:
++ git -c 'http.userAgent=gitlab-runner <version>' fetch origin +refs/pipelines/<id>:refs/pipelines/<id> ...
error: RPC failed; curl 16 HTTP/2 send again with decreased length
fatal: ...你可以通过配置 Git 和 libcurl 来使用 HTTP/1.1 来解决此问题。配置可以添加到:
-
作业的
pre_get_sources_script中:job_name: hooks: pre_get_sources_script: - git config --global http.version "HTTP/1.1" -
带有 Git 配置环境变量 的 runner’s
config.toml中:[[runners]] ... environment = [ "GIT_CONFIG_COUNT=1", "GIT_CONFIG_KEY_0=http.version", "GIT_CONFIG_VALUE_0=HTTP/1.1" ]
使用 resource_group 的作业卡住了
- Tier: Free, Premium, Ultimate
- Offering: GitLab Self-Managed, GitLab Dedicated
如果使用 resource_group 的作业卡住了,GitLab 管理员可以尝试从 rails console 运行以下命令:
# 按名称查找资源组
resource_group = Project.find_by_full_path('...').resource_groups.find_by(key: 'the-group-name')
busy_resources = resource_group.resources.where('build_id IS NOT NULL')
# 识别哪些构建正在占用资源
# (我认为现在应该是 1 个)
busy_resources.pluck(:build_id)
# 最好检查一下为什么这个构建正在占用资源。
# 它卡住了吗?是否被系统强制丢弃了?
# 释放占用的资源
busy_resources.update_all(build_id: nil)“您无权运行此手动作业"消息
尝试运行手动作业时,如果出现以下情况,你可能会收到此消息并且 Run 按钮被禁用: