项目使用了grpc,前端希望每次proto文件有修改时,能自动生成对应的js文件并提交到前端js文件的仓库,于是研究了下gitlab ci,做个记录。
我这边因为用的微服务,每个服务独立一个git仓库,每个服务对应的proto文件也在各自服务的git仓库,所以通过gitlab群组的CI/CD配置定义了几个共用的变量以及整个生成的脚本,方便不同的服务仓库共享。
生成脚本
proto生成js的命令
1 | protoc --proto_path=. --proto_path=../../../protobuf --js_out=import_style=commonjs,binary:. --grpc-web_out=import_style=typescript,mode=grpcweb:. xxx/xxxx.proto |
根据git的修改记录生成对应的js文件
1 | files=$(git diff --name-only HEAD~ | grep '\.proto') |
提交新生成的js文件到git仓库
1 | tsFiles=$(find ./ -name *.ts -type f) |
$TS_PROTO_REPOSITORY_NAME
是gitlab的CI/CD中定义的要提交生成js文件的git仓库地址$TS_PROTO_REPOSITORY_NAME
是gitlab的CI/CD中定义的要提交生成js文件的git仓库名称gitlab ci配置
1
2
3
4
5
6
7
8
9
10ts:
stage: build
only:
- master
extends:
- .template
script:
- chmod +x $GENERATE_TS_BY_PROTO_SCRIPT
- $GENERATE_TS_BY_PROTO_SCRIPT
$GENERATE_TS_BY_PROTO_SCRIPT
是在gitlab的CI/CD配置中,配置的一个文件类型的变量,主要是把上面的shell脚本整合在一个文件里面,定义在gitlab的群组里面,群组下面的所有git仓库(我是微服务,每个服务一个独立的git仓库)可以共用。
配置文件类型的变量需要特别注意,不能勾选
Expand variable reference
这个选项,否则脚本中定义的变量会被提前扩展出来(扩展的时候脚本没执行,没有值),导致脚本执行失败。
下面是$GENERATE_TS_BY_PROTO_SCRIPT
的完整内容:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
if [ -z "$(git diff --name-only HEAD~ | grep '\.proto')" ]; then
echo "no proto file changed!"
exit 0
fi
files=$(git diff --name-only HEAD~ | grep '\.proto')
for filePath in $files
do
protoc --proto_path=. --proto_path=../../../protobuf --js_out=import_style=commonjs,binary:. --grpc-web_out=import_style=typescript,mode=grpcweb:. $filePath
done;
tsFiles=$(find ./ -name *.ts -type f)
git clone --depth 1 --branch master $TS_PROTO_REPOSITORY_ADDR
for tsfilePath in $tsFiles
do
echo "----cp $tsfilePath------"
cp --parents $tsfilePath ./$TS_PROTO_REPOSITORY_NAME
done;
cd ./$TS_PROTO_REPOSITORY_NAME/
git add .;
git commit -m "ci通过${CI_PROJECT_PATH}中${GITLAB_USER_NAME}的提交${CI_COMMIT_SHORT_SHA}同步" -m "${CI_COMMIT_MESSAGE}" || true;
git push;