本教程使用的是二进制的 gitlab-runner 配合 docker 生成 protobuf 的第三方包,并在分支 merge 时自动发布 tag 版本。
- 准备一台 Linux 机器,能链接到 gitlab 服务器即可
- 准备 gitlab 对应版本的 runner 文件,可以去官网找
我司的 gitlab 太古老,是 10.5.6,配套的 runer 最多只能到 10.0.2 版本 ,下载地址是:
https://gitlab-runner-downloads.s3.amazonaws.com/v10.0.2/bina...
地址是猜出来的。版本对应关系在官网有一个表格,可以参考找表格到自己需要的版本。
一. 安装配置 gitlab-runner:
1. 在 linux 服务上配置帐号:
prepare user for gitlab-runner. We need it run gitlab-runner on Linux system.
sudo passwd gitlab-runner
sudo gpasswd -a gitlab-runner root
sudo su
su gitlab-runner
ssh-keygen
cat ~/.ssh/id_rsa.pub
依次执行,得到一个 public key。存下来,后面备用。
2. 配置 gitlab-runner 用户的 git 权限
(可忽略此步)在 gitlab 上注册一个帐号,记住用户名和邮箱地址,这里假设:
用户名: cicdops
邮箱: cicd@mycompany.com
在这个帐号的 ssh-key 管理中添加步骤 1.1 得到的 public key。就是 cat 输出的结果字符串。
使用上述帐号生成一个 Personal access token,给与读写权限。
为该用户赋予对应仓库的读写权限。
在服务器上进入 gitlab-runner 用户的家目录,也就是 /home/gitlab-runner/
,创建两个文件并写入配置
1. 文件 .netrc
保证 gitlab-runner 可以访问 gitlab,内容如下:
machine gitlab.companyname.com
login cicdops
passwod {token}
token 就是前面生成的 Personal access token
2. 文件 /home/gitlab-runner/.gitconfig
这个文件保证可以使用 ciciops 用户打 tag 并推送
[user]
name = cicdops
email = cicdops@mycompany.com
[url "https://"]
insteadOf = http://
3. 查找 git 仓库的 runner 配置
4. 在服务器上配置并启动 runner
sudo ./gitlab-runner-linux-amd64-10_0_2.bin install --user=gitlab-runner --working-directory=/home/gitlab-runner
sudo ./gitlab-runner-linux-amd64-10_0_2.bin register
sudo ./gitlab-runner-linux-amd64-10_0_2.bin status
sudo ./gitlab-runner-linux-amd64-10_0_2.bin start
依次执行上述命令并填入参数,其中地址和 token 可以从前面步骤的 git 仓库配置中找到。
配置成功之后会在 gitlab 页面看到 runner 有绿色的标记。
二. 配置自动化流程
1. 初始化代码仓库
保证下图红框标记的文件和目录存在
2. 使用 ci 文件定义流程
我的 .gitlab-ci.yml
文件内容如下
variables:
GIT_STRATEGY: clone
stages:
- gen-go-SNAPSHOT
- gen-go-PRODUCTION
generate_go_SNAPSHOT:
variables:
build_branch: dev
stage: gen-go-SNAPSHOT
only:
- dev
- merge_requests
image:
name: rvolosatovs/protoc:v4.1.0-rc1
entrypoint: [""]
script:
- echo $build_branch
- echo $CI_JOB_ID
- bash ./gen-proto.sh $build_branch $CI_JOB_ID
generate_go_PRODUCTION:
stage: gen-go-PRODUCTION
variables:
build_branch: prod
only:
- master
- merge_requests
image:
name: rvolosatovs/protoc:v4.1.0-rc1
entrypoint: [""]
script:
- echo $build_branch
- echo $CI_JOB_ID
- bash ./gen-proto.sh $build_branch $CI_JOB_ID
这个文件不多解释,可以参考 gitlab 官方文档的语法。这里的 ci 文件定义了两个流程,分布在合并到 dev 、 master 分支时触发。具体操作是带参数执行 gen-proto.sh
脚本
3. 使用 shell 脚本实现生成和推送
脚本使用 docker 来生成 protobuf 文件对应的 go 文件,并推送到 git 仓库的 tag 。其中 dev 分支的 tag 带后缀 -dev
以示区分。
#/bin/bash
if [ $# -ne 2 ]; then
echo "Usage: ./gen-proto.sh dev|prod 421"
else
packEnv=$1
num=$2
fi
versionNum=$(date +"1.%y%m%d.")
if [ "$packEnv" = "prod" ] ; then
packEnv="prod"
versionNum=$versionNum$num
else
packEnv="dev"
versionNum=$versionNum$num"-dev"
fi
echo "Package ENV : " $packEnv
echo " Version : " $versionNum
docker run --rm -v $(pwd):/opt/pbdir/ rvolosatovs/protoc:v4.1.0-rc1 \
--proto_path=/opt/pbdir/proto \
--go_out=paths=source_relative:/opt/pbdir/package-go/ \
--go-grpc_out=paths=source_relative:/opt/pbdir/package-go/ \
/opt/pbdir/proto/*.proto
cmsg=`git log --pretty=format:'%s - %an' | head -n 2 | tail -n 1`
rm -rf package-go/go.mod
cp go.mod.tpl go.mod
rm -rf ./*.go
cp package-go/*.go ./
git add .
git commit -m "$cmsg"
git tag -a $versionNum -m ""
git push origin --tags
go.mod.tpl 文件自己按照自己的需求写一个即可。
遇到一个 push 时报错的问题
解决方法:sed -i 's/gitlab-ci-token:.*@/cicdops:{YourPrivateToken}@/g' .git/config
4. 使用 protoc-gen-openapi 实现文档的自动生成和内网发布
- 下载 protoc-gen-openapi 的二进制文件
github 的 release 页面有二进制,下载,放到 runner 服务器的目录上,通过挂载将二进制挂载到 path 中,注意这里把二进制改名为 protoc-gen-openapiv2
docker run --rm -v $(pwd):/opt/pbdir/ -v /home/gitlab-runner/bin:/opt/bins/ -e PATH=/opt/bins:$PATH \
rvolosatovs/protoc:v4.1.0-rc1 \
--proto_path=/opt/pbdir/proto \
--go_out=paths=source_relative:/opt/pbdir/package-go/ \
--go-grpc_out=paths=source_relative:/opt/pbdir/package-go/ \
--grpc-gateway_out=paths=source_relative:/opt/pbdir/package-go \
--openapiv2_out=/opt/pbdir/ \
--openapiv2_opt=logtostderr=true \
/opt/pbdir/proto/*.proto
这样 build 的时候会生成 api.swagger.json
文件
- 下载 swagger-ui 放到 nginx 目录下
此步骤略去,注意 ui 需要修改 swagger-initialer.json 中的配置 url 。此 url 即为上面步骤生成的文件地址。
- 建立 web 索引文件,维护 json 文件中的版本
修改上述的 gen-proto.sh 文件,添加下面内网
if [ "$packEnv" = "dev" ]; then
sed -i 's/version not set/'${versionNum}'/g' api.swagger.json
sed -i 's/internal-credit-dev-version.*internal-credit-dev-version/internal-credit-dev-version>'${versionNum}'<internal-credit-dev-version/g' /var/www/html/index.html
mv api.swagger.json /var/www/html/swagger-files/internal-credit-dev/
else
sed -i 's/version not set/'${versionNum}'/g' api.swagger.json
sed -i 's/internal-credit-version.*internal-credit-version/internal-credit-version>'${versionNum}'<internal-credit-version/g' /var/www/html/index.html
mv api.swagger.json /var/www/html/swagger-files/internal-credit/
fi
其中 index.html 原始内容为:
<head>
<meta charset="UTF-8">
<title>Swagger UI</title>
<link rel="stylesheet" type="text/css" href="./swagger-ui.css" />
<link rel="stylesheet" type="text/css" href="index.css" />
<link rel="icon" type="image/png" href="./favicon-32x32.png" sizes="32x32" />
<link rel="icon" type="image/png" href="./favicon-16x16.png" sizes="16x16" />
</head>
<body>
<ul>
<li style="font-size: 24px; font-weight:bold;">
XXX 服务 ( DDDreddit )
<ul>
<li>
<a href="http://192.168.255.654/internal-xxx/">
internal-xxx </a>
<sup style="color:green">
<internal-xxx-version>v1.230625.4721<internal-xxx-version>
</sup>
</li>
<li><a href="http://192.168.255.654/internal-ddd-dev/">
internal-xxx-dev</a>
<sup style="color:blue">
<internal-xxx-dev-version>v1.230625.4720-dev<internal-xxx-dev-version>
</sup>
</li>
</ul>
</li>
</ul>
</body>
</html>
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。