1. 概述
在 GitLab CI 流水线中实现向代码仓库推送变更的能力,可以有效自动化一些场景,例如版本号更新、依赖项升级等。这不仅能减少手动操作,还能提升流程的一致性和可重复性。
本文将介绍几种在 GitLab CI 中实现推送变更的常见认证方式,并附上具体示例代码和配置说明。
2. 使用访问令牌(Access Token)
这是最常见也最简单的一种方式,适用于大多数项目自动化场景。
2.1 配置步骤
GitLab 支持多种访问令牌类型,包括:
- 个人访问令牌(Personal Access Token)
- 项目访问令牌(Project Access Token)
- 群组访问令牌(Group Access Token)
根据你的权限需求选择合适的类型。以个人访问令牌为例,创建一个名为 AUTOMATION_ACCESS_TOKEN
的令牌,并赋予 write_repository
权限:
创建完成后,在项目的 CI/CD 设置中添加一个变量:
2.2 示例配置
将以下内容添加到 .gitlab-ci.yml
文件中:
push_changes:
image: ubuntu:latest
before_script: |
apt-get update && apt-get install -y git >/dev/null
git config --global user.email ${GITLAB_USER_EMAIL}
git config --global user.name ${GITLAB_USER_NAME}
git remote set-url origin https://oauth2:${AUTOMATION_ACCESS_TOKEN}@${CI_PROJECT_URL#https://}.git
script: |
git commit -m "noop" --allow-empty
git push origin -o ci.skip HEAD:main
📌 说明:
git remote set-url
设置了使用 token 的认证方式。git push
使用了-o ci.skip
参数来避免触发新的流水线,防止无限循环。--allow-empty
允许提交空变更。
2.3 实际运行效果
✅ 优点:配置简单,适合快速集成
❌ 缺点:token 管理需谨慎,权限控制不够细粒度
3. 使用 SSH 密钥
使用 SSH 密钥推送代码,适合需要更高安全性和权限控制的场景。
3.1 配置步骤
首先,生成一对 SSH 密钥:
ssh-keygen -t rsa -b 4096 -C "[email protected]"
将公钥添加到 GitLab 用户设置中:
然后,将私钥进行 Base64 编码,并添加为 CI/CD 变量 SSH_PRIVATE_KEY_BASE64
:
cat ~/.ssh/id_rsa | base64
3.2 示例配置
push_changes:
image: ubuntu:latest
before_script: |
apt-get update && apt-get install -y openssh-client git >/dev/null
mkdir -p ~/.ssh && chmod 700 ~/.ssh
echo -n "$SSH_PRIVATE_KEY_BASE64" | base64 -d > ~/.ssh/ssh_private_key
cat << EOF >> ~/.ssh/config
Host gitlab.com
User git
IdentityFile ~/.ssh/ssh_private_key
IdentitiesOnly yes
StrictHostKeyChecking no
EOF
chmod -R 400 ~/.ssh/ssh_private_key ~/.ssh/config
git config --global user.email ${GITLAB_USER_EMAIL}
git config --global user.name ${GITLAB_USER_NAME}
eval "$(ssh-agent -s)"
ssh-add ~/.ssh/ssh_private_key
git remote set-url origin [email protected]:${CI_PROJECT_PATH}.git
script: |
git commit -m "noop" --allow-empty
git push origin -o ci.skip HEAD:main
📌 说明:
- 使用了
ssh-agent
管理私钥。 - 通过
StrictHostKeyChecking no
跳过首次连接确认,避免流水线阻塞。 - 同样使用了
-o ci.skip
避免触发新流水线。
3.3 实际运行效果
✅ 优点:更安全,适合权限控制严格场景
❌ 缺点:配置步骤较多,维护成本略高
4. 使用 GitLab API 推送变更
除了使用 Git 协议,也可以通过 GitLab 提供的 Commit API 来直接推送变更。
4.1 示例配置
push_changes:
image: curlimages/curl:latest
rules:
- if: '$CI_COMMIT_MESSAGE !~ /noop/'
variables:
FILE_PATH: README.md
COMMIT_MESSAGE: noop
API_URL: "https://gitlab.com/api/v4/projects/$CI_PROJECT_ID/repository/commits"
before_script: |
FILE_CONTENT=$(curl --header "PRIVATE-TOKEN: $AUTOMATION_ACCESS_TOKEN" \
"https://gitlab.com/api/v4/projects/$CI_PROJECT_ID/repository/files/$FILE_PATH/raw?ref=$CI_COMMIT_REF_NAME" | base64)
script: |
curl --request POST "$API_URL" \
--header "PRIVATE-TOKEN: $AUTOMATION_ACCESS_TOKEN" \
--header "Content-Type: application/json" \
--data '{
"branch": "'$CI_COMMIT_REF_NAME'",
"commit_message": "'$COMMIT_MESSAGE'",
"actions": [{"action": "update", "file_path": "'$FILE_PATH'", "content": "'$FILE_CONTENT'", "encoding": "base64"}]
}'
📌 说明:
- 通过 API 获取文件内容并重新提交,模拟一次“noop”提交。
- 使用
rules
条件防止无限流水线循环。
4.2 实际运行效果
✅ 优点:无需 clone 仓库,适合轻量级操作
❌ 缺点:API 调用较复杂,对文件内容处理有局限性
5. 总结
方式 | 适用场景 | 安全性 | 易用性 | 推荐指数 |
---|---|---|---|---|
访问令牌(Access Token) | 快速集成、小项目 | 中 | 高 | ⭐⭐⭐⭐ |
SSH 密钥 | 权限控制严格、中大型项目 | 高 | 中 | ⭐⭐⭐⭐⭐ |
GitLab API | 无需 clone 仓库的轻量级操作 | 高 | 低 | ⭐⭐⭐ |
📌 踩坑提醒:
- 不要忘记使用
-o ci.skip
避免无限流水线 - 私钥 Base64 编码时注意格式和换行问题
- Token 和 SSH 密钥都应设置合理的过期时间
通过本文介绍的几种方式,你可以根据项目规模和安全需求,灵活选择最适合的推送方式。