☰
gitlab-ci-local:.gitlab-ci.yml 本地运行,3 分钟跑通整条流水线
2026/10/18 15:57:34 网站建设 项目流程

gitlab-ci-local:.gitlab-ci.yml 本地运行,3 分钟跑通整条流水线

【免费下载链接】gitlab-ci-localTired of pushing to test your .gitlab-ci.yml?项目地址: https://gitcode.com/GitHub_Trending/gi/gitlab-ci-local

周四下午 4 点,改完 .gitlab-ci.yml 推上去。6 分钟后流水线挂在 test 阶段第三行:stage 名拼错一个字母,deploy 作业没跑,也没报错,只是安静地不执行。这种"推上去才知道"的坑,靠本地运行就能提前排掉——gitlab-ci-local 就是干这件事的。

它是什么:一条在本地跑 GitLab pipeline 的命令行工具,替代"提交、推送、等 6 分钟、再看到报错"的循环。兼容性上最硬的一条事实:它拿 GitLab 官方 JSON schema 来校验 .yml,远端会报的错,本地执行前就报出来,一次都不用推。

3 分钟装好并跑通第一条本地流水线

打开终端,一条命令装上(npm 通道最通用,Debian 也有 apt 源,macOS 有 brew,另有各平台独立二进制可下):

npm install -g gitlab-ci-local

在自己项目目录里放一个最小 .gitlab-ci.yml,只写一个纯 shell 作业:

hello: script: - echo "pipeline works"

没有 image 的作业默认走 shell executor,不需要 Docker。进项目目录执行gitlab-ci-local,结尾会看到绿色的PASS hello和一句 pipeline finished 的耗时。顺手把alias gcl='gitlab-ci-local'加进 .bashrc,以后命令能短一截。

跑之前想确认"这次到底会执行哪些作业",用gitlab-ci-local --list先看表格,when: never 的作业默认被过滤掉。README 里的示例输出长这样:

name description stage when allow_failure needs test-job Run Tests test on_success false build-job build on_success true [test-job]

还有两个常用开关:--preview打印 defaults / includes / extends / reference 展开后的完整 YML,是排查"变量为什么没生效"的第一站;--list-csv输出 CSV,方便接进脚本。

按日常操作拆解:写配置、跑流水线、排障

我常用的节奏是:改配置前先用--list看一眼,跑挂了先看日志,再单作业重跑。三个阶段各有专属工具。

写配置阶段:用 --list 预览作业清单

先执行gitlab-ci-local --list。schema 校验默认开启,stage 拼错、关键字误用会在执行前直接报出来,不用推上去看;想看包括 when: never 在内的全部作业,换--list-all。

变量管理分三层,作用域从大到小:

  • 项目级:项目根目录默认读.gitlab-ci-local-variables.yml,支持 yaml 和 .env 两种格式
  • 用户级:$HOME/.gitlab-ci-local/variables.yml,按 project / group / global 分节,靠 git remote 匹配
  • 单次运行:--variable KEY=value临时注入

项目级变量文件长这样,密码、token 都该放这里(记得把该文件加进 .gitignore)。值如果是本地文件路径,会被自动当作 File 类型变量:

AUTHORIZATION_PASSWORD: djwqiod910321 KNOWN_HOSTS: '~/.ssh/known_hosts'

include 有一个容易忽略的缓存机制:外部 include(remote / project / component)只拉取一次并缓存在本地,模板仓库有新提交时,加--fetch-includes强制重新拉取,否则行为停留在旧版本。

跑流水线阶段:执行器与 needs 依赖都在本地解析

打开 .yml 看 image 字段:没有 image 的作业默认走 shell executor,有 image 的走 Docker executor。想全部在宿主机跑,用--force-shell-executor,但官方注明:只用于可信仓库。

单个作业直接写名字当位置参数就能跑。--needs会连带执行它的依赖,--only-needs只跑依赖,--stage build跑整个 stage。一条典型的依赖链:

build: script: echo built artifacts: { paths: [dist/] } test: needs: [build] script: ls dist/

gitlab-ci-local test --needs会按顺序执行 build 和 test,build 产出的 dist/ 在 test 里直接可见。artifacts 的落盘规则:shell executor 默认复制回主机当前目录,--no-artifacts-to-source可以关掉(单个作业用# @NoArtifactsToSource注释也行);Docker executor 统一走.gitlab-ci-local/artifacts目录。--shell-isolation则给 shell 作业做工作区隔离,模仿远端行为。

并行作业多了会挤,--concurrency 2限制同时执行的作业数。manual 作业如果被你要跑的作业依赖,必须用--manual <name>显式声明,否则报一个很明确的错,后面避坑清单里有。

排障阶段:30 秒内定位挂掉的作业

流水线跑完,报告按作业列出 PASS / WARN / FAIL,FAIL 和 WARN 后面附最后 3 行日志;完整日志落在.gitlab-ci-local/output/目录下按作业名存文件,直接打开 grep。

重跑单个作业不用整条流水线重来。前者重跑该作业和它全部 needs,后者按名字直接跑 manual 作业:

gitlab-ci-local --needs npm-outdated gitlab-ci-local docker-compose-down

调试长流水线时加--timestamps(或GCL_TIMESTAMPS=true),每行输出带时间戳,报告里还会标出每个作业耗时,慢在哪一目了然。

实战 walkthrough:跑通 docker-compose 示例

clone 仓库,里面有完整示例 examples/docker-compose-nodejs,链路是装依赖、查过时依赖、docker compose 部署:

git clone https://gitcode.com/GitHub_Trending/gi/gitlab-ci-local cd gitlab-ci-local gitlab-ci-local --cwd examples/docker-compose-nodejs/

流水线构成:npm-install(build 阶段,needs: []抢跑)产出 node_modules 制品 → npm-outdated(test 阶段,needs: [npm-install],allow_failure: true)检查可升级依赖 → docker-compose-up(deploy 阶段)拉起服务容器。执行效果如下:

有两个点值得写下来。

一是首跑明显慢,Docker executor 在拉 node 镜像;pull-policy 默认 if-not-present,第二次就快了。

二是 npm-outdated 显示 WARN 而不是 FAIL:ncu 命令发现有可升级依赖时退出码非零,但 allow_failure 让流水线结果仍算成功。这正是验证 allow_failure 语义的好机会——作业本身标红,整条流水线不算挂。

示例里最后的 docker-compose-down 作业写法很"本地"。因为本地跑时 GITLAB_CI 恒为 false,这个作业只在你机器上存在,按名字跑一次即可关掉容器:

rules: - { if: $GITLAB_CI == 'false', when: 'manual' }

这个"local-only 作业"的写法值得抄进自己项目。想要 PHP 场景可以看 examples/docker-swarm-php。

进阶技巧:5 条默认 → 改动 → 收益

  1. 时间戳与耗时:默认输出没有时间信息 → 加--timestamps→ 每行带时间戳,报告标出单作业耗时,慢作业一眼可见。
  2. 强刷 includes:默认外部 include 拉一次就缓存 → 加--fetch-includes→ 行为与模板仓库最新提交一致,避免"模板改了本地没变"。
  3. 全 shell 执行:默认有 image 的作业走 Docker →--force-shell-executor(仅可信仓库)→ 不依赖 Docker,秒级启动,适合快速验证纯脚本作业。
  4. 固定常用参数:默认所有参数都要敲命令行 → 在 cwd 放.gitlab-ci-local-env文件写NEEDS=true、FILE=other.yml(或放$HOME/.gitlab-ci-local/.env)→ 一次配置到处跑,GCL_前缀环境变量同理。
  5. 限制并发:默认独立作业全并行 →--concurrency 2→ 低配机器上容器不扎堆,机器不卡死。

⚠️ 避坑清单:5 个高频问题

  1. 现象:宿主机刚建的文件,容器作业里看不到 →根因:隔离作业只同步 git 跟踪的文件,untracked 和 ignored 文件不会拷进去 →解决:先git add再跑。
  2. 现象:X is when:manual, its needed by Y, and not specified in --manual→根因:manual 作业是你所跑作业的依赖,必须显式声明 →解决:gitlab-ci-local --manual X Y。
  3. 现象:模板仓库已合并新代码,本地行为没变 →根因:外部 include 被缓存 →解决:加--fetch-includes。
  4. 现象:单跑作业报X could not be found→根因:名字写错,或 matrix 展开后作业名带后缀,与 .yml 里写的不同 →解决:先gitlab-ci-local --list确认真实名字。
  5. 现象:第二次运行端口冲突、容器残留 →根因:示例的 docker-compose-up 会留容器,down 作业按设计是 manual →解决:gitlab-ci-local --cwd examples/docker-compose-nodejs/ docker-compose-down。

适合谁用,哪些场景别硬用

先打开你的 .yml 看三样东西:needs 链、artifacts 传递、复杂 rules。占两样以上,本地运行就有实打实的价值。也适合不想在公共机器上碰 secret token 的场景:变量放本地文件,流水线本地调通,再安心推上去。

没必要的场景:只想验证 YAML 语法,GitLab 实例自带的 lint 就够,不用装整套

【免费下载链接】gitlab-ci-localTired of pushing to test your .gitlab-ci.yml?项目地址: https://gitcode.com/GitHub_Trending/gi/gitlab-ci-local

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询