1. 概述

在 GitLab CI/CD 流水线中,除了触发任务(trigger job)外,其他任务都必须通过 script 标签来执行 Shell 命令。通常情况下,只要一个 Shell 命令在本地终端运行正常,它在 GitLab Pipeline 中也应能正常执行。

但在某些场景下,原本在本地运行正常的 cURL 命令,却可能在 GitLab 环境中失败,尤其是当命令中包含冒号(:)时。本文将围绕这个常见问题,结合示例说明如何正确地在 .gitlab-ci.yml 文件中使用 cURL。


2. .gitlab-ci.yml 中冒号的解析问题

cURL 命令中经常需要使用冒号来传递键值对(如 headers 或请求体),这在 YAML 文件中可能会导致解析错误。

2.1. 问题分析

我们先在本地运行一条标准的 cURL 命令测试接口:

$ curl -X POST "https://jsonplaceholder.typicode.com/posts" \
-H "Content-Type: application/json" \
-d '{"title": "foo", "body": "bar", "userId": 1}'

输出结果如下:

{
    "title": "foo",
    "body": "bar",
    "userId": 1,
    "id": 101
}

接着,将这条命令写入 .gitlab-ci.ymlscript 字段中:

curl_job:
  script:
    - curl -X POST "https://jsonplaceholder.typicode.com/posts" -H "Content-Type: application/json" -d '{"title": "foo", "body": "bar", "userId": 1}'

运行流水线后发现任务失败。GitLab 在解析时误将 : (冒号加空格)识别为键值对分隔符,导致 YAML 解析错误。

2.2. 初步修复方案

最简单的修复方式是去掉冒号后的空格

curl_job:
  script:
    - curl -X POST "https://jsonplaceholder.typicode.com/posts" -H "Content-Type:application/json" -d '{"title":"foo", "body":"bar", "userId":1}'

这样确实能解决问题,但如果请求体中包含 : 字符(如 "body": "foo: bar"),问题又会重现。


3. 使用 GitLab 变量(CI/CD Variables)

更稳妥的解决方案是使用 GitLab 的 CI/CD 变量来封装包含冒号的内容。

示例:

curl_job:
  variables:
    REQUEST_BODY: '{"title":"foo", "body":"foo: bar", "userId":1}'
  script:
    - curl -X POST "https://jsonplaceholder.typicode.com/posts" -H "Content-Type:application/json" -d "$REQUEST_BODY"

✅ 注意:

  • 定义变量时使用单引号包裹,保留双引号。
  • 使用变量时用双引号包裹,防止空格分割问题。

运行后日志显示任务成功执行,说明该方法有效。


4. 使用多行 YAML 字符串(Multi-line YAML Scalars)

为了提高可读性并避免冒号问题,我们还可以使用 YAML 的多行字符串特性。

4.1. 使用折叠块标量(Folded Block Scalar >

curl_job:
  variables:
    REQUEST_BODY: '{"title":"foo", "body":"foo: bar", "userId":1}'
  script: >
    curl --silent -X POST "https://jsonplaceholder.typicode.com/posts"
    -H "Content-Type: application/json"
    -d "${REQUEST_BODY}"

⚠️ 注意:

  • 所有换行会被转换为空格。
  • 继续行不能缩进,必须与首行对齐。

运行后任务成功。

4.2. 使用字面块标量(Literal Block Scalar |

curl_job:
  script: |
    curl -X POST "https://jsonplaceholder.typicode.com/posts" \
      -H "Content-Type: application/json" \
      -d '{"title": "foo", "body": "foo: bar", "userId": 1}'

✅ 优点:

  • 支持 \ 换行符,结构清晰。
  • 可以缩进继续行,不影响解析。

运行后任务成功。


5. 总结

本文围绕 .gitlab-ci.yml 中使用 cURL 的常见问题,总结了以下几种解决方式:

方法 说明 适用场景
✅ 去掉冒号后的空格 简单快捷 请求体/头中不含 :
✅ 使用 CI/CD 变量 稳定可靠 请求体中含特殊字符
✅ 多行字符串(> 或 ` `) 提高可读性

完整示例代码已上传至 GitHub查看仓库(仅为示例,实际地址请根据上下文 mock)。

如果你在使用 GitLab Pipeline 时也遇到 cURL 执行失败的问题,建议优先检查是否因冒号导致的 YAML 解析异常。


原始标题:Guide to Using cURL in gitlab-ci.yml