stages定义有序的阶段列表。同一阶段的作业并行运行;只有当前阶段所有作业成功后才启动下一个阶段。没有 `stage` 键的作业默认属于 `test` 阶段。
stages: - build - test - deploy
GitLab CI/CD 速查表,80+ 条目,覆盖流水线结构、作业配置、rules、变量、制品、Runner、模板、安全与 API。
stages定义有序的阶段列表。同一阶段的作业并行运行;只有当前阶段所有作业成功后才启动下一个阶段。没有 `stage` 键的作业默认属于 `test` 阶段。
stages: - build - test - deploy
workflow:rules控制是否创建流水线。在任何作业之前求值。用来避免重复流水线(例如,分支推送和 MR 事件对同一提交分别创建流水线)。
⚠ 常见坑: 没有 `workflow:rules`,GitLab 会对同一提交同时创建分支流水线和 MR 流水线,这是重复运行最常见的原因。
workflow:
rules:
- if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
- if: '$CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH'
- if: '$CI_COMMIT_TAG'default为流水线中所有作业设置默认值。支持:`image`、`before_script`、`after_script`、`tags`、`retry`、`timeout`、`interruptible`、`artifacts`、`cache`。作业级键会覆盖这些默认值。
default:
image: node:20-alpine
before_script:
- npm ci --prefer-offline
retry:
max: 2
when: runner_system_failure
interruptible: trueinclude从外部文件导入 YAML 到当前流水线。类型:`local`(同仓库)、`project`(另一个 GitLab 仓库)、`remote`(HTTP URL)、`template`(GitLab 内置模板)。文件被合并,后者覆盖前者。
include:
- local: '.gitlab/ci/build.yml'
- template: 'Security/SAST.gitlab-ci.yml'
- project: 'my-group/ci-templates'
ref: main
file: '/templates/docker-build.yml'trigger (multi-project pipeline)在另一个项目中触发流水线。下游流水线异步运行,除非设置 `strategy: depend`,此时触发作业会镜像下游流水线的状态。
⚠ 常见坑: 没有 `strategy: depend`,触发作业无论下游流水线结果如何都显示"通过"——损坏的部署可能被忽视。
deploy-downstream:
trigger:
project: my-group/deploy-repo
branch: main
strategy: depend
variables:
IMAGE_TAG: $CI_COMMIT_SHAtrigger (child pipeline)从同一项目内的生成或静态 YAML 文件触发子流水线。子流水线嵌套在父流水线下显示。用于动态流水线生成(`generate-config` 作业写出 YAML,trigger 读入它)。
generate:
script: python generate_pipeline.py > pipeline.yml
artifacts:
paths: [pipeline.yml]
run-child:
trigger:
include:
- artifact: pipeline.yml
job: generate.gitlab-ci.yml skeleton包含三个阶段的最小可用流水线。`image` 键为所有作业设置默认 Docker 镜像。每个阶段可以包含多个并行运行的作业。
stages: [build, test, deploy]
image: alpine:3.19
build-job:
stage: build
script:
- echo "Building…"
test-job:
stage: test
script:
- echo "Testing…"
deploy-job:
stage: deploy
script:
- echo "Deploying…"
rules:
- if: '$CI_COMMIT_BRANCH == "main"'include:component从 GitLab 目录引用 CI/CD 组件(GitLab 16.0+)。组件是有版本、自文档化的流水线构建块。用 `~latest` 或固定具体版本标签以保证稳定性。
include:
- component: gitlab.com/components/sast/sast@~latest
inputs:
stage: securityscript / before_script / after_script`script` 是作业中唯一必填的键——shell 命令列表。`before_script` 在 `script` 前运行(覆盖全局默认值)。`after_script` 在 `script` 后始终运行,即使 `script` 失败,因此用它做清理工作。
test-unit:
stage: test
before_script:
- cp .env.test .env
script:
- npm test
after_script:
- rm -f .envallow_failure`allow_failure: true` 允许流水线在该作业失败时继续运行——作业显示橙色警告图标而非红色。用于非阻断性质量检查。`allow_failure:exit_codes` 可指定哪些退出码被允许失败。
lint:
script: npm run lint
allow_failure: true
# Allow only specific exit code
dependency-check:
script: ./check-deps.sh
allow_failure:
exit_codes: [2, 3]retry自动重试失败的作业。`max` 设置重试次数(1 或 2)。`when` 限制只在特定失败类型时重试:`runner_system_failure`、`runner_unsupported`、`stuck_or_timeout_failure`、`script_failure`、`api_failure`、`always`。
deploy:
script: ./deploy.sh
retry:
max: 2
when:
- runner_system_failure
- stuck_or_timeout_failuretimeout设置作业的最长运行时间。覆盖项目级和 Runner 级超时。使用 Go 时长格式:`30m`、`1h 30m`、`2h`。超过超时时间后作业被取消。
e2e-tests: script: npm run test:e2e timeout: 2h 30m unit-tests: script: npm test timeout: 10 minutes
when`when` 控制作业相对于前一阶段状态的运行时机。取值:`on_success`(默认)、`on_failure`(仅当前一阶段失败)、`always`(无论如何)、`manual`(需人工点击)、`delayed`(延迟 `start_in` 后运行)、`never`。
⚠ 常见坑: `when: manual` 会在该阶段阻塞流水线,除非同时设置 `allow_failure: true`。否则后续阶段必须等人工点击才能运行。
notify-on-failure: script: ./notify.sh when: on_failure deploy-to-prod: script: ./deploy-prod.sh when: manual allow_failure: false canary-deploy: script: ./canary.sh when: delayed start_in: 30 minutes
environment将作业与 GitLab 环境关联(不存在时自动创建)。启用部署跟踪、环境范围变量和 Environments 仪表板。用 `environment:url` 在 GitLab UI 里显示实时链接。
deploy-staging:
script: ./deploy.sh staging
environment:
name: staging
url: https://staging.example.com
deploy-review:
script: ./deploy.sh review/$CI_COMMIT_REF_SLUG
environment:
name: review/$CI_COMMIT_REF_SLUG
url: https://$CI_COMMIT_REF_SLUG.review.example.com
on_stop: stop-reviewcoverage用正则从作业脚本输出中提取覆盖率百分比。捕获的数字显示在 GitLab UI、MR 组件和流水线徽章中。配合 `artifacts:reports:coverage_report` 可获得行级覆盖率。
test: script: pytest --cov=myapp --cov-report=term-missing coverage: '/TOTAL.*s+(d+%)$/' test-node: script: npm test -- --coverage coverage: '/Liness*:s*(d+.?d*)%/'
pages部署到 GitLab Pages 的特殊作业名。必须产生 `artifacts:paths: [public]` 目录。Pages 作业必须在 `pages` 或 `pages:` 命名空间下,并在默认分支上运行。
pages:
stage: deploy
script:
- npm run build
- mv dist/ public/
artifacts:
paths:
- public
rules:
- if: '$CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH'inherit控制作业级 `variables` 和 `default` 值是否从全局范围继承。`inherit:variables: false` 阻止全局变量泄漏到作业中。`inherit:default: false` 跳过全局 `default` 键。
deploy:
script: ./deploy.sh
inherit:
default: false
variables:
- DEPLOY_TOKEN
- TARGET_ENVrules:if用 CI/CD 变量表达式条件包含作业。规则从上到下求值,第一个匹配的规则生效。没有规则匹配时,作业默认被排除。用 `when: never` 作为兜底显式排除。
deploy:
script: ./deploy.sh
rules:
- if: '$CI_COMMIT_BRANCH == "main"'
when: on_success
- if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
when: never
- when: neverrules:changes仅当指定文件相对于对比目标发生变化时才运行作业。适合 monorepo 流水线,只构建受影响的服务。用 `compare_to` 指定基准分支。
⚠ 常见坑: 在没有对比目标的新分支上,`rules:changes` 始终返回 true。加一个兜底 `if` 子句或用 `compare_to` 避免不必要的运行。
build-frontend:
script: npm run build
rules:
- changes:
paths:
- frontend/**/*
- package-lock.json
compare_to: 'refs/heads/main'rules:exists仅当仓库中存在指定文件时才运行作业。适合可选构建步骤(例如只有 `Dockerfile` 存在时才运行 Docker 构建)。接受 glob 模式。
docker-build:
script: docker build .
rules:
- exists:
- Dockerfile
- exists:
- 'services/*/Dockerfile'needs为 DAG(有向无环图)流水线指定作业依赖。带 `needs` 的作业在所有列出的作业完成后立即启动,无视阶段顺序。对大型流水线大幅减少总时长。
test-unit:
stage: test
needs: [build]
test-e2e:
stage: test
needs:
- job: build
artifacts: true
- job: seed-db
artifacts: falsedependencies限制下载哪些前置作业的制品。默认情况下每个作业下载前置阶段所有作业的制品。设置 `dependencies: []` 不下载任何制品,或列出特定作业只下载它们的制品。
⚠ 常见坑: 使用 `needs` 时,在每个 need 条目上设置 `artifacts: true/false`,而不是用顶层 `dependencies` 键——两者同时存在时会冲突。
deploy:
stage: deploy
script: ./deploy.sh
dependencies:
- build-app
e2e-tests:
stage: test
script: npm run test:e2e
dependencies: [] # don't download any artifactsonly / except (legacy)**已弃用,推荐用 `rules` 替代。** `only:branches` / `only:refs` 将作业限制在特定分支上。`except` 用于排除。不支持布尔表达式,无法干净地处理 MR 流水线去重。
# Legacy — prefer rules:
deploy:
script: ./deploy.sh
only:
- main
- tags
except:
- /^experiment/.*/Predefined variables (common)GitLab 自动设置数十个 `CI_*` 变量。最常用的:`$CI_COMMIT_BRANCH`(当前分支名)、`$CI_PIPELINE_SOURCE`(push/merge_request_event/schedule/api/trigger)、`$CI_COMMIT_TAG`、`$CI_DEFAULT_BRANCH`、`$CI_COMMIT_SHA`、`$CI_ENVIRONMENT_NAME`。
# Common rule conditions: rules: - if: '$CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH' - if: '$CI_PIPELINE_SOURCE == "schedule"' - if: '$CI_COMMIT_TAG =~ /^v\d+\.\d+\.\d+$/' - if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
rules:variables根据匹配的规则条件设置作业变量。允许单个作业定义在不同环境中表现不同,无需重复定义作业。
build:
script: docker build -t $IMAGE_TAG .
rules:
- if: '$CI_COMMIT_BRANCH == "main"'
variables:
IMAGE_TAG: $CI_REGISTRY_IMAGE:latest
- if: '$CI_COMMIT_TAG'
variables:
IMAGE_TAG: $CI_REGISTRY_IMAGE:$CI_COMMIT_TAG
- variables:
IMAGE_TAG: $CI_REGISTRY_IMAGE:$CI_COMMIT_SHORT_SHAvariables (global)声明对所有作业可用的变量。可在作业级别覆盖。这里设置的变量在 UI 流水线视图中可见(避免放密钥)。密钥用 GitLab CI/CD 设置 → 变量。
variables: DOCKER_DRIVER: overlay2 DOCKER_TLS_CERTDIR: "/certs" NODE_ENV: production FF_USE_FASTZIP: "true" # GitLab feature flag
variables (job-level)只在单个作业范围内有效。用同名变量覆盖全局变量。用 `$VAR` 或 `${VAR}` 语法引用其他变量。支持 `expand` 标志,对含有 `$` 的值禁用变量展开。
test-postgres:
image: postgres:15
variables:
POSTGRES_DB: test_db
POSTGRES_USER: ci
POSTGRES_PASSWORD: ""
CONN_STR: "postgres://${POSTGRES_USER}@postgres/${POSTGRES_DB}"$CI_REGISTRY / Docker image variables`$CI_REGISTRY` 是 GitLab 容器镜像仓库主机名。`$CI_REGISTRY_IMAGE` 是当前项目的完整镜像路径。`$CI_REGISTRY_USER` 和 `$CI_REGISTRY_PASSWORD` 是当前流水线的临时凭证。
build-image:
script:
- docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
- docker build -t $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA .
- docker push $CI_REGISTRY_IMAGE:$CI_COMMIT_SHAdotenv artifact (pass vars between jobs)把 `KEY=VALUE` 对写入文件并声明为 `dotenv` 报告制品。在 `needs` 中引用该作业的下游作业自动接收这些变量作为环境变量。
build:
script:
- VERSION=$(git describe --tags)
- echo "VERSION=$VERSION" > build.env
- echo "IMAGE=$CI_REGISTRY_IMAGE:$VERSION" >> build.env
artifacts:
reports:
dotenv: build.env
deploy:
script:
- echo "Deploying $IMAGE version $VERSION"
needs:
- job: build
artifacts: truevariables:description / value / options为手动触发流水线的流水线级变量添加元数据。`description` 显示提示文字,`value` 设置默认值,`options` 提供下拉菜单。适合参数化发布流水线。
variables:
ENVIRONMENT:
value: "staging"
options:
- "staging"
- "production"
description: "Target environment for deployment"
LOG_LEVEL:
value: "info"
description: "Application log level"$CI_JOB_TOKENGitLab 为每个作业生成的短期令牌。用于向 GitLab API、容器镜像仓库、包仓库和允许 CI 作业令牌访问的其他项目进行身份验证。作业完成后过期。
download-package:
script:
- curl --header "JOB-TOKEN: $CI_JOB_TOKEN"
"https://gitlab.example.com/api/v4/projects/123/packages/generic/myapp/1.0/app.tar.gz"
-o app.tar.gzMasked variables在 GitLab 设置 → CI/CD → 变量中标记为"Masked"的变量会从作业日志中被遮蔽。值必须至少 8 个字符、由可打印 ASCII 组成且不含换行。密钥、密码和令牌用遮蔽变量。
⚠ 常见坑: 遮蔽变量在 GitLab CE/EE 中静态存储时并不加密——它只是从日志中隐藏。静态加密密钥请用 HashiCorp Vault 或密钥管理集成。
# In .gitlab-ci.yml, just reference the variable name:
deploy:
script:
- curl -H "Authorization: Bearer $DEPLOY_TOKEN" https://api.example.com/deploy
# DEPLOY_TOKEN is masked in GitLab Settings → CI/CD → Variables$CI_COMMIT_REF_SLUG分支或标签名的 URL 安全小写版本。斜杠被替换为连字符。适合动态环境名和必须 DNS 兼容的 Docker 标签。
# Branch "feature/my-feature" → "feature-my-feature"
deploy-review:
environment:
name: review/$CI_COMMIT_REF_SLUG
url: https://$CI_COMMIT_REF_SLUG.review.example.com
script:
- kubectl create namespace $CI_COMMIT_REF_SLUG || trueartifacts:paths作业完成时把匹配的文件/目录上传到 GitLab。可在 UI 下载,也可供下游作业使用。用 `artifacts:name` 设置归档文件名,`artifacts:when` 控制在失败时也上传。
build:
script: npm run build
artifacts:
name: "$CI_JOB_NAME-$CI_COMMIT_REF_SLUG"
paths:
- dist/
- coverage/
when: always # upload even if script fails
expire_in: 1 weekartifacts:expire_in设置制品自动删除的时间。接受:`never`、`30 seconds`、`5 minutes`、`1 hour`、`1 day`、`2 weeks`、`1 month`、`1 year`。省略时使用项目级或实例级默认值。
build:
artifacts:
paths: [dist/]
expire_in: 30 days
test:
artifacts:
paths: [coverage/]
expire_in: never # keep test reports foreverartifacts:reports:junit上传 JUnit XML 文件到 GitLab。测试结果显示在 MR 测试摘要面板和流水线 Test 标签页中。失败的测试在 MR 差异视图中内联高亮。
test:
script:
- pytest --junitxml=report.xml
- npm test -- --reporters=junit --outputFile=junit.xml
artifacts:
reports:
junit:
- report.xml
- junit.xmlartifacts:reports:coverage_report上传 Cobertura 或 clover XML 覆盖率报告。GitLab 在 MR 差异中渲染行级覆盖率高亮,显示哪些行被测试覆盖。
test:
script: pytest --cov=myapp --cov-report=xml:coverage.xml
artifacts:
reports:
coverage_report:
coverage_format: cobertura
path: coverage.xmlartifacts:reports:sast / dependency_scanning安全报告制品。SAST、依赖扫描、容器扫描和密钥检测结果显示在 MR 安全标签页和安全仪表板中。由 `Security/SAST.gitlab-ci.yml` 模板自动生成。
include:
- template: Security/SAST.gitlab-ci.yml
- template: Security/Dependency-Scanning.gitlab-ci.yml
# To consume manually:
semgrep-sast:
artifacts:
reports:
sast: gl-sast-report.jsoncache在流水线运行之间存储目录以加速依赖安装。`key` 决定缓存隔离——key 改变时创建新的缓存条目。`policy: pull`(只下载)或 `push`(只上传)跳过不必要的操作。
test:
cache:
key:
files:
- package-lock.json
paths:
- node_modules/
policy: pull-push # default: download, run, uploadcache:key:files从一个或多个文件的哈希创建缓存 key。当文件变化时(例如 `package-lock.json` 更新)缓存自动失效。依赖缓存的最佳实践。
build:
cache:
- key:
files: [package-lock.json]
paths: [node_modules/]
- key:
files: [Gemfile.lock]
paths: [vendor/bundle/]artifacts:exclude在上传的制品归档中排除匹配文件,同时保留更宽泛的 `paths` 模式。适合从发布制品中排除测试固件、sourcemap 或调试二进制。
build:
script: npm run build
artifacts:
paths: [dist/]
exclude:
- dist/**/*.map
- dist/**/*.test.jstags选择哪个注册的 Runner 执行作业。只有拥有列出的所有标签的 Runner 才会被分配。可以给组/项目专属 Runner 打标签(如 `docker`、`kubernetes`、`linux`、`gpu`)进行工作负载路由。
build:
tags:
- docker
- linux
gpu-train:
tags:
- gpu
- cuda-12image为作业指定 Docker 镜像(使用 Docker executor 时)。可以是任何公共或私有镜像仓库的镜像。在安全敏感的流水线中追加 `@sha256:...` 以固定摘要。
test:
image: python:3.12-slim
build-go:
image: golang:1.22-alpine
security-scan:
image:
name: aquasec/trivy:0.50.1
entrypoint: [""]services在作业容器旁边运行额外的 Docker 容器。服务共享网络命名空间,可通过镜像名作为主机名访问。用于数据库、消息队列和其他测试依赖。
test-integration:
image: node:20
services:
- name: postgres:15
alias: db
- name: redis:7-alpine
alias: cache
variables:
POSTGRES_DB: test
POSTGRES_USER: ci
DATABASE_URL: "postgres://ci@db/test"parallel: N创建 N 个相同的并发作业实例。每个实例获得 `$CI_NODE_INDEX`(从 1 开始)和 `$CI_NODE_TOTAL` 来分割工作。用来把大型测试套件分片到多个 Runner 上。
rspec:
script:
- bundle exec rspec --format progress
--only-failures-at-index $((CI_NODE_INDEX - 1))
--shard-count $CI_NODE_TOTAL
parallel: 5parallel:matrix为每种变量组合创建一个作业。GitLab 自动为每种组合生成唯一作业名。矩阵作业并发运行,在流水线图中显示为单独的行。
build:
script: make build TARGET=$TARGET ARCH=$ARCH
parallel:
matrix:
- TARGET: [linux, darwin, windows]
ARCH: [amd64, arm64]
- TARGET: linux
ARCH: [386]runner executor typesExecutor 决定 Runner 如何运行作业。`shell`:直接在宿主机上运行。`docker`:每个作业在新容器中运行。`kubernetes`:在 Kubernetes Pod 中运行。`docker-autoscaler`/`instance`(GitLab 16+):临时虚拟机。`docker` 加 `privileged: true` 启用 Docker-in-Docker(DinD)。
# In /etc/gitlab-runner/config.toml:
[[runners]]
name = "docker-runner"
executor = "docker"
[runners.docker]
image = "alpine:latest"
privileged = true # needed for DinDDOCKER_HOST / dind serviceDocker-in-Docker 模式,用于在 CI 作业内构建 Docker 镜像。使用 `docker:dind` 服务并设置 `DOCKER_HOST` 连接到它。替代方案:用 `kaniko` 或 `buildah` 进行无根镜像构建。
⚠ 常见坑: DinD 需要 Runner 处于 `privileged` 模式,在共享 Runner 上存在重大安全风险。共享/不受信任环境优先用 `kaniko`。
build-image:
image: docker:24
services:
- docker:24-dind
variables:
DOCKER_HOST: tcp://docker:2376
DOCKER_TLS_CERTDIR: "/certs"
script:
- docker build -t myapp .
- docker push myappartifacts:untracked上传所有 git 未跟踪的文件。适合在构建工具生成 GitLab 应该归档的文件的解释型或编译语言项目中捕获构建输出。
build:
script: go build ./...
artifacts:
untracked: true
paths:
- bin/extends继承另一个作业(或以 `.` 开头的隐藏作业)的配置。深度合并父子 YAML。子作业中的列表完全替换父列表(不进行列表合并)。用隐藏作业(`.`)作为抽象基础模板。
.deploy-base:
stage: deploy
before_script:
- apt-get install -y curl
retry:
max: 2
deploy-staging:
extends: .deploy-base
script: ./deploy.sh staging
environment:
name: staging
deploy-prod:
extends: .deploy-base
script: ./deploy.sh prod
when: manualYAML anchors (&, *, <<)在同一文件内复用配置的原生 YAML 锚点。`&anchor-name` 定义锚点,`*anchor-name` 引用它,`<<: *anchor-name` 合并它。与 `extends` 不同,锚点不能跨文件,只在单个 YAML 文档内有效。
.node-setup: &node-setup
image: node:20-alpine
cache:
key:
files: [package-lock.json]
paths: [node_modules/]
test:
<<: *node-setup
script: npm test
lint:
<<: *node-setup
script: npm run lint!referenceGitLab 专有标签,引用另一个作业或映射中的嵌套键。比 YAML 锚点更强大,因为可以访问嵌套结构。用于从多个来源组合复杂的 `script` 或 `rules` 块。
.setup-steps:
script:
- apt-get update -qq
- apt-get install -y curl
.prod-rules:
rules:
- if: '$CI_COMMIT_BRANCH == "main"'
deploy:
script:
- !reference [.setup-steps, script]
- ./deploy.sh
rules: !reference [.prod-rules, rules]include:template (GitLab CI templates)GitLab 内置了数百个 CI 模板。常用模板:`Security/SAST.gitlab-ci.yml`、`Code-Quality.gitlab-ci.yml`、`Docker.gitlab-ci.yml`、`Auto-DevOps.gitlab-ci.yml`。
include:
- template: Security/SAST.gitlab-ci.yml
- template: Security/Secret-Detection.gitlab-ci.yml
- template: Code-Quality.gitlab-ci.yml
# Override a template job:
semgrep-sast:
rules:
- if: '$CI_PIPELINE_SOURCE == "merge_request_event"'include:inputs向 CI 组件或可包含的配置传递命名输入。组件用 `spec:inputs` 声明输入;调用方通过 `inputs:` 提供值。这取代了覆盖模板变量的模式。
spec:
inputs:
stage:
default: test
image:
default: alpine
---
my-job:
stage: $[[ inputs.stage ]]
image: $[[ inputs.image ]]
script: echo "running"Hidden jobs (.job-name)以 `.` 开头的作业不会被 Runner 直接选取。它们作为 `extends` 的抽象基础或锚点定义使用。用来定义共享配置而不创建实际的流水线作业。
.docker-login:
before_script:
- docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
.only-main:
rules:
- if: '$CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH'
build-image:
extends:
- .docker-login
- .only-main
script: docker build -t $CI_REGISTRY_IMAGE .extends: [multiple]一个作业可以继承多个隐藏作业或基础配置。GitLab 从左到右合并,后面的优先。避免深层 YAML 嵌套,同时组合流水线构建块。
.base-node:
image: node:20
cache:
key:
files: [package-lock.json]
paths: [node_modules/]
.mr-only:
rules:
- if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
test-on-mr:
extends:
- .base-node
- .mr-only
script: npm testid_tokens (OIDC)为作业签发 OpenID Connect JWT。用于向云提供商(AWS、GCP、Azure)或 Vault 进行身份验证,无需存储长期密钥。JWT 包含 `sub`(项目路径 + ref)等声明,仅在作业期间有效。
deploy-aws:
id_tokens:
AWS_OIDC_TOKEN:
aud: https://sts.amazonaws.com
script:
- export AWS_ROLE_ARN=arn:aws:iam::123456789012:role/GitLabCI
- aws sts assume-role-with-web-identity
--role-arn $AWS_ROLE_ARN
--web-identity-token $AWS_OIDC_TOKEN
--role-session-name gitlab-ciProtected branches / environments变量可在 GitLab 设置中限定在保护分支和保护环境范围内。只有在这些分支/标签/环境上运行的作业才能访问该变量。用来防止生产密钥泄漏到特性分支流水线。
# In GitLab UI: Settings → CI/CD → Variables # Variable: PROD_DB_URL # Environments: production ← scoped # Protected: ✓ ← only runs on protected branches deploy-prod: environment: production script: ./deploy.sh $PROD_DB_URL # only available here
secrets (Vault integration)用 JWT 身份验证从 HashiCorp Vault 获取密钥。`vault` 关键字需要 GitLab Vault 集成(GitLab Premium 或社区 JWT 认证方式)。密钥作为环境变量注入。
deploy:
secrets:
DATABASE_PASSWORD:
vault: production/db/password@ops
API_KEY:
vault:
engine:
name: kv-v2
path: secrets
path: myapp/prod
field: api_key
script: ./deploy.shenvironment:action: stop定义关闭审查环境的拆除作业。`stop` 作业必须有 `when: manual` 或 `when: always`,并引用相同的环境名。GitLab 可在 MR 合并时自动触发它。
deploy-review:
script: kubectl apply -f k8s/review.yaml
environment:
name: review/$CI_COMMIT_REF_SLUG
on_stop: stop-review
stop-review:
script: kubectl delete namespace $CI_COMMIT_REF_SLUG
environment:
name: review/$CI_COMMIT_REF_SLUG
action: stop
when: manualCI_JOB_TOKEN allowlist默认情况下,`$CI_JOB_TOKEN` 只能向自己的项目进行身份验证。在**设置 → CI/CD → 令牌访问**中授予特定项目访问权限。这防止组内跨项目的令牌滥用。
# Reference another project's API using allowlisted CI_JOB_TOKEN:
fetch-shared-lib:
script:
- curl --header "JOB-TOKEN: $CI_JOB_TOKEN"
"$CI_API_V4_URL/projects/456/repository/files/lib.sh/raw?ref=main"
-o lib.shSAST / Secret Detection templatesGitLab 提供的安全扫描模板。包含它们即可在 MR 和安全仪表板中获得自动漏洞报告。`SAST.gitlab-ci.yml` 分析源代码;`Secret-Detection.gitlab-ci.yml` 在 git 历史中查找凭证。
include: - template: Security/SAST.gitlab-ci.yml - template: Security/Secret-Detection.gitlab-ci.yml - template: Security/Dependency-Scanning.gitlab-ci.yml - template: Security/Container-Scanning.gitlab-ci.yml
interruptible将作业标记为在同一 ref 有新流水线启动时可安全取消。所有作业都设置 `interruptible: true` 时,GitLab 会自动取消推送时过时的进行中流水线,节省 Runner 时间。
default: interruptible: true # applies to all jobs # Override for deploy jobs that must not be interrupted: deploy-prod: interruptible: false script: ./deploy.sh
resource_group防止共享相同资源组名的作业并发运行。当作业启动时,它获取组的排他锁。具有相同组的后续流水线作业排队并按顺序运行。对于序列化部署至关重要。
deploy-prod: script: ./deploy.sh production resource_group: production-deploy environment: production # Only one deploy-prod can run at a time across all pipelines
[skip ci] / [ci skip]在提交信息中包含 `[skip ci]` 或 `[ci skip]` 可阻止创建流水线。适合纯文档提交、版本号提升或不应触发 CI 的自动提交。
git commit -m "chore: update changelog [skip ci]" # Or use the CI_SKIP variable in API triggers: curl --request POST \ --form "token=$CI_JOB_TOKEN" \ --form "ref=main" \ --form "variables[CI_SKIP]=true" \ "https://gitlab.example.com/api/v4/projects/1/trigger/pipeline"
Cache policy: pull对只读取缓存的作业设置 `policy: pull`(例如所有需要相同 `node_modules` 的并行测试作业)。这些作业跳过缓存上传步骤,减少 S3/MinIO 流量和作业时长。
install:
script: npm ci
cache:
key:
files: [package-lock.json]
paths: [node_modules/]
policy: pull-push # download + upload
test:
script: npm test
needs: [install]
cache:
key:
files: [package-lock.json]
paths: [node_modules/]
policy: pull # download only — don't re-uploadSparse checkout / shallow clone用 `GIT_DEPTH` 控制 git 克隆深度,加快在历史记录长的仓库上的作业速度。`GIT_STRATEGY: clone|fetch|none` 控制 Runner 是全量克隆、增量拉取还是完全跳过克隆(用于仅使用制品的作业)。
variables:
GIT_DEPTH: 1 # shallow clone — fastest
GIT_STRATEGY: fetch # reuse existing checkout
deploy:
variables:
GIT_STRATEGY: none # no checkout needed, uses artifacts only
script: ./deploy.shDAG pipeline pattern完整 DAG 流水线:构建扇出到多个并行测试类型,集成测试依赖所有单元测试,最后部署依赖所有测试。不需要阶段——`needs` 驱动执行顺序。
stages: [build, test, deploy] build-app: stage: build script: npm run build test-unit: stage: test needs: [build-app] script: npm test test-lint: stage: test needs: [build-app] script: npm run lint test-e2e: stage: test needs: [test-unit, test-lint] script: npm run test:e2e deploy: stage: deploy needs: [test-e2e] script: ./deploy.sh
rules:if with $CI_COMMIT_MESSAGE在 rules 中用 `$CI_COMMIT_MESSAGE` 基于提交信息关键词创建条件流水线。适合触发扩展测试套件、强制发布构建或从提交中跳过耗时作业。
full-test-suite:
script: npm run test:all
rules:
- if: '$CI_COMMIT_MESSAGE =~ /\[full-tests\]/'
- if: '$CI_COMMIT_BRANCH == "main"'
nightly-security-scan:
script: ./security-scan.sh
rules:
- if: '$CI_PIPELINE_SOURCE == "schedule"'POST /projects/:id/trigger/pipeline用流水线触发令牌通过 API 触发流水线。变量可以作为表单字段传递。在外部系统(GitHub Actions、webhooks、Slack 机器人)中用来程序化启动 GitLab CI 流水线。
curl -X POST \ --form "token=$TRIGGER_TOKEN" \ --form "ref=main" \ --form "variables[DEPLOY_ENV]=production" \ "https://gitlab.example.com/api/v4/projects/123/trigger/pipeline"
GET /projects/:id/pipelines列出项目的流水线。按 `status`(created/waiting_for_resource/preparing/pending/running/success/failed/canceled/skipped/manual/scheduled)、`ref`、`sha`、`username`、`source`、`updated_after` 过滤。
# List recent failed pipelines on main: curl --header "PRIVATE-TOKEN: $GITLAB_TOKEN" \ "https://gitlab.example.com/api/v4/projects/123/pipelines?ref=main&status=failed&per_page=10"
GET /projects/:id/jobs/:job_id/artifacts下载作业的制品归档。用可选的 `artifact_path` 查询参数下载特定文件而不是整个归档。需要身份验证或公开项目。
# Download the entire artifact archive: curl --header "PRIVATE-TOKEN: $TOKEN" \ "https://gitlab.example.com/api/v4/projects/123/jobs/456/artifacts" \ -o artifacts.zip # Download a specific file: curl --header "PRIVATE-TOKEN: $TOKEN" \ "https://gitlab.example.com/api/v4/projects/123/jobs/456/artifacts/dist/app.js" \ -o app.js
GET /projects/:id/pipelines/:pipeline_id/jobs列出流水线的所有作业。适合 CI/CD 报告脚本、仪表板,以及查找后续制品下载的作业 ID。用 `scope` 过滤只获取失败、运行中或手动作业。
# List all failed jobs in a pipeline: curl --header "PRIVATE-TOKEN: $TOKEN" \ "https://gitlab.example.com/api/v4/projects/123/pipelines/789/jobs?scope[]=failed"
POST /projects/:id/pipeline无需触发令牌即可为指定 ref 创建流水线(使用个人/组/项目访问令牌)。支持以 JSON 数组传递变量。对于已认证的脚本优于触发器端点。
curl -X POST \
--header "PRIVATE-TOKEN: $GITLAB_TOKEN" \
--header "Content-Type: application/json" \
--data '{
"ref": "main",
"variables": [
{"key": "DEPLOY_ENV", "value": "production"},
{"key": "IMAGE_TAG", "value": "v1.2.3"}
]
}' \
"https://gitlab.example.com/api/v4/projects/123/pipeline"POST /projects/:id/jobs/:job_id/play通过 API 手动触发 `when: manual` 作业。在发布自动化脚本中用来跨环境推进制品,无需点击 GitLab UI。
# Trigger a manual deploy job: curl -X POST \ --header "PRIVATE-TOKEN: $TOKEN" \ "https://gitlab.example.com/api/v4/projects/123/jobs/456/play"
GET /projects/:id/pipelines/:id (status polling)获取特定流水线的状态。轮询此端点等待触发的流水线完成。检查 `status` 字段:`success`、`failed`、`canceled`、`running`、`pending`。
#!/bin/bash
PIPELINE_ID=$1
while true; do
STATUS=$(curl -s --header "PRIVATE-TOKEN: $TOKEN" \
"https://gitlab.example.com/api/v4/projects/123/pipelines/$PIPELINE_ID" \
| jq -r '.status')
echo "Status: $STATUS"
[[ "$STATUS" =~ ^(success|failed|canceled)$ ]] && break
sleep 10
donePOST /projects/:id/statuses/:sha从外部系统设置提交状态。适合把第三方 CI 工具、代码质量门禁或安全扫描器与 GitLab 提交状态 API 集成,使其结果显示在 MR 中。
curl -X POST \ --header "PRIVATE-TOKEN: $TOKEN" \ --data "state=success&name=external-quality-check&description=All checks passed" \ "https://gitlab.example.com/api/v4/projects/123/statuses/$CI_COMMIT_SHA"
可搜索的 GitLab CI/CD 速查表,80+ 条目按十个分类整理。 流水线结构:`.gitlab-ci.yml` 骨架、`stages`、`workflow:rules`、 `default`、全局 `include`、多项目流水线。 作业配置:`script`、`before_script`、`after_script`、 `allow_failure`、`retry`、`timeout`、`when`、`environment`。 条件规则:`rules:if` 与预定义变量、`rules:changes`、 `rules:exists`、`needs` DAG、合并请求流水线、`only`/`except`。 变量:作业级和全局变量、预定义 `CI_*` 变量、 masked/protected 变量、`dotenv` 制品传值。 制品:制品路径、报告(JUnit、覆盖率、SAST)、 过期时间、缓存 key 与策略。 Runner:`tags` 选择 Runner、Docker 镜像、services、 并行作业、parallel:matrix。 模板:`extends`、`!reference`、`include:template`、 `include:project`、`include:component`、YAML 锚点。 安全:保护变量、保护环境、`id_tokens`(OIDC)、 Masked 变量、Vault/GCP/AWS 密钥。 优化:`interruptible`、`resource_group`、DAG `needs`、 缓存策略、`inherit:variables`、跳过流水线。 HTTP API:触发流水线、列出作业、下载制品、流水线状态。 每条都有双语说明、可直接复制的例子和常见坑提醒。全浏览器运行。
把内容粘贴或拖入工具面板。
点击按钮,在浏览器内本地处理,文件不上传。
一键复制结果或下载到本地。
适合穿插在写代码、查问题、做 Review、上线前的小任务里。
这些入口会把当前任务接到更完整的工具链里。
你发现特性分支上不停触发流水线。打开速查表,拿到带 `$CI_COMMIT_BRANCH == "main"` 的 `workflow:rules` 块,粘贴到 `.gitlab-ci.yml` 顶部,一次提交搞定。速查表还展示了 MR 流水线变体 以及同时在 main 和 MR 事件运行的组合规则。
CI 因为测试串行跑需要 20 分钟。打开速查表,复制带 `NODE_VERSION: [16, 18, 20]` 的 `parallel:matrix` 示例,粘贴到测试 作业里,三个版本同时运行。总时间从 20 分钟降到 7 分钟。
构建作业生成了 Docker 镜像 tag。打开速查表,找到 `dotenv` 制品条目, 复制两步模式(写入 `.env` → `artifacts:reports:dotenv`),部署作业 通过 `needs` 自动拿到 `$IMAGE_TAG`。不用 sed,不用 pipeline trigger。
用 `only: [main]` 而不是 `rules:if: '$CI_COMMIT_BRANCH == "main"'`,`only` 在合并请求流水线上行为不正确,可能导致重复运行。
把 artifacts 和 cache 用错位置,cache 用于跨流水线运行复用依赖;artifacts 用于在同一流水线的作业间传递文件。
用了 DAG 但忘记写 `needs`,没有 `needs`,同一阶段的作业仍然等待前一阶段全部完成,并行优化完全失效。
部署作业用 `when: always`,这会导致测试失败后仍然部署。用 `when: on_success`(默认值)或加 `rules:if` 守卫。
把预定义 `CI_*` 变量当作业变量设置,大多数 GitLab 管理的 `CI_` 前缀变量无法被覆盖,改用自定义名称。
全部在你的浏览器里跑。速查表是内存里的静态数组,搜索框、分类胶囊和复制按钮 都不发任何网络请求。你打的字不会被记录。离网或跳板机上都能用。
做你这行的人, 还会一起用这些。