本文是19底年的文章,在公司当时的环境写的了,现在大部分公司都有Devops效能平台采用docker或者oss部署
本来只是想用 curl 去模拟触发部署静态资源的请求的。后来想到如果把这个操作交给 gitlab 操作岂不是更方便? 所以这几天折腾了一下 gitlab 的 CI/CD,读了一些 gitlab 的官方文档,进一步完善了.gitlab-ci.yml。记录这个过程如下:
模拟请求
利用 curl 命令行工具去模拟我们点击 开始构建
时那一时刻发起的第一个请求。
第一个请求
经实践,第一个请求为上面的这个请求,重要参数是 json:xxx 和 Cookie,请求结果是一个 303 重定向。
编写请求脚本
方便起见,首先用浏览器提供的方式,复制该请求。
复制了整个请求之后,删除了一些不必要的参数之后,与提取 env, branch 这些变量之后, 得知下面的脚本
env=uat
branch=test
curl 'https://xxxx/job/tao.tao/build?delay=0sec' \
-H 'Cookie: JSESSIONID=8EF2BD7082FB37279EE93A3B7BB3ED25' \
--data-raw 'json={"parameter":[{"name":"PJ","value":"crm-finance-static"},{"name":"MYENV", "value":"'$env'"},{"name":"TAG","value":"'$branch'"}]}' \
--compressed
上面的脚本是用 cookie 做用户认证的,既然是 cookie,就存在过期的可能。还好 Jenkins 提供了 token 的方法给用户。
具体看官方文档这两篇文章:
https://www.jenkins.io/doc/book/system-administration/authenticating-scripted-clients/
https://www.jenkins.io/blog/2018/07/02/new-api-token-system/
配置了 token 之后,修改之后脚本
env=uat
branch=test
curl 'https://xxxx/job/tao.tao/build?delay=0sec' \
--user tao-tao:1169ee9c0493b27d915632c0577fdd66fd \
--data-raw 'json={"parameter":[{"name":"PJ","value":"crm-finance-static"},{"name":"MYENV", "value":"'$env'"},{"name":"TAG","value":"'$branch'"}]}' \
--compressed
我们直接使用了 sh 上面的脚本.sh
执行,打开 jenkins 发布平台就可以看到有任务在执行了
安排到 gitlab 上面
注:原来已经有了.gitlab-ci.yml 文件存在了,主要负责: 当我们 push 代码到 gitlab 仓库之后,自动执行 build 命令,并且复制到目标静态资源仓库中,之后再 push 到 gitlab 上
不熟悉 gitlab 工作流的话,可以先看,开卷有益
增加如下代码:
deploy:
stage: deploy
only:
- /^(test|pre|dev)$/
script:
- command -v curl >/dev/null 2>&1 || exit 1 #判断是否执行curl,否则推荐脚本
- env="$REF_NAME" # 默认env 与 分支名一致, 特殊处理uat --》 test
- >
if [ "$REF_NAME" == "test" ]; then
env="uat"
fi
- sh ./scripts/fetch-jenkins.sh $env $REF_NAME # 执行脚本, 带上参数
最初我是放在 after_script 中执行的,后来发现 after_script 即使脚本执行出错,gitlab 上面的 CI/CD/Pipelines 的 Job 的状态,照样是 passed 状态。
搜索得知 after_script 中是忽略失败的,如果需要支持的话,要另外安装脚本,具体可以看如下解释:https://gitlab.com/gitlab-org/gitlab-foss/-/issues/43010,所以我后面把它放在了 script 中,这样脚本出错的话,Job 的状态也是 failed 的状态(Job 失败的话,gitlab 还给我们发了邮件)
另外,curl 只是模拟构建请求,但是我们如何判断请求成功还是失败的?前面我们说构建请求是返回 303 重定向的, 没有 response 内容回来,据此我们就可以判断,请求成功还是失败了,如果有请求结果的话,脚本就 exit 1
if [ "$RES" ]; then { echo 'failed!'; exit 1; } fi
.gitlab-ci.yml
与 fetch-jenkins.sh
代码附件:
.gitlab-ci.yml
fetch-jenkins.sh
忽略.gitlab-ci.yml 的作用
如果我们有一个这样的需要,在某一次 push,我不需要 gitlab 执行构建任务,或者我们觉得 gitlab 构建任务 pengding 太久, 或者 running 太慢。 如何解决这个痛点呢?
这样,我们如果控制 push 代码的时候,携带信息通知 gitlab 服务器,达到我们想要的结果。
很幸运,Gitlab CI/CD 是提供这个服务的,只不过有版本限制,
得知,我们的 gitlab runner 版本是是支持 ci.skip。
携带 -o ci.skip
之后 再 Pipelines 中就可以看到 ,如下图所示:跳过 job
本地执行 CI/CD 脚本
如果觉得 gitlab 构建速度太慢,结合我之前写的构建脚本,同样也可以实现自动构建,自动部署。
大概脚本如下:
#!/usr/bin/env bash
set -euo pipefail
branch=$1
curPath=`pwd`
targetPath="./build" # 打包静态资源路径配置, 为了统一推荐clone在源码根目录下的build文件夹(.gitignore 已忽略build)
commitID=`git rev-parse --short HEAD` # get last commit SHA
subModule=finance
curBranch=`git symbolic-ref --short -q HEAD` # get current branch
# 首先判断是否在目标分支build
if [ "$curBranch" != "$branch" ]; then
echo -------------------------------------
echo -e "\033[41;37m please checkout $branch before building \033[0m"
echo -------------------------------------
exit 1
fi
cd "$targetPath"
# 获取分支名称
targetBranch=`git symbolic-ref --short -q HEAD`
# 判断是否在目标分支,不在的话checkout
if [ "$targetBranch" != "$branch" ]; then
git checkout "$branch"
fi
git pull
rm -rf "$targetPath/$subModule/"
cp -r "$curPath/dist/$subModule/" "./"
message="deploy based on $branch from $commitID"
# set +e
git add .
git commit -m "$message"
git push -u origin
cd -
# fetch jenkins interface
case $branch in
dev ) env="dev"
;;
test ) env="uat"
;;
pre ) env="pre"
;;
master ) echo -e "\033[41;37m not support master \033[0m" && exit 0
;;
* ) echo -------------------------------------
echo -e "\033[41;37m branch($branch) error before fetch jenkins \033[0m"
echo -------------------------------------
exit 1
esac
sh ./scripts/fetch-jenkins.sh $env $branch # 执行触发jenkins请求脚本
附件如下:
然后 package.json 在配置如下
直接执行 yarn deploy:dev 就帮助我们构建,push 到静态自然仓库,触发 jenkins 请求,部署到了 dev 了
最后,CI/CD 能有很多方式实现,有待大家挖掘, 这个也算是根据实际的项目情况,打通了 Jenkins,欢迎大家多多交流。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。