前言
GitLab CI/CD 是一个内置在GitLab中的工具,用于通过持续方法进行软件开发:
- Continuous Integration (CI) 持续集成
- Continuous Delivery (CD) 持续交付
- Continuous Deployment (CD) 持续部署
持续集成的工作原理是将小的代码块推送到Git仓库中托管的应用程序代码库中,并且每次推送时,都要运行一系列脚本来构建、测试和验证代码更改,然后再将其合并到主分支中。
持续交付和部署相当于更进一步的CI,可以在每次推送到仓库默认分支的同时将应用程序部署到生产环境。
这些方法使得可以在开发周期的早期发现bugs和errors,从而确保部署到生产环境的所有代码都符合为应用程序建立的代码标准。
原理
gitlab 本身只有 CI/CD 的接口,真正执行 CI/CD 任务的是 gilab runner,它负责与 gitlab 通信,接受 CI/CD 任务,并交给 Executor 执行,Executor 有7种类型:
Docker
Shell
Kubernetes
SSH
VirtualBox
Parallels
Custom
Executor的类型在注册 Runner 的时候确定,
执行流程图:
gitlab-runner的安装与注册(linux-centos)
本文介绍Executor为shell类型
安装
sudo curl -L --output /usr/local/bin/gitlab-runner https://gitlab-runner-downloads.s3.amazonaws.com/latest/binaries/gitlab-runner-linux-amd64
# 赋予执行权限
sudo chmod +x /usr/local/bin/gitlab-runner
# 创建一个 GitLab Runner 用户
sudo useradd --comment 'GitLab Runner' --create-home gitlab-runner --shell /bin/bash
# 安装并作为服务运行
sudo gitlab-runner install --user=gitlab-runner --working-directory=/home/gitlab-runner
# 启动
sudo gitlab-runner start
# 重启
sudo gitlab-runner restart
# 停止
sudo gitlab-runner stop
注册
# 注册 runner
[root@localhost ~]# sudo gitlab-runner register --url http://1xx.1xx.x.2xx4:xxxx/ --registration-token GR1xxxxxxxxxxx
Runtime platform arch=amd64 os=linux pid=378174 revision=66269445 version=17.3.1
Running in system-mode.
# 输入 gitlab 的地址
Enter the GitLab instance URL (for example, https://gitlab.com/):
[http://1xx.1xx.x.2xx4:xxxx/]:
# 输入 gitlab 上的 token,就是上面的
Enter the registration token:
[GR1xxxxxxxxxxx]:
# 输入描述信息
Enter a description for the runner:
[localhost.localdomain]: build runner
# 输入标签,这个gitlab-runner输入一个标记,这个 tag 非常重要,在后续的使用过程中需要使用这个 tag 来指定 gitlab-runner
Enter tags for the runner (comma-separated):
build
Enter optional maintenance note for the runner:
WARNING: Support for registration tokens and runner parameters in the 'register' command has been deprecated in GitLab Runner 15.6 and will be replaced with support for authentication tokens. For more information, see https://docs.gitlab.com/ee/ci/runners/new_creation_workflow
Registering runner... succeeded runner=GR1348941w5ZUUAPZ
# 选择执行器,我选的是 shell
Enter an executor: custom, ssh, virtualbox, docker-windows, docker+machine, docker-autoscaler, shell, parallels, docker, kubernetes, instance:
shell
# 可以看到,注册成功了
Runner registered successfully. Feel free to start it, but if it's running already the config should be automatically reloaded!
Configuration (with the authentication token) was saved in "/etc/gitlab-runner/config.toml"
刷新gitlab页面,显示已注册成功
runner配置
runner 注册完成后会在/etc/gitlab-runner/ 目录下生成一个 config.toml 的文件。这个就是 runner 的配置文件
gitlab项目配置
为项目中添加 .gitlab-ci.yml 文件,表示启动的 CI/CD 。默认提交动作会自动运行该 .gitlab-ci.yml 中定义的作业
当文件提交后,会发现流水线已跑
gitlab-ci.yml文件配置参考
将制品上传至软件包库中,实现产品库的概念;
后端项目常用
# 全部打包
stages:
- build
- deploy
build:
stage: build
script:
- echo "Starting build process"
- mvn clean package -T 16C
- echo "Packaging JAR file into ZIP"
- mkdir -p "xxx"
- cp $(find . -name '*.jar') "xxx/"
- zip -r "xxx.zip" "xxx/"
- echo "Build process completed"
# 获取tag描述
- |
TAG_DESC=$(git show "${CI_COMMIT_TAG:-latest}" --no-patch --no-notes --pretty='%B' )
echo "$TAG_DESC" > update_description.txt
artifacts:
paths:
- "xxx.zip"
expire_in: 3 months
rules:
- if: '$CI_COMMIT_TAG'
when: always
- when: never
deploy:
stage: deploy
needs:
- build
script:
- echo "上传软件包库"
- |
# 上传包
curl --header "JOB-TOKEN: $CI_JOB_TOKEN" \
--upload-file "xxx.zip" \
"http://172.xx.xx.xx/api/v4/projects/${CI_PROJECT_ID}/packages/generic/${CI_PROJECT_NAME}/${CI_COMMIT_TAG:-latest}/xxx.zip"
# 上传描述信息
curl --header "JOB-TOKEN: $CI_JOB_TOKEN" \
--upload-file "update_description.txt" \
"http://172.xx.xx.xx/api/v4/projects/${CI_PROJECT_ID}/packages/generic/${CI_PROJECT_NAME}/${CI_COMMIT_TAG:-latest}/update_description.txt"
rules:
- if: '$CI_COMMIT_TAG'
when: always
- when: never
#差异化打包(新建tag时构建)(对比最新的tag与上次tag,将有目录更改的jar包且排除api.jar进行打包)
stages:
- build
- deploy
build:
stage: build
script:
- echo "Starting build process"
# 获取最新标签和上次标签
- |
LATEST_TAG=$(git describe --tags --abbrev=0)
PREV_TAG=$(git describe --tags --abbrev=0 $(git rev-list --tags --max-count=2 --skip=1) | tail -n 1)
echo "Latest tag: ${LATEST_TAG}"
echo "Previous tag: ${PREV_TAG}"
# 获取tag描述
- |
TAG_DESC=$(git show "${CI_COMMIT_TAG:-latest}" --no-patch --no-notes --pretty='%B' )
echo "$TAG_DESC" > update_description.txt
# 查找修改的目录
- |
CHANGED_DIRS=$(git diff --name-only "${PREV_TAG}" "${LATEST_TAG}" | awk -F/ '{print $1}' | sort -u)
echo "Changed directories: ${CHANGED_DIRS}"
# 全项目构建
- mvn clean package -T 16C
# 打包变化的目录中的 JAR 文件
- |
if [ -n "$CHANGED_DIRS" ]; then
PACKAGE_DIR="zzzz"
mkdir -p "$PACKAGE_DIR"
for dir in ${CHANGED_DIRS}; do
find "$dir" -type f -name '*.jar' ! -name '*api.jar' -exec cp {} "${PACKAGE_DIR}/" \;
done
zip -r "${PACKAGE_DIR}.zip" "${PACKAGE_DIR}/"
else
echo "No changes in directories, no JAR files to package"
fi
artifacts:
paths:
- "zzzz.zip"
- "update_description.txt"
# 过期时间
expire_in: 1 week
rules:
- if: '$CI_COMMIT_TAG'
when: always
- when: never
deploy:
stage: deploy
needs:
- build
script:
- echo "上传软件包库"
- |
# 上传包
curl --header "JOB-TOKEN: $CI_JOB_TOKEN" \
--upload-file "zzzz.zip" \
"http://172.xx.xx.xx/api/v4/projects/${CI_PROJECT_ID}/packages/generic/${CI_PROJECT_NAME}/${CI_COMMIT_TAG:-latest}/zzzz.zip"
# 上传描述信息
curl --header "JOB-TOKEN: $CI_JOB_TOKEN" \
--upload-file "update_description.txt" \
"http://172.xx.xx.xx/api/v4/projects/${CI_PROJECT_ID}/packages/generic/${CI_PROJECT_NAME}/${CI_COMMIT_TAG:-latest}/update_description.txt"
rules:
- if: '$CI_COMMIT_TAG'
when: always
- when: never
效果图
前端项目常用
stages:
- build
- deploy
build:
stage: build
script:
- echo "开始打包 xxx"
- yarn cache clean
- yarn install --network-concurrency=16 --registry=https://registry.npmmirror.com
- yarn build
- echo "打包完成 xxx"
- echo "进行压缩"
- tar -czf "dist.tar.gz" -C dist .
# 获取tag描述
- TAG_DESC=$(git show "${CI_COMMIT_TAG:-latest}" --no-patch --no-notes --pretty='%B' )
- echo "$TAG_DESC" > update_description.txt
artifacts:
paths:
- "dist.tar.gz"
- "update_description.txt"
# 过期时间
expire_in: 1 week
rules:
- if: '$CI_COMMIT_TAG'
when: always
- when: never
deploy:
stage: deploy
needs:
- build
script:
- echo "上传软件包库"
- |
# 上传包
curl --header "JOB-TOKEN: $CI_JOB_TOKEN" \
--upload-file "dist.tar.gz" \
"http://172.xx.xx.xx/api/v4/projects/${CI_PROJECT_ID}/packages/generic/${CI_PROJECT_NAME}/${CI_COMMIT_TAG:-latest}/dist.tar.gz"
# 上传描述信息
curl --header "JOB-TOKEN: $CI_JOB_TOKEN" \
--upload-file "update_description.txt" \
"http://172.xx.xx.xx/api/v4/projects/${CI_PROJECT_ID}/packages/generic/${CI_PROJECT_NAME}/${CI_COMMIT_TAG:-latest}/update_description.txt"
rules:
- if: '$CI_COMMIT_TAG'
when: always
- when: never
效果图
H5项目常用
stages:
- build
- deploy
build:
stage: build
script:
- echo "开始打包 zzzx-app"
- yarn cache clean
- yarn install --network-concurrency=16 --registry=https://registry.npmmirror.com
- yarn run build:h5
- echo "打包完成 zzzx-app"
- echo "进行压缩"
- tar -czf "h5.tar.gz" -C dist/build/h5 .
# 获取tag描述
- TAG_DESC=$(git show "${CI_COMMIT_TAG:-latest}" --no-patch --no-notes --pretty='%B' )
- echo "$TAG_DESC" > update_description.txt
artifacts:
paths:
- "h5.tar.gz"
- "update_description.txt"
# 过期时间
expire_in: 1 week
rules:
- if: '$CI_COMMIT_TAG'
when: always
- when: never
deploy:
stage: deploy
needs:
- build
script:
- echo "上传软件包库"
- |
# 上传包
curl --header "JOB-TOKEN: $CI_JOB_TOKEN" \
--upload-file "h5.tar.gz" \
"http://172.xx.xx.xx/api/v4/projects/${CI_PROJECT_ID}/packages/generic/${CI_PROJECT_NAME}/${CI_COMMIT_TAG:-latest}/h5.tar.gz"
# 上传描述信息
curl --header "JOB-TOKEN: $CI_JOB_TOKEN" \
--upload-file "update_description.txt" \
"http://172.xx.xx.xx/api/v4/projects/${CI_PROJECT_ID}/packages/generic/${CI_PROJECT_NAME}/${CI_COMMIT_TAG:-latest}/update_description.txt"
rules:
- if: '$CI_COMMIT_TAG'
when: always
- when: never
效果图
其他
修改上传文件大小限制配置
流水线执行时,出现如下报错
解决
或
修改.gitlab-ci.yml ,在开头配置
variables:
# 设置工件最大尺寸为50MB
ARTIFACTS_MAX_SIZE: "50MiB"
stages:
- build
- deploy
.....
-------------------------------------
本文结束