使用Bash和cURL通过CI/CD管道推送时生成GitLab合并请求

mwkjh3gx  于 2022-11-13  发布在  Git
关注(0)|答案(1)|浏览(167)

所以,这几天我一直在为这个问题绞尽脑汁,我需要一些帮助。最初,我找到了2017年的gitlab博客文章:https://about.gitlab.com/blog/2017/09/05/how-to-automatically-create-a-new-mr-on-gitlab-with-gitlab-ci/
然而,看起来很多都已经过时了(?),但我能够使用POSTMAN来创建一个工作模型(使用令牌作为参数,而不是头部,等等)。
问题是,我无法触发合并请求,我认为这是由于--data(-d)没有插入变量。
我已经用正确的值硬编码了有效负载,并推到我的分支,它生成了MR。
但是,我用来尝试合并变量的任何方法都将导致cURL通过,但不会生成MR。
更重要的是,GL Runner不输出响应-所以我很难弄清楚到底是什么问题。
我试过用反斜杠转义,我试过用单引号转义单引号设置,用${}变量做内双引号,但什么都没有。
我已经验证了从yml发送进来的变量是否存在(在curl调用和body设置之前将它们回显),但我只是在这一点上迷失了方向。
我还没有尝试JQ,但我不确定运行者是否安装了它,但我会在返回测试时找到答案。
任何帮助都很好。
脚本代码的一般格式:

#!/usr/bin/env bash
TARGET_BRANCH="test"

echo "Host: ${HOST}"
echo "Project  Id: ${CI_PROJECT_ID}
echo "SOURCE BRANCH: ${CI_COMMIT_REF_NAME}
echo "Target Branch: ${TARGET_BRANCH}

BODY="{
    \"id\": ${CI_PROJECT_ID},
    \"source_branch\": \"${CI_COMMIT_REF_NAME}\",
    \"target_branch\": \"${TARGET_BRANCH}\",
    \"remove_source_branch\": false,
    \"title\": \"WIP: ${CI_COMMIT_REF_NAME}\",
}";

echo "Body: ${BODY}"

# Create MR
curl -X POST https://${HOST}/api/v4/projects/${CI_PROJECT_ID}/merge_requests?private_token${PRIVATE_TOKEN}"\
--header "PRIVATE_TOKEN: ${PRIVATE_TOKEN}"\
--header "Content-Type: application/json"\
--data "${BODY}"

现在我想指出的是,在进行测试并看到旋度通过,但没有生成MR后,我将--data值从${BODY}修改为:(假设为有效值,只是出于原因而模糊化)

--data '{
  "id": <x>,
  "source_branch": "dev",
  "target_branch": "test",
  "remove_source_branch": false,
  "title":"WIP: dev"
}'

这个成功了!我的MR产生得很好。
然后用双引号替换单引号,并转义内部的双引号,但仍然保留硬编码的值,返回到没有生成MR。
我被难倒了--我甚至回到了BODY=...块,并试图重新格式化它。
然后我就去了外单,内双,流窜

'{
  "id": '"${CI_PROJECT_ID}"',
  ...
'}

还是什么都没有。
所以,在所有的尝试和与一些队友交谈都无济于事之后,我休息了一下,并向Stack Overflow征求了一些建议。
添加了注解:这不是典型的应用程序项目存储库,因此,当使用存储库时不会使用问题、用户参与最少等时,任何关于“这不是一个良好的标准实践,使用问题作为生成MR的锚点”的讨论都不适用。
我很重视这些见解,但同样,可以说,这个回购协议的用例并不是一个实际的“项目”。
谢谢你

cyej8jka

cyej8jka1#

我有点搞不懂你问的是什么。听起来你把json字符串直接传递给curl的data标志就可以很好地工作了,而你只是想知道为什么其他尝试都没有成功。如果是这样的话,下面是我看到的会让你的其他尝试失败的东西:

# ...
BODY="{
    \"id\": ${CI_PROJECT_ID},
    \"source_branch\": \"${CI_COMMIT_REF_NAME}\",
    \"target_branch\": \"${TARGET_BRANCH}\",
    \"remove_source_branch\": false,
    \"title\": \"WIP: ${CI_COMMIT_REF_NAME}\",
}";

echo "Body: ${BODY}"

# Create MR
curl -X POST https://${HOST}/api/v4/projects/${CI_PROJECT_ID}/merge_requests?private_token${PRIVATE_TOKEN}"\
--header "PRIVATE_TOKEN: ${PRIVATE_TOKEN}"\
--header "Content-Type: application/json"\
--data "${BODY}"

在第一个选项中,变量看起来很好,但是当你在curl命令中使用它时,你要引用变量(即"$BODY")。当你进行连接时,这没有什么问题,但是在这里它可能会导致语法问题,因为当变量被提取时,结果是一个被双引号引起来的json字符串:

""{
    \"id\": ${CI_PROJECT_ID},
    \"source_branch\": \"${CI_COMMIT_REF_NAME}\",
    \"target_branch\": \"${TARGET_BRANCH}\",
    \"remove_source_branch\": false,
    \"title\": \"WIP: ${CI_COMMIT_REF_NAME}\",
}""

我会尝试传递不带引号的$BODY变量:

# Create MR
curl -X POST https://${HOST}/api/v4/projects/${CI_PROJECT_ID}/merge_requests?private_token${PRIVATE_TOKEN}"\
--header "PRIVATE_TOKEN: ${PRIVATE_TOKEN}"\
--header "Content-Type: application/json"\
--data $BODY

对于第三次尝试,我假设您的问题中存在拼写错误,因为您在右大括号前使用了最后一个单引号。另一个问题是您在json中间终止了单引号字符串:

'{
  "id": '"${CI_PROJECT_ID}"',
  ...
}'

因为它以单引号开始,所以它看到的第一个单引号将结束字符串。第一个单引号大约是"${CI_PROJECT_ID}"',所以传递给curl的字符串是:

'{
  "id": '

为了说明为什么curl命令没有抛出退出代码,这仍然是一个法律的的字符串,curl完全可以使用,所以它将其发送到GitLab API。但是当解析数据时,GitLab无法解析它,所以那里什么也不会发生。它会产生一个4xx HTTP代码,但是正如你提到的,你在作业输出中看不到一些信息。
为了解决这个问题,我将删除$CI_PROJECT_ID前后的单引号:

'{
  "id": "${CI_PROJECT_ID}",
  ...
}'

或者,由于$CI_PROJECT_ID是并且将始终是整数,因此可以删除它周围的所有引号:

'{
  "id": $CI_PROJECT_ID,
  ...
}'

相关问题