在做的项目最近终于接近了第一个里程碑 ,挤了些时间把一直没做的 CI/CD 利用现有的资源和 GitLab 实现了,记录下大概的过程。
CI/CD 是什么,为什么需要 CI/CD
什么是 CI/CD ?持续集成与持续交付
上面这篇文章已经总结得不错了,我这边主要也是利用 CI/CD 确保每次 push 的代码都是完整可编译的,从而减少错误的发生,同时自动部署,免去手动发布 APP 测试版本和登陆测服人工部署网站更新的麻烦,提高工作效率。
相比于原始的编写自动化脚本(shell/python等),yaml 格式的 CI/CD 配置方式简化了流程,提供了很多便捷的功能。但是相对应的,需要查阅相关配置文档,而且需要更强的 shell 命令编写能力
Flutter 项目(目前仅限 Android 端)
安装 GitLab Runner
如上图,进入项目的 GitLab 主页,导航至[设置]-[CI/CD]-展开[Runner]选项卡,可以看到简易教程.
这里我他妈被误导了😤,看到那个大大蓝底的“在 Kubernetes 上安装 Runner”按钮,以为是 Runner 必须安装在 K8s上呢,结果浪费了时间去搭建 K8s 还没搭成功……其实这里表述的真实含义是在 K8s 集群上或者某台服务器上安装 Runner 都是可以的,二选一。。。😑
手动安装 GitLab Runner 的教程在: https://docs.gitlab.com/runner/install/
由于 Flutter 项目环境相对比较难配,为了以后可以方便地在多台设备上配置 Runner, 所以我选择基于 docker 环境用以项目编译。恰好内网中有一台之前创建好专门用于运行 docker 的 debian 服务器,所以这次就把项目需要的 Runner 直接安装在这台服务器上了。
在服务器上执行安装命令(参考:Install GitLab Runner using the official GitLab repositories):
1 2
| curl -L "https://packages.gitlab.com/install/repositories/runner/gitlab-runner/script.deb.sh" | sudo bash export GITLAB_RUNNER_DISABLE_SKEL=true; sudo -E apt-get install gitlab-runner
|
注册 Runner
安装好后运行注册命令:
1
| sudo gitlab-ci-multi-runner register
|
配置如下:
- 设置 GitLab 服务器的地址,用于 Runner 定时查询 GitLab server 是否有新的作业;
- 设置 Token(注册令牌);
- 设置 Runner 的描述,用语在 GitLab 管理页面区分不同的 Runner 实例;
- 设置 tag,和项目通过
.gitlab-ci.yml
文件定义流水线时指定的 tag 匹配;
- 选择执行器,这里输入
docker
;
- 由于上一步选择了 docker,这一步需要指定默认的 Docker image,这里提供的是 flutter 官方的镜像。
建议此时预先 pull 好所需的镜像,这样第一次作业执行时就不用花时间 pull 镜像了:
1
| docker pull cirrusci/flutter:latest
|
这样一来就注册完成了,可以在下面的页面看到新注册的 Runner:
编写 CI 配置文件
回到项目主页,点击 配置 CI/CD
按钮,开始编写 CI 流水线配置:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50
| stages: - release
release_project: image: cirrusci/flutter:latest stage: release script: - export PUB_HOSTED_URL=https://pub.flutter-io.cn - export FLUTTER_STORAGE_BASE_URL=https://storage.flutter-io.cn - sed -i "s/\(version.\+\)[0-9]+\([0-9]\)/\1${CI_JOB_ID}+${CI_JOB_ID}/" pubspec.yaml - echo ${FLUTTER_BUILD_APK_KEY} | base64 -d > key.jks - echo storePassword=${FLUTTER_BUILD_APK_KEY_PASSWD} > android/key.properties - echo keyPassword=${FLUTTER_BUILD_APK_KEY_PASSWD} >> android/key.properties - echo keyAlias=key >> android/key.properties - echo storeFile=${CI_PROJECT_DIR}/key.jks >> android/key.properties - flutter pub get - flutter clean - flutter pub global activate intl_utils - flutter --no-color pub global run intl_utils:generate - sed -i "s/google()/maven { url 'https:\/\/maven.aliyun.com\/repository\/google' }/g" android/build.gradle - sed -i "s/jcenter()/maven { url 'https:\/\/maven.aliyun.com\/repository\/jcenter' }/g" android/build.gradle - sed -i "s/google()/maven { url 'https:\/\/maven.aliyun.com\/repository\/google' }/g" ${FLUTTER_HOME}/packages/flutter_tools/gradle/flutter.gradle - sed -i "s/jcenter()/maven { url 'https:\/\/maven.aliyun.com\/repository\/jcenter' }/g" ${FLUTTER_HOME}/packages/flutter_tools/gradle/flutter.gradle - sed -i "s/https:\/\/storage.googleapis.com/https:\/\/storage.flutter-io.cn\/download.flutter.io/g" ${FLUTTER_HOME}/packages/flutter_tools/gradle/flutter.gradle - flutter -v build apk --no-shrink --target-platform=android-arm - mv build/app/outputs/apk/release/app-release.apk app-release.apk - echo "build success, uploading..." - curl -X 'POST' -F "[email protected]" http://xxx.xxx.xxx.xx/debugger_api/upload/`md5sum app-release.apk | awk '{print $1}'`.apk - python3 deploy.py `md5sum app-release.apk | awk '{print $1}'` ${CI_JOB_ID} "${CI_COMMIT_MESSAGE}" - echo "uploaded, start release..." artifacts: paths: - app-release.apk
tags: - flutter
|
效果
每次向 master 分支提交代码时,都会自动触发 CI 流水线:
可以在作业详情页面查看流水线的日志、下载作业产物等:
作业执行完后自动将apk上传服务器发版,app侧可以检测到版本更新:
加速构建速度
刚配置好的流水线运行时间长达接近一个小时,原因在于每次执行 job 时都会基于 docker base image 开始重新构建环境,需要重新下载 gradle
、flutter插件、android build tools、android 依赖等大量资源,即使配置了镜像加速,重新下载这些东西还是要花费大量时间。
解决办法就是配置这些路径为 docker 的 volume 以持久化数据,防止重复下载。
修改 Runner 服务器的 /etc/gitlab-runner/config.toml
: