条件与规则 #
一、条件执行概述 #
GitLab CI提供了两种条件执行机制:only/except(旧语法)和rules(新语法)。
text
┌─────────────────────────────────────────────────────────────┐
│ 条件执行机制 │
├─────────────────────────────────────────────────────────────┤
│ │
│ only/except (旧语法) rules (新语法) │
│ ┌─────────────────┐ ┌─────────────────┐ │
│ │ • 简单条件 │ │ • 复杂条件 │ │
│ │ • 单一判断 │ │ • 多条件组合 │ │
│ │ • 不够灵活 │ │ • if/when/exists │ │
│ │ │ │ • 变量设置 │ │
│ │ • 推荐迁移 │ │ • 推荐使用 │ │
│ └─────────────────┘ └─────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────┘
二、only/except语法 #
基本用法 #
yaml
job_name:
script: echo "Hello"
only:
- main
分支条件 #
yaml
deploy_production:
script: echo "Deploying..."
only:
- main
- release
排除分支 #
yaml
test:
script: npm test
except:
- main
标签条件 #
yaml
release:
script: echo "Creating release..."
only:
- tags
合并请求 #
yaml
test:
script: npm test
only:
- merge_requests
触发源 #
yaml
deploy:
script: echo "Deploying..."
only:
variables:
- $CI_PIPELINE_SOURCE == "schedule"
正则表达式 #
yaml
deploy:
script: echo "Deploying..."
only:
- /^release-.*$/
组合条件 #
yaml
deploy:
script: echo "Deploying..."
only:
refs:
- main
variables:
- $DEPLOY == "true"
changes:
- Dockerfile
only/except关键字 #
| 关键字 | 说明 |
|---|---|
refs |
分支或标签 |
variables |
变量条件 |
changes |
文件变更 |
kubernetes |
Kubernetes服务 |
三、rules语法 #
基本用法 #
yaml
job_name:
script: echo "Hello"
rules:
- if: $CI_COMMIT_BRANCH == "main"
if条件 #
yaml
deploy_production:
script: echo "Deploying..."
rules:
- if: $CI_COMMIT_BRANCH == "main"
when: manual
- when: never
多条件 #
yaml
deploy:
script: echo "Deploying..."
rules:
- if: $CI_COMMIT_BRANCH == "main"
- if: $CI_COMMIT_BRANCH == "develop"
- when: never
when关键字 #
yaml
job_name:
script: echo "Hello"
rules:
- if: $CI_COMMIT_BRANCH == "main"
when: always
- if: $CI_COMMIT_BRANCH == "develop"
when: manual
- when: never
| 值 | 说明 |
|---|---|
always |
总是执行 |
never |
从不执行 |
on_success |
前面Job成功时执行(默认) |
on_failure |
前面Job失败时执行 |
manual |
手动执行 |
delayed |
延迟执行 |
exists条件 #
检查文件是否存在:
yaml
docker_build:
script: docker build .
rules:
- exists:
- Dockerfile
changes条件 #
检查文件是否变更:
yaml
build:
script: npm run build
rules:
- changes:
- package.json
- package-lock.json
- src/**/*
variables条件 #
设置变量:
yaml
deploy:
script: echo "Deploying to $DEPLOY_ENV"
rules:
- if: $CI_COMMIT_BRANCH == "main"
variables:
DEPLOY_ENV: "production"
- if: $CI_COMMIT_BRANCH == "develop"
variables:
DEPLOY_ENV: "staging"
allow_failure #
yaml
lint:
script: npm run lint
rules:
- if: $CI_COMMIT_BRANCH == "main"
allow_failure: false
- allow_failure: true
四、复杂条件组合 #
AND条件 #
yaml
deploy:
script: echo "Deploying..."
rules:
- if: $CI_COMMIT_BRANCH == "main" && $DEPLOY == "true"
OR条件 #
yaml
deploy:
script: echo "Deploying..."
rules:
- if: $CI_COMMIT_BRANCH == "main" || $CI_COMMIT_BRANCH == "develop"
正则匹配 #
yaml
deploy:
script: echo "Deploying..."
rules:
- if: $CI_COMMIT_BRANCH =~ /^release-.*$/
正则不匹配 #
yaml
test:
script: npm test
rules:
- if: $CI_COMMIT_BRANCH !~ /^docs-.*$/
组合示例 #
yaml
deploy:
script: echo "Deploying..."
rules:
- if: $CI_COMMIT_BRANCH == "main"
when: manual
allow_failure: false
variables:
DEPLOY_ENV: production
- if: $CI_COMMIT_BRANCH == "develop"
when: always
variables:
DEPLOY_ENV: staging
- when: never
五、workflow规则 #
控制Pipeline创建 #
yaml
workflow:
rules:
- if: $CI_COMMIT_BRANCH == "main"
when: always
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
when: always
- when: never
避免重复Pipeline #
yaml
workflow:
rules:
- if: $CI_COMMIT_BRANCH && $CI_OPEN_MERGE_REQUESTS && $CI_PIPELINE_SOURCE == "push"
when: never
- when: always
设置Pipeline变量 #
yaml
workflow:
rules:
- if: $CI_COMMIT_BRANCH == "main"
variables:
DEPLOY_ENV: production
- if: $CI_COMMIT_BRANCH == "develop"
variables:
DEPLOY_ENV: staging
六、only/except迁移到rules #
简单迁移 #
yaml
deploy:
script: echo "Deploying..."
only:
- main
迁移后:
yaml
deploy:
script: echo "Deploying..."
rules:
- if: $CI_COMMIT_BRANCH == "main"
复杂迁移 #
yaml
deploy:
script: echo "Deploying..."
only:
refs:
- main
variables:
- $DEPLOY == "true"
changes:
- Dockerfile
迁移后:
yaml
deploy:
script: echo "Deploying..."
rules:
- if: $CI_COMMIT_BRANCH == "main" && $DEPLOY == "true"
changes:
- Dockerfile
except迁移 #
yaml
test:
script: npm test
except:
- main
迁移后:
yaml
test:
script: npm test
rules:
- if: $CI_COMMIT_BRANCH != "main"
七、条件表达式 #
比较运算符 #
| 运算符 | 说明 |
|---|---|
== |
等于 |
!= |
不等于 |
=~ |
正则匹配 |
!~ |
正则不匹配 |
逻辑运算符 #
| 运算符 | 说明 |
|---|---|
&& |
与 |
| ` | |
! |
非 |
括号分组 #
yaml
deploy:
script: echo "Deploying..."
rules:
- if: ($CI_COMMIT_BRANCH == "main" || $CI_COMMIT_BRANCH == "develop") && $DEPLOY == "true"
八、最佳实践 #
1. 使用rules替代only/except #
yaml
deploy:
rules:
- if: $CI_COMMIT_BRANCH == "main"
script:
- echo "Deploying..."
2. 设置默认规则 #
yaml
default:
rules:
- if: $CI_COMMIT_BRANCH == "main"
when: always
- when: never
3. 使用变量简化条件 #
yaml
variables:
PRODUCTION_BRANCH: "main"
STAGING_BRANCH: "develop"
deploy_production:
rules:
- if: $CI_COMMIT_BRANCH == $PRODUCTION_BRANCH
script:
- echo "Deploying..."
4. 组合使用多种条件 #
yaml
deploy:
rules:
- if: $CI_COMMIT_BRANCH == "main"
exists:
- Dockerfile
changes:
- src/**/*
when: manual
script:
- echo "Deploying..."
5. 使用workflow统一控制 #
yaml
workflow:
rules:
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
- if: $CI_COMMIT_BRANCH == "main"
- if: $CI_COMMIT_BRANCH == "develop"
- when: never
九、常见场景 #
1. MR流水线 #
yaml
test:
rules:
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
script:
- npm test
2. 定时任务 #
yaml
nightly_build:
rules:
- if: $CI_PIPELINE_SOURCE == "schedule"
script:
- npm run build
3. 手动部署 #
yaml
deploy_production:
rules:
- if: $CI_COMMIT_BRANCH == "main"
when: manual
script:
- echo "Deploying..."
4. 条件部署 #
yaml
deploy:
rules:
- if: $CI_COMMIT_BRANCH == "main" && $CI_COMMIT_MESSAGE =~ /\[deploy\]/
script:
- echo "Deploying..."
5. 文件变更触发 #
yaml
docker_build:
rules:
- changes:
- Dockerfile
- docker-compose.yml
script:
- docker build .
十、完整示例 #
多环境部署 #
yaml
stages:
- test
- deploy
workflow:
rules:
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
- if: $CI_COMMIT_BRANCH == "main"
- if: $CI_COMMIT_BRANCH == "develop"
- when: never
test:
stage: test
rules:
- when: always
script:
- npm test
deploy_staging:
stage: deploy
environment:
name: staging
url: https://staging.example.com
rules:
- if: $CI_COMMIT_BRANCH == "develop"
when: always
script:
- echo "Deploying to staging..."
deploy_production:
stage: deploy
environment:
name: production
url: https://example.com
rules:
- if: $CI_COMMIT_BRANCH == "main"
when: manual
allow_failure: false
script:
- echo "Deploying to production..."
cleanup:
stage: deploy
rules:
- if: $CI_COMMIT_BRANCH == "develop"
when: manual
script:
- echo "Cleaning up..."
下一步 #
现在你已经掌握了条件与规则的使用,接下来让我们学习 Runner基础!
最后更新:2026-03-28