博客 / 詳情

返回

現代化 protobuf 包管理 - 七個步驟使用cicd生成第三方包

本教程使用的是二進制的 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 配置

image.png

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 有綠色的標記。
image.png

二. 配置自動化流程

1. 初始化代碼倉庫

保證下圖紅框標記的文件和目錄存在

image.png

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>
user avatar
0 位用戶收藏了這個故事!

發佈 評論

Some HTML is okay.