因组内算法开发工作需要搭建一套Gitlab CI实现算法底库的自动化编译和Linux端/车机端离线测试,这里记录一下踩过的坑🤣
简介
GitLab CI/CD 是一个内置在GitLab中的工具,用于通过持续方法进行软件开发:
- Continuous Integration (CI) 持续集成
- Continuous Delivery (CD) 持续交付
- Continuous Deployment (CD) 持续部署
持续集成的工作原理是将小的代码块推送到Git仓库中托管的应用程序代码库中,并且每次推送时,都要运行一系列脚本来构建、测试和验证代码更改,然后再将其合并到主分支中。
持续交付和部署相当于更进一步的CI,可以在每次推送到仓库默认分支的同时将应用程序部署到生产环境。
这些方法使得可以在开发周期的早期发现bugs和errors,从而确保部署到生产环境的所有代码都符合为应用程序建立的代码标准。
GitLab CI/CD 由一个名为 .gitlab-ci.yml 的文件进行配置,改文件位于仓库的根目录下。文件中指定的脚本由GitLab Runner执行。
基于Docker搭建Gitlab CI
为了快速部署,我采用的方案是在将Gitlab Runner和Excutor都部署在docker中。
这里Gitlab Runner的工作原理为:runner运行在一个docker container中,其负责维护一个对应repo的基础分支,当有作业任务分发到当前runner时,runner会根据CI yaml所配置的image创建并启动一个对应的container,在这个container中切换分支更新代码后执行相应的CI命令。
安装Gitlab Runner
GitLab Runner is an application that works with GitLab CI/CD to run jobs in a pipeline.
Gitlab Runner是Gitlab CI/CD实现运行各种作业的软件应用。所以想让自己的机器可以与Gitlab交互运行Gitlab上配置的作业任务,第一步需要在机器上安装Gitlab Runner。安装Gitlab Runner可以直接下载软件安装,也可以使用官方发布的Docker Image,这里我们第二种方法。
1
| docker pull gitlab/gitlab-runner
|
注意:这里有个天坑,老版本的gitlab-runner(<=14.xx)无法控制Runner上接收的job数量,比如配置了Runner仅能同时跑一个job,但是老版本的Runner控制错误导致多个job同时跑在同一个runner的同一个excutor中,具体的问题可以在Issue: Concurrent jobs on a single Runner sometimes run in the same CI_PROJECT_DIR和Issue: CI-Runner shell executor runs concurrently with concurrency=1,Gitlab-Runner开发组应该是2022年初解决的这个问题。
启动Gitlab Runner
1 2 3 4
| docker run -d --name gitlab-runner --restart always \ -v /srv/gitlab-runner/config:/etc/gitlab-runner \ -v /var/run/docker.sock:/var/run/docker.sock \ gitlab/gitlab-runner:latest
|
1
| docker run -d --name gitlab_runner-gwalglib --restart always -v C:\gitlab-runner\config:/etc/gitlab-runner -v /var/run/docker.sock:/var/run/docker.sock gitlab/gitlab-runner:latest
|
/etc/gitlab-runner
: gitlab-runner的配置文件保存路径
注册Runner
上一步我们启动了runner程序,下一步需要将runner注册到对应的Gitlab Repo中,只有注册后Repo的作业任务才能分发到runner程序上。
使用命令docker exec -it gitlab-runner /bin/bash
进入到我们刚刚启动的GitLab Runner的container中,执行注册命令
根据交互提示,完成runner注册。
修改配置
配置文件的路径在/etc/gitlab-runner/config.toml
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
| concurrent = 2 check_interval = 0
[session_server] session_timeout = 1800
[[runners]] name = "your_runner_name" url = "your_url" id = 1 token = "xxx" token_obtained_at = xxx token_expires_at = xxx executor = "docker" limit = 2 [runners.custom_build_dir] [runners.cache] [runners.cache.s3] [runners.cache.gcs] [runners.cache.azure] [runners.docker] tls_verify = false image = "python:latest" privileged = false disable_entrypoint_overwrite = false oom_kill_disable = false disable_cache = false volumes = ["/cache"] shm_size = 0 pull_policy = ["if-not-present"] network_mode = "host"
|
concurrent
: 并行数,同时可以运行的job数量
limit
: runner任务队列中允许接收的job数量
pull_policy = ["if-not-present"]
: 如果使用的docker image已经存在在机器上,那不会执行pull
network_mode = "host"
: docker使用host的网络
完成配置修改后,Gitlab Runner就配置完成啦~
Gitlab Yaml Config
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 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148
| default: image: name: <默认使用的docker image>
stages: - code_analysis - build - test - auto_test - parse_auto_test
variables: DOCKER_AUTH_CONFIG: '{"auths": {"<域名>": {"auth": "<授权token>"}}}'
before_script: - git submodule sync --recursive - git submodule foreach --recursive git fetch - git submodule update --init - git lfs pull
clang-format: stage: code_analysis script: - python3 CI/CodeAnalysis/FormatCheck/run-clang-format.py --style Google -r ./ tags: - cpp_build only: - merge_requests
linux:build: stage: build script: - bash CI/ci-linux-build.sh artifacts: paths: - build/ exclude: - build/install/**/*.pt tags: - cpp_build rules: - if: $CI_PIPELINE_SOURCE == "merge_request_event" - if: $schedule_linux_auto_test_memory == "True"
linux:test: stage: test needs: job: "linux:build" artifacts: true script: - bash CI/ci-run-linux-test.sh tags: - test only: - merge_requests retry: max: 1 when: always
linux:auto_test-memory: stage: auto_test needs: job: "linux:build" artifacts: true artifacts: paths: - build/auto_test_result/ script: - bash CI/ci-linux-auto-test.sh tags: - autotest only: refs: - schedules variables: - $schedule_linux_auto_test_memory == "True" retry: max: 1 when: always
linux:auto_test_report-memory: stage: parse_auto_test before_script: - which python needs: job: "linux:auto_test-memory" artifacts: true artifacts: paths: - build/auto_test_result/ image: name: ubuntu_20_04-python:v1.0 script: - python tools/ProcessAutoTestMemoryData.py build/auto_test_result/memory_collect_data.txt tags: - autotest only: refs: - schedules variables: - $schedule_linux_auto_test_memory == "True" retry: max: 1 when: always
car:auto_test-memory: stage: auto_test needs: job: "qnx:build" artifacts: true image: name: <对应的docker image> variables: ADB_IP: $CI_ADB_IP CAR_ANDROID_DIR: "/data/vendor/nfs/mount/fota/auto_test" CAR_QNX_DIR: "/usr/nfs_ota/fota/auto_test" before_script: - git lfs pull script: - chmod a+x ./CI/ci-qnx-auto-test/test_memory/ci_run_test_memory.sh - ./CI/ci-qnx-auto-test/test_memory/ci_run_test_memory.sh artifacts: paths: - auto_test-car_result/ tags: - autotest only: refs: - schedules variables: - $schedule_car_auto_test_memory == "True" retry: max: 1 when: always
|
References: