先来说一下配置 CI/CD 的目标,咱们在提交代码后即提交 push 申请后 gitLab 会主动生成一个 pipeLine 工作,如果咱们想要在每次提交代码之后都跑一次单元测试就须要对其进行编辑,此外咱们还能够在此运行咱们自定义的脚本来实现更多需要,例如向钉钉收回推送。
上面这就是对应的配置文件——.gitlab-ci.yml
咱们在此文件中次要用到的一共就只有上面几个关键词:
stages:设置运行步骤
variables:定义变量
tags:设置运行环境
script:设置要执行的命令
对于 stages:
stages:
-step1 // 步骤一
-step2 // 步骤二
step_one:
stage: step1 // 申明是属于步骤一
. . .
step_two:
stage: step1 // 申明是属于步骤一
. . .
step_three
stage: step2 // 申明是属于步骤二
. . .
其中 step_one 和 step_two 是并行执行的。step_two 在其后执行。
对于 variables 须要揭示的是 gitLab 有本人内置的变量,咱们能够间接进行应用,只须要在 scrpts: 执行 -env,就能够查看总共有那些变量。
对于 scrpts: 其作用就相当咱们本地的在我的项目根目录下的终端,输出相应指令就能够在运行相应步骤时执行。
对于 tags:申明运行时所用的环境
第一个问题—在远端执行时呈现格局报错
咱们自定义的脚本在本地运行没有问题后就提交到了 gitlab 中通过 gitlab CI/CD 调用时却产生了格局谬误,例如:存在预期之外的“(”等报错。
在网上查找后所失去的问题出处都是呈现在脚本解释器的阐明上即脚本结尾的 #!/bin/bash
然而通过测试——新建 test.sh 在远端运行通过 bash 解释器运行发现并没有问题,不会产生报错;
于是我又认真地看了一边 shell 教程,发现这下面对于函数的阐明是这样的:
没有用到 function 关键字,于是我尝试着去掉它之后发现的确不报错了,但之后在远端执行时还遇到等等其余的格局问题就不在此一一赘述了。
一步一步跟着远端运行的报错解决完格局问题后的确能够在远端残缺运行咱们自定义的.sh 文件,然而为什么在本地就没有这些格局问题在远端就呈现问题了过后还是没有解决,过后只是把它归纳于可能是版本不一样。
所以这样的解决办法就带来了上面第二个问题:
问题二—获取 pipeLine 运行工夫时遇到的问题
在 gitlab 给出的 pipeLine 自带的变量中只有 pipeLine 的创立工夫:CI_PIPELINE_CREATED_AT
一开始是想可不可以间接在 gitLab CI 运行时取得以后工夫,间接在 gitLab 配置文件中计算出其时间差,然而找了很久都没有找到能够间接在 gitLab CI 中获取以后工夫的办法,所以只能转变思路——把 CI_PIPELINE_CREATED_AT
传给咱们的 shell 脚本,在脚本中实现这些操作。
currentTime=`date "+%Y-%m-%d %H:%M:%S"` // 获取工夫
while [-n "$1"]; do //shell 脚本是以字符串为单位承受的变量
case "$1" in
. . .
-M)
PIPE="$2" // 把 $2 即传过来的工夫赋给 PIPE
CURRENT_STAMP=$(date -d "$currentTime" +%s) // 转化为工夫戳
PIPE_STAMP=$(date -d "$PIPE" +%s) // 转化为工夫戳
TIME_STRING=$((CURRENT_STAMP-PIPE_STAMP)) // 计算工夫戳差值
CONTENT=$CONTENT$TIME_STRING"秒"
shift 2 // 将数据前移 2 项,即 $1=$3,$2=$4...
;;
done
在本地执行之后能够失常运行,在远端运行时发现最初计算出来的差值始终为零,起初认为是 pipe_line 的开始工夫有误,然而查看后与预期统一,于是就尝试着在脚本中输入转化后的起始工夫戳和以后工夫戳然而发现其打印后果都为空。
起初还是认为是因为版本不同,于是又在网上找了很多在 shell 中对工夫戳的操作,然而基本上都是大同小异,都不实用。
到了最初才留神到 tags 字段,即给其设置运行环境,当我在其步骤中申明运行环境再运行就能够失常应用了。
tags:
- ubuntu
问题三—获取 pipeLine 对应的 mergeRequest 的链接时遇到的问题
咱们推送到钉钉上的 PipeLine 的运行信息最好要附带上其对应的 mergeRequest 链接,然而在 gitLab 给出的环境变量中并没有间接给出 mergeRequest 链接,而是给出了 CI_OPEN_MERGE_REQUESTS 变量。
CI_OPEN_MERGE_REQUESTS=yunzhiclub/smart-community!9
这阐明了其对应的 mergeRequest 编号是 9, 而咱们还发现 mergeRequest 链接是这样的
https://gitlab.xxx.com:xxxx/xxxclub/smart-community/-/merge_requests/9
这也就是说咱们能够人为把这个链接结构进去,其中 /-/merge_requests/
局部是固定的,咱们能够间接在脚本中申明,而 https://gitlab.xxx.com:xxxx/xxxclub/smart-community
局部能够通过 gitLab 所给出的环境变量 $CI_PROJECT_URL$mergeRequestUrl
取得。
而后咱们要做的就是如何从 CI_OPEN_MERGE_REQUESTS
中只取得其最初的编号,咱们在 shell 中能够通过一下办法来从 string1 中取得截去 string2 局部的字符串 string3。
string3 = ${string1#${string2}}
起初我也想过能不能间接在配置文件运行中间接批改咱们要传给脚本的 contetnt 即内容主体,然而通过测试,在 scrpts 中运行命令只能获取配置文件中内容,然而在其中定义的变量无奈被配置文件获取,所以咱们还是在脚本中进行批改。
而咱们所要去掉的局部即 yunzhiclub/smart-community
可由 CI_PROJECT_PATH
取得,所以咱们要做的就是把这些传给脚本,即
// 配置文件中
- sh send-ding.sh-U $CI_PROJECT_URL$mergeRequestUrl${CI_OPEN_MERGE_REQUESTS#${CI_PROJECT_PATH}"!" . . .
-U)
MERGE_URL="$2"
MARKDOWN_URL="### [pullRequest]($MERGE_URL)"
CONTENT=$MARKDOWN_URL"\n"$CONTENT
shift 2
;;
然而应用 CI_OPEN_MERGE_REQUESTS
取得 mergeRequest 编号会有一个 bug,比方咱们进行完一次 push 后开启 mergeRequest 这时是没有问题的,然而当咱们敞开这个 mergeRequest,再进行 push 而后再开启 mergeRequest 就会发现 CI_OPEN_MERGE_REQUESTS
中所对应的 mergeRequest 还是第一次提出的 mergeRequest,目前在收集相干材料后也没能找到很好的解决办法。