我用Gemini写CI/CD脚本:40分钟的事8分钟干完,但有些坑必须说
AI助力CI/CD脚本开发:效率提升与避坑指南 摘要: 本文分享了使用Gemini AI生成CI/CD脚本的实际体验。测试表明,Gemini在生成基础GitLab CI/GitHub Actions配置时表现良好,能将40分钟的工作压缩至8分钟完成,特别适合从零搭建脚本框架。但存在需要人工干预的关键点:1)必须手动添加任务依赖链(needs);2)Docker标签需改为动态生成;3)SSH脚本需补
我用Gemini写CI/CD脚本:40分钟的事8分钟干完,但有些坑必须说
我之前对用AI写CI/CD脚本是怀疑的。运维脚本错一个字符,整个流水线挂掉,比业务代码出Bug刺激多了。但上个月试着用Gemini 2.5 Pro写了一组GitLab CI和GitHub Actions脚本,发现有些场景它还真能打。下面是我实际踩过的坑,以及哪些场景值得用、哪些别碰。
一、先说结论:Gemini能打,但不全能
我测了5个场景:
| 场景 | Gemini表现 | 我的评价 |
|---|---|---|
| 生成基础GitLab CI配置 | 能打,改几行就能用 | 省时间 |
| 生成GitHub Actions workflow | 几乎不用改 | 表现最好 |
| 多环境部署脚本(dev/staging/prod) | 逻辑对,环境变量要核对 | 需要人工检查 |
| K8s部署CI步骤 | 能用,但最好你懂K8s | 不懂就别用 |
| 调试CI报错 | 把日志贴给它,分析得挺准 | 强烈推荐 |
一句话总结:Gemini适合"从0到1"生成脚本骨架,不适合"从99到100"处理复杂边界条件。如果你对CI/CD有一定了解,它能省60-70%的时间;如果你完全不懂,它会给你一个看起来对但跑不起来的东西。
二、GitHub Actions自动部署:从40分钟压缩到8分钟
我想实现的功能
- 推送到
main分支时自动跑测试 - 测试通过后自动构建Docker镜像推到Docker Hub
- 自动部署到云服务器(SSH执行命令)
- 部署完成发企业微信通知
我的Prompt(这个写法成功率最高)
我需要生成一个GitHub Actions workflow文件,要求:
1. 触发条件:推送到main分支,或手动触发
2. 环境变量通过GitHub Secrets管理:
- DOCKER_USERNAME / DOCKER_PASSWORD
- SSH_HOST / SSH_USERNAME / SSH_KEY
- WECHAT_WEBHOOK_URL
3. 步骤:
a) 运行npm test(Node.js项目)
b) 构建Docker镜像推送到Docker Hub,tag用commit SHA+latest
c) SSH连接云服务器,执行docker pull并重启容器
d) 调用企业微信webhook发部署结果通知
4. 用GitHub Actions最佳实践(依赖缓存、needs依赖链、只需要的步骤)
Gemini生成的workflow(我微调后的最终版)
name: Deploy to Production
on:
push:
branches: [main]
workflow_dispatch:
env:
DOCKER_REGISTRY: docker.io
IMAGE_NAME: myorg/myapp
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 20
cache: npm
- run: npm ci
- run: npm test
build-and-push:
needs: test # 这行很关键,Gemini第一版没加
runs-on: ubuntu-latest
outputs:
image-tag: ${{ steps.meta.outputs.tags }}
steps:
- uses: actions/checkout@v4
- uses: docker/setup-buildx-action@v3
- uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
- id: meta
uses: docker/metadata-action@v5
with:
images: ${{ env.DOCKER_REGISTRY }}/${{ env.IMAGE_NAME }}
tags: |
type=sha,format=short
type=raw,value=latest,enable={{is_default_branch}}
- uses: docker/build-push-action@v6
with:
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
deploy:
needs: build-and-push # 这行Gemini也没加,我手动补的
runs-on: ubuntu-latest
steps:
- name: Deploy to server via SSH
uses: appleboy/ssh-action@v1.0.0
with:
host: ${{ secrets.SSH_HOST }}
username: ${{ secrets.SSH_USERNAME }}
key: ${{ secrets.SSH_KEY }}
script: |
set -e # 这行很重要,Gemini没加,我补的:任何命令失败就退出
cd /opt/myapp
docker compose pull
docker compose up -d
docker system prune -f
- name: Notify WeChat
if: always()
run: |
curl -X POST "${{ secrets.WECHAT_WEBHOOK_URL }}" \
-H "Content-Type: application/json" \
-d "{\"msgtype\":\"text\",\"text\":{\"content\":\"🚀 部署完成\n分支: main\n状态: ${{ job.status }}\"}}"
我微调了3个地方
1. 加了needs依赖链
Gemini第一版把test、build、deploy三个job平行写了,导致deploy在test还没跑完就开始了。我加了needs: test和needs: build-and-push,保证顺序执行。
2. Docker tag改用动态生成
Gemini原本写的是tags: latest硬编码。这样每次部署都会覆盖latest,出问题时无法回滚到特定版本。我让它改成用docker/metadata-action动态生成基于commit SHA的tag。
3. SSH脚本加了set -e
这句的意思是:任何命令失败就立即退出script。Gemini生成的script没有错误处理,如果docker compose pull失败了,up -d还是会执行,导致部署一个旧版本。
时间对比:之前手写这套workflow大概40分钟(查文档+调试),用Gemini大概8分钟(生成+检查+微调)。
三、Gemini调试GitLab CI报错:比翻文档快
这个场景我强烈推荐——把报错日志贴给Gemini,让它分析,比你自己搜GitLab文档快得多。
我遇到的报错
ERROR: Job failed: exit code 1
fatal: unable to access 'https://gitlab-ci-token:xxxxx@gitlab.com/myorg/myrepo.git/': The requested URL returned error: 403
我的Prompt
我的GitLab CI报上面的错。这是.gitlab-ci.yml相关部分:
stages:
- test
- deploy
test:
stage: test
image: node:20
script:
- npm ci
- npm test
deploy:
stage: deploy
image: alpine:latest
before_script:
- apk add --no-cache curl
script:
- curl -X POST "$DEPLOY_WEBHOOK_URL"
only:
- main
帮我分析可能的原因,以及怎么修。我的GitLab版本是16.5。
Gemini给出了4个可能原因(按概率排序)
原因1(概率最高):CI_JOB_TOKEN权限收紧
GitLab 16.0之后,CI_JOB_TOKEN的默认权限收紧了。如果你的项目设置了ci_job_token_scope,跨项目访问会被拒。
修法:Settings → CI/CD → Token Access,把目标项目加进去。
原因2:仓库迁移后URL没更新
本地.git/config里的URL还是老的。运行git remote set-url origin <新URL>。
原因3:2FA启用但token没更新
如果启用了2FA,Personal Access Token需要重新生成,勾选api权限。
原因4:GitLab Runner的helper image版本太老
运行gitlab-runner --version检查,如果低于15.0,升级Runner。
实际情况:原因1命中
我们公司把仓库从GitLab.com迁移到了自建GitLab,忘了更新ci_job_token_scope设置。Gemini排在第一位的原因正好命中。
这个场景为什么推荐用AI:CI/CD的报错信息通常很含蓄,文档分散在各个版本迁移指南里。Gemini训练数据里包含了大量Stack Overflow问题和GitLab issue,所以它能把"报错→可能原因→解决方法"这个链路直接给你,省去你自己在文档里翻版本变更说明的时间。
但有个坑:Gemini有时会给过时的解决方案(比如GitLab 14.x的配置方法,但你在用16.x)。一定要核对它给的配置项是否在你用的版本里存在。
四、多环境GitLab CI:Gemini生成的配置需要大改
这个场景Gemini的表现一般——能生成能跑的配置,但在最佳实践上差点意思。
我的需求
- 推送到
develop分支 → 部署到dev环境 - 推送到
main分支 → 部署到staging环境 - 打
v*tag → 部署到production,需要手动批准
Gemini生成的配置(我大改后的版本)
stages:
- test
- build
- deploy
variables:
DOCKER_DRIVER: overlay2
IMAGE: $CI_REGISTRY/$CI_PROJECT_PATH
# 模板:重用逻辑(Gemini第一版没加这个)
.job_template: &job_template
image: docker:24.0.5
services:
- docker:24.0.5-dind
before_script:
- echo $CI_REGISTRY_PASSWORD | docker login -u $CI_REGISTRY_USER --password-stdin $CI_REGISTRY
test:
stage: test
image: node:20
script:
- npm ci
- npm test
- npm run lint
rules:
- if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
- if: '$CI_COMMIT_BRANCH'
build:
stage: build
<<: *job_template # 用了YAML anchor重用,Gemini第一版是重复写的
script:
- docker build -t $IMAGE:$CI_COMMIT_SHORT_SHA .
- docker push $IMAGE:$CI_COMMIT_SHORT_SHA
rules:
- if: '$CI_COMMIT_BRANCH == "main" || $CI_COMMIT_BRANCH == "develop"'
- if: '$CI_COMMIT_TAG =~ /^v\d+\.\d+\.\d+$/'
deploy:dev:
stage: deploy
<<: *job_template
script:
- docker pull $IMAGE:$CI_COMMIT_SHORT_SHA
- echo "Deploying to DEV..."
- ./scripts/deploy.sh dev
environment:
name: dev
url: https://dev.myapp.com
rules:
- if: '$CI_COMMIT_BRANCH == "develop"'
deploy:staging:
stage: deploy
<<: *job_template
script:
- docker pull $IMAGE:$CI_COMMIT_SHORT_SHA
- echo "Deploying to STAGING..."
- ./scripts/deploy.sh staging
environment:
name: staging
url: https://staging.myapp.com
rules:
- if: '$CI_COMMIT_BRANCH == "main"'
deploy:prod:
stage: deploy
<<: *job_template
script:
- docker pull $IMAGE:$CI_COMMIT_SHORT_SHA
- echo "Deploying to PRODUCTION..."
- ./scripts/deploy.sh prod
environment:
name: production
url: https://myapp.com
rules:
- if: '$CI_COMMIT_TAG =~ /^v\d+\.\d+\.\d+$/'
when: manual # 需要手动批准
我改了3个关键地方
1. 提取了YAML anchor重用配置
Gemini第一版把before_script和image在每个job里重复写了三遍。我让它提取成<<: *job_template。这个改法在GitLab CI文档里有,但Gemini不会主动这样做,需要你提示。
2. rules替代了only/except
Gemini第一版用的是only/except语法(GitLab 14.x的写法)。我让它改成了rules(15.x+推荐)。如果你用的是GitLab 15+,一定要用rules。
3. 加了environment声明
GitLab的Environment功能可以让你在UI里看到每次部署的状态和回滚按钮。这个Gemini没主动加,我手动补上了。补上之后,在GitLab项目的"部署"页面可以看到每个环境的当前版本,回滚只要点一下。
五、Prompt怎么写,Gemini生成的CI脚本才靠谱
我测下来,同样的任务,Prompt写法不同,生成质量差很多。下面是我总结的4个技巧。
技巧1:给它完整的上下文,不要只说"帮我写一个CI配置"
差的Prompt:
帮我写一个GitLab CI配置,用于Node.js项目的测试和部署。
好的Prompt:
帮我写一个.gitlab-ci.yml,用于Node.js 20项目。
项目信息:
- 测试命令:npm test(需要MongoDB,用service方式启动)
- 构建:npm run build,输出在dist/目录
- 部署:构建Docker镜像推送到$CI_REGISTRY,然后用SSH部署到目标服务器
- 分支策略:develop→dev,main→staging,v* tag→prod(手动批准)
- 使用GitLab 16.x,请用rules语法,不要用only/except
为什么:CI/CD配置高度依赖具体技术栈和版本。你给的上下文越具体,它生成的东西需要改的地方越少。
技巧2:让它"先解释再写"
在Prompt最后加一句:
在写配置之前,先说明你选择的CI策略和每个步骤的设计原因。
效果:Gemini会先输出一段分析,告诉你"为什么用rules而不是only"“为什么把test和build分成两个job”。这段分析能帮你判断它是否理解你的需求——如果分析部分就有错误,生成出来的配置大概率也有问题,你可以早点让它重改,而不是等到跑CI的时候才发现有问题。
技巧3:调试报错时,把相关配置也贴进去
很多人贴报错的时候只贴错误日志,但不贴对应的CI配置。Gemini没有配置上下文,只能靠错误信息猜。
推荐贴的内容:
- 完整报错日志(包括stack trace)
- 对应的CI配置文件(
.gitlab-ci.yml或.github/workflows/*.yml) - 你的GitLab/GitHub Actions版本(很关键,不同版本的配置语法有差异)
- 你预期的行为 vs 实际的行为
技巧4:迭代,但不要指望一次生成完美结果
我的做法是:
- 先让Gemini生成基础版本
- 我跑一遍,把报错贴回去
- 让它修复,通常2-3轮能收敛
但有个上限:如果基础逻辑有问题(比如它选了一个不适合你场景的CI策略),迭代修复不如重写Prompt。我一般3轮还没修好,就重新开始,换个思路描述需求。
六、Gemini vs Claude vs Cursor:写CI/CD脚本谁更强?
我用这三个工具写了同一套GitHub Actions workflow(就是第二节的那个案例),对比结果:
| 维度 | Gemini 2.5 Pro | Claude Sonnet 4 | Cursor (GPT-4o) |
|---|---|---|---|
| 生成速度 | 快 | 中 | 快 |
| 首次生成准确率 | 75% | 85% | 70% |
| 调试报错能力 | 强 | 中 | 中 |
| 对CI/CD概念的理解 | 深 | 最深 | 中 |
| 生成配置的简洁度 | 中 | 最优 | 冗余较多 |
| 免费额度 | 有 | 有限 | 有限 |
我的结论:
- 首次生成:Claude最强,它生成的配置通常不需要大改
- 调试迭代:Gemini最强,分析报错的能力比Claude稍好,而且免费额度够大
- 局部修改:Cursor最适合——因为它能看到你的整个仓库上下文,而Gemini/Claude你只能贴文件内容
七、这些场景,别用AI写CI/CD脚本
说了这么多优点,也要说清楚边界。
1. 你完全不懂CI/CD,想让AI"帮我搞一套"
别这样做。AI生成的配置需要你判断安全性、正确性和适用性。如果你不懂,你没法判断它生成的东西会不会把你的生产环境搞挂。
最低门槛:你需要理解CI/CD的基本概念(pipeline、job、stage、artifact),能读懂生成的配置每一行在干什么。
2. 涉及敏感操作的配置(生产环境部署、数据库迁移)
AI不知道你的具体安全策略。它生成的脚本可能包含:
- 把secrets明文写在配置文件里(应该用GitHub Secrets/GitLab CI Variables)
- 过度授予权限(比如GitHub Actions用了
permissions: write-all) - 没有错误处理,部署失败了也返回成功
做法:涉及生产环境的脚本,一定要人工review每一行。
3. 公司有特殊合规要求(等保、SOX、HIPAA)
AI训练数据里不会有你们公司的内部合规规范。它生成的配置可能不符合你们的安全基线。这种场景,老老实实看公司的CI/CD规范文档。
八、总结:Gemini写CI/CD脚本的正确用法
值得用Gemini的场景:
- ✅ 从零生成基础CI/CD配置(GitHub Actions / GitLab CI / Jenkinsfile)
- ✅ 调试CI报错(把日志贴给它分析)
- ✅ 重构已有配置(比如从
only/except迁移到rules) - ✅ 写CI相关的辅助脚本(如部署脚本、健康检查脚本)
不值得用(至少不能只用AI)的场景:
- ❌ 生产环境部署配置,没有人工review
- ❌ 你完全不懂CI/CD,想让AI全权负责
- ❌ 公司有特定合规要求,需要符合内部规范
我的工作流:
- 用Gemini生成第一版配置(省时间)
- 人工review关键部分(安全相关、生产环境相关)
- 推到测试分支跑一遍(验证)
- 如果报错,把日志贴回Gemini迭代(通常2-3轮收敛)
- 合并到主分支,设置好分支保护规则
参考资料:
- GitLab CI/CD Documentation (v16.x): https://docs.gitlab.com/ee/ci/
- GitHub Actions Documentation: https://docs.github.com/en/actions
- 本文所有案例来自本人实际测试(Gemini 2.5 Pro,2026年4月-5月)
我之前对AI写CI/CD是怀疑的,现在态度是"可以用,但要review"。如果你用Gemini写CI/CD的时候踩了什么坑,欢迎评论区交流。
更多推荐



所有评论(0)