3、代码仓库搭建:自建GitLab服务器、仓库权限管理、Webhook与CI/CD触发
说到代码仓库,很多团队直接就用GitHub或Gitee了。但嵌入式开发有个特点——代码量大、二进制文件多、有时候还涉及硬件描述文件。我个人的习惯是,只要团队超过5个人,或者有保密需求,就果断自建GitLab。
为什么?说白了,自建GitLab给你的是完全的控制权。你想想看,嵌入式固件里经常包含芯片厂商的SDK,这些东西上传到公有仓库,心里总有点不踏实。我在一个车规级项目里就遇到过,客户审计时明确要求代码必须托管在内网服务器上。嗯,那时候幸好我们提前搭好了GitLab。
3.1 自建GitLab服务器的硬件与系统准备
先说说硬件。GitLab其实挺吃资源的,尤其是内存。我踩过这个坑——第一次用一台2核4G的虚拟机跑,结果跑个CI直接卡死。
| 团队规模 | 推荐配置 | 说明 |
|---|---|---|
| 1-10人 | 4核 / 8G内存 / 100G SSD | 够用,CI并发建议≤2 |
| 10-50人 | 8核 / 16G内存 / 500G SSD | 可以跑4-6个并发CI |
| 50人以上 | 16核 / 32G内存 / 1T SSD | 建议拆分Runner到独立机器 |
系统我推荐Ubuntu 20.04 LTS或22.04 LTS。CentOS虽然稳定,但GitLab官方对Ubuntu的支持更及时。安装过程其实很简单,官方提供了Omnibus一键安装包。
# 更新系统
sudo apt update && sudo apt upgrade -y
# 安装依赖
sudo apt install -y curl openssh-server ca-certificates
# 添加GitLab仓库并安装
curl -sS https://packages.gitlab.com/install/repositories/gitlab/gitlab-ce/script.deb.sh | sudo bash
sudo EXTERNAL_URL="http://gitlab.yourcompany.com" apt install gitlab-ce
# 安装完成后重新配置
sudo gitlab-ctl reconfigure
这里有个小细节——EXTERNAL_URL一定要设对。我曾经因为写成了IP地址,后面改域名时折腾了半天。建议一开始就用域名,哪怕内网DNS解析也行。
sudo gitlab-rake gitlab:check 检查所有组件状态。这一步能提前发现很多潜在问题,比如Redis没启动、PostgreSQL权限不对等。
3.2 仓库权限管理——别让所有人都能push主干
仓库搭好了,接下来就是权限管理。嵌入式项目里,我见过最乱的情况是——实习生不小心把未编译的中间文件push上去了,结果仓库体积暴涨到几个G。
GitLab的权限模型分五个级别:Guest、Reporter、Developer、Maintainer、Owner。我一般这样分配:
- Guest:只读权限,适合给项目经理或测试看代码
- Reporter:可以看代码、提Issue,但不能push
- Developer:可以push到功能分支,但不能push到主干
- Maintainer:可以合并MR、管理分支保护规则
- Owner:完全控制,一般只给1-2个人
重点来了——分支保护。我建议至少保护main和develop分支。设置方法很简单:
# 通过GitLab Web界面操作:
Settings -> Repository -> Protected Branches
# 或者用API设置
curl --request POST \
--header "PRIVATE-TOKEN: your_token" \
--data "name=main&push_access_level=40&merge_access_level=40" \
"http://gitlab.yourcompany.com/api/v4/projects/1/protected_branches"
这里push_access_level=40表示只有Maintainer才能push。Developer只能通过Merge Request来合并代码。我曾经在一个项目中,因为没设这个保护,有人直接往main分支push了一个未测试的驱动,结果整条产线都停了。嗯,从那以后我再也不敢偷懒了。
3.3 Webhook与CI/CD触发——让代码提交自动干活
Webhook这东西,说白了就是一个回调。当仓库发生push、merge、tag等事件时,GitLab会向指定的URL发送一个HTTP POST请求。我一般用它来做两件事:触发CI流水线、通知协作平台(比如飞书或钉钉)。
先看一个最简单的Webhook配置——触发Jenkins构建:
# 在GitLab项目设置中:
Settings -> Webhooks -> Add new webhook
# URL填写Jenkins的触发地址
URL: http://jenkins.yourcompany.com/generic-webhook-trigger/invoke?token=my_token
# 勾选触发事件:
☑ Push events
☑ Merge request events
☑ Tag push events
# 点击Add webhook,然后测试一下
Test -> Push events
测试时如果返回200,说明通了。如果返回500,多半是Jenkins那边没配好。我遇到过最坑的一次是——Jenkins的CSRF保护没关,Webhook死活调不通。折腾了两小时才发现。
再说说GitLab自带的CI/CD。其实GitLab CI比Jenkins轻量多了,尤其适合嵌入式项目。你只需要在项目根目录放一个.gitlab-ci.yml文件:
stages:
- build
- test
- deploy
build_firmware:
stage: build
image: embedded-toolchain:latest
script:
- make clean
- make all
artifacts:
paths:
- build/*.bin
- build/*.hex
expire_in: 1 week
run_unit_tests:
stage: test
script:
- make test
only:
- merge_requests
deploy_to_production:
stage: deploy
script:
- scp build/firmware.bin prod-server:/firmware/
only:
- tags
when: manual
这个配置里我用了几个技巧:
- artifacts:把编译产物保存下来,方便测试人员直接下载
- only: merge_requests:单元测试只在MR时跑,节省资源
- when: manual:部署到生产环境需要手动确认,防止误操作
3.4 避坑指南——我踩过的那些坑
最后分享几个实战中遇到的坑,希望能帮你省点时间:
- 磁盘空间爆炸:GitLab的CI日志和artifacts会占用大量磁盘。记得设置自动清理策略——
Settings -> CI/CD -> Artifacts -> Expire artifacts,我一般设7天。 - Runner注册失败:注册GitLab Runner时,记得用
--executor "docker"参数。我一开始用shell executor,结果环境不一致,本地能编译通过,CI上就报错。 - Webhook重复触发:如果你同时配了push和merge request事件,一个MR合并可能会触发两次构建。解决方案是在CI脚本里加一个
CI_PIPELINE_SOURCE判断。 - 大文件上传超时:嵌入式固件经常有几十MB的hex文件。GitLab默认的nginx上传大小限制是10MB,记得改一下:
sudo gitlab-rake gitlab:env:set GITLAB_UPLOAD_MAX_SIZE=100M
嗯,差不多就这些。代码仓库是整个DevOps流程的基石,搭好了后面的事情就顺了。下一章我们会聊持续集成环境的搭建,到时候会用到今天配的这些基础设施。