GitHub Actions 条件执行 #
条件执行允许你根据特定条件控制作业和步骤的执行。本节详细介绍条件表达式的使用。
条件概述 #
什么是条件执行? #
条件执行使用 if 表达式决定是否执行:
- 作业级别条件
- 步骤级别条件
- 基于上下文和状态
基本语法 #
yaml
jobs:
job-name:
if: expression
steps:
- name: step-name
if: expression
作业条件 #
基本条件 #
yaml
jobs:
deploy:
if: github.ref == 'refs/heads/main'
runs-on: ubuntu-latest
steps:
- run: echo "Deploying to production"
多条件组合 #
yaml
jobs:
deploy:
if: github.ref == 'refs/heads/main' && github.event_name == 'push'
runs-on: ubuntu-latest
steps:
- run: echo "Deploying"
基于依赖状态 #
yaml
jobs:
build:
runs-on: ubuntu-latest
steps:
- run: echo "Building"
deploy:
needs: build
if: success()
runs-on: ubuntu-latest
steps:
- run: echo "Deploying"
步骤条件 #
基本条件 #
yaml
steps:
- name: Only on main
if: github.ref == 'refs/heads/main'
run: echo "This is main branch"
基于前序步骤状态 #
yaml
steps:
- name: Step 1
id: step1
run: echo "Step 1"
- name: On success
if: success()
run: echo "Previous steps succeeded"
- name: On failure
if: failure()
run: echo "Previous steps failed"
基于步骤输出 #
yaml
steps:
- id: check
run: echo "should_deploy=true" >> $GITHUB_OUTPUT
- name: Deploy
if: steps.check.outputs.should_deploy == 'true'
run: echo "Deploying"
状态函数 #
success() #
所有前序步骤成功时返回true。
yaml
steps:
- name: On success
if: success()
run: echo "All previous steps succeeded"
failure() #
任一前序步骤失败时返回true。
yaml
steps:
- name: On failure
if: failure()
run: echo "Some previous step failed"
always() #
总是返回true,无论前序步骤状态。
yaml
steps:
- name: Always run
if: always()
run: echo "This always runs"
cancelled() #
工作流被取消时返回true。
yaml
steps:
- name: On cancelled
if: cancelled()
run: echo "Workflow was cancelled"
条件表达式 #
比较运算符 #
yaml
# 等于
if: github.ref == 'refs/heads/main'
# 不等于
if: github.ref != 'refs/heads/develop'
# 包含
if: contains(github.ref, 'release')
# 开头匹配
if: startsWith(github.ref, 'refs/tags/')
# 结尾匹配
if: endsWith(github.ref, '.js')
逻辑运算符 #
yaml
# 与
if: github.ref == 'refs/heads/main' && success()
# 或
if: github.event_name == 'push' || github.event_name == 'pull_request'
# 非
if: !failure()
复杂表达式 #
yaml
jobs:
deploy:
if: |
github.event_name == 'push' &&
github.ref == 'refs/heads/main' &&
!contains(github.event.head_commit.message, '[skip deploy]')
常见使用场景 #
分支条件 #
yaml
jobs:
deploy-production:
if: github.ref == 'refs/heads/main'
runs-on: ubuntu-latest
steps:
- run: echo "Deploying to production"
deploy-staging:
if: github.ref == 'refs/heads/develop'
runs-on: ubuntu-latest
steps:
- run: echo "Deploying to staging"
事件条件 #
yaml
jobs:
on-push:
if: github.event_name == 'push'
runs-on: ubuntu-latest
steps:
- run: echo "Push event"
on-pr:
if: github.event_name == 'pull_request'
runs-on: ubuntu-latest
steps:
- run: echo "Pull request event"
标签条件 #
yaml
jobs:
release:
if: startsWith(github.ref, 'refs/tags/v')
runs-on: ubuntu-latest
steps:
- run: echo "Release from tag"
矩阵条件 #
yaml
jobs:
test:
strategy:
matrix:
node: [16, 18, 20]
runs-on: ubuntu-latest
steps:
- name: Coverage report
if: matrix.node == '20'
run: npm run coverage
手动触发条件 #
yaml
on:
workflow_dispatch:
inputs:
environment:
type: choice
options:
- staging
- production
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- name: Deploy to staging
if: github.event.inputs.environment == 'staging'
run: ./deploy.sh staging
- name: Deploy to production
if: github.event.inputs.environment == 'production'
run: ./deploy.sh production
路径条件 #
yaml
jobs:
build:
if: contains(github.event.head_commit.modified, 'src/')
runs-on: ubuntu-latest
steps:
- run: echo "Source files changed"
作业依赖条件 #
基于依赖状态 #
yaml
jobs:
build:
runs-on: ubuntu-latest
steps:
- run: echo "Building"
test:
needs: build
if: success()
runs-on: ubuntu-latest
steps:
- run: echo "Testing"
deploy:
needs: [build, test]
if: success() && github.ref == 'refs/heads/main'
runs-on: ubuntu-latest
steps:
- run: echo "Deploying"
检查特定依赖状态 #
yaml
jobs:
build:
runs-on: ubuntu-latest
steps:
- run: exit 0
test:
needs: build
runs-on: ubuntu-latest
steps:
- run: exit 1
notify:
needs: [build, test]
if: always()
runs-on: ubuntu-latest
steps:
- name: Build status
run: echo "Build: ${{ needs.build.result }}"
- name: Test status
run: echo "Test: ${{ needs.test.result }}"
- name: Overall status
if: needs.build.result == 'success' && needs.test.result == 'success'
run: echo "All succeeded"
部分依赖成功 #
yaml
jobs:
test-unit:
runs-on: ubuntu-latest
steps:
- run: echo "Unit tests"
test-integration:
runs-on: ubuntu-latest
steps:
- run: exit 1
deploy:
needs: [test-unit, test-integration]
if: needs.test-unit.result == 'success'
runs-on: ubuntu-latest
steps:
- run: echo "Deploying despite integration test failure"
continue-on-error #
步骤级 #
yaml
steps:
- name: Might fail
run: exit 1
continue-on-error: true
- name: Will still run
run: echo "This runs even if previous step failed"
条件continue #
yaml
steps:
- name: Conditional continue
run: exit 1
continue-on-error: ${{ github.ref != 'refs/heads/main' }}
实际应用示例 #
CI/CD流水线 #
yaml
name: CI/CD
on:
push:
branches: [main, develop]
pull_request:
branches: [main]
jobs:
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: npm ci
- run: npm run lint
test:
needs: lint
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: npm ci
- run: npm test
build:
needs: test
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: npm ci
- run: npm run build
deploy-staging:
needs: build
if: github.ref == 'refs/heads/develop'
runs-on: ubuntu-latest
environment: staging
steps:
- run: ./deploy.sh staging
deploy-production:
needs: build
if: github.ref == 'refs/heads/main'
runs-on: ubuntu-latest
environment: production
steps:
- run: ./deploy.sh production
notify:
needs: [deploy-staging, deploy-production]
if: always()
runs-on: ubuntu-latest
steps:
- name: Success notification
if: success()
run: echo "Deployment successful"
- name: Failure notification
if: failure()
run: echo "Deployment failed"
回滚工作流 #
yaml
jobs:
validate:
runs-on: ubuntu-latest
outputs:
can-rollback: ${{ steps.check.outputs.can }}
steps:
- id: check
run: |
if [ "$(./check-version.sh)" == "valid" ]; then
echo "can=true" >> $GITHUB_OUTPUT
else
echo "can=false" >> $GITHUB_OUTPUT
fi
rollback:
needs: validate
if: needs.validate.outputs.can-rollback == 'true'
runs-on: ubuntu-latest
steps:
- run: ./rollback.sh
最佳实践 #
1. 使用有意义的条件 #
yaml
# 推荐
if: github.ref == 'refs/heads/main'
# 不推荐
if: ${{ true }}
2. 组合条件使用多行 #
yaml
if: |
github.event_name == 'push' &&
github.ref == 'refs/heads/main' &&
!contains(github.event.head_commit.message, '[skip ci]')
3. 使用环境变量简化 #
yaml
env:
IS_MAIN: ${{ github.ref == 'refs/heads/main' }}
jobs:
deploy:
if: env.IS_MAIN == 'true'
4. 总是清理资源 #
yaml
jobs:
cleanup:
if: always()
runs-on: ubuntu-latest
steps:
- run: ./cleanup.sh
5. 使用环境保护 #
yaml
jobs:
deploy:
if: github.ref == 'refs/heads/main'
environment: production
下一步学习 #
小结 #
- 使用if表达式控制执行
- 支持作业级和步骤级条件
- 状态函数检查前序步骤状态
- 使用比较和逻辑运算符
- continue-on-error允许失败继续
- 基于上下文和依赖状态判断
- 使用always()确保清理步骤执行
最后更新:2026-03-28