GitHub Actions 作业依赖 #
作业依赖是控制工作流执行顺序的核心机制。本节详细介绍如何配置和使用作业依赖。
依赖概述 #
什么是作业依赖? #
作业依赖定义了作业之间的执行顺序:
- 被依赖的作业先执行
- 依赖的作业等待前置作业完成
- 可以设置多个依赖
依赖关系图 #
text
┌─────────┐
│ build │
└────┬────┘
│
├─────────────────┐
│ │
▼ ▼
┌─────────┐ ┌─────────┐
│ test-1 │ │ test-2 │
└────┬────┘ └────┬────┘
│ │
└────────┬────────┘
│
▼
┌─────────┐
│ deploy │
└─────────┘
基本依赖 #
单一依赖 #
yaml
jobs:
build:
runs-on: ubuntu-latest
steps:
- run: echo "Building..."
test:
needs: build
runs-on: ubuntu-latest
steps:
- run: echo "Testing..."
deploy:
needs: test
runs-on: ubuntu-latest
steps:
- run: echo "Deploying..."
多个依赖 #
yaml
jobs:
build:
runs-on: ubuntu-latest
steps:
- run: echo "Building..."
test-unit:
needs: build
runs-on: ubuntu-latest
steps:
- run: echo "Unit testing..."
test-integration:
needs: build
runs-on: ubuntu-latest
steps:
- run: echo "Integration testing..."
test-e2e:
needs: build
runs-on: ubuntu-latest
steps:
- run: echo "E2E testing..."
deploy:
needs: [test-unit, test-integration, test-e2e]
runs-on: ubuntu-latest
steps:
- run: echo "Deploying..."
依赖状态 #
查看依赖状态 #
yaml
jobs:
build:
runs-on: ubuntu-latest
steps:
- run: echo "Building..."
deploy:
needs: build
runs-on: ubuntu-latest
steps:
- name: Check dependency status
run: |
echo "Build result: ${{ needs.build.result }}"
echo "Build output: ${{ needs.build.outputs.version }}"
状态值 #
| 状态 | 描述 |
|---|---|
success |
成功完成 |
failure |
执行失败 |
cancelled |
被取消 |
skipped |
被跳过 |
条件执行 #
yaml
jobs:
build:
runs-on: ubuntu-latest
steps:
- run: echo "Building..."
notify-success:
needs: build
if: success()
runs-on: ubuntu-latest
steps:
- run: echo "Build succeeded"
notify-failure:
needs: build
if: failure()
runs-on: ubuntu-latest
steps:
- run: echo "Build failed"
作业输出传递 #
定义输出 #
yaml
jobs:
build:
outputs:
version: ${{ steps.version.outputs.value }}
artifact: ${{ steps.artifact.outputs.path }}
runs-on: ubuntu-latest
steps:
- id: version
run: echo "value=1.0.0" >> $GITHUB_OUTPUT
- id: artifact
run: echo "path=dist/" >> $GITHUB_OUTPUT
使用输出 #
yaml
jobs:
build:
outputs:
version: ${{ steps.version.outputs.value }}
steps:
- id: version
run: echo "value=1.0.0" >> $GITHUB_OUTPUT
deploy:
needs: build
runs-on: ubuntu-latest
steps:
- name: Use build output
run: |
echo "Deploying version ${{ needs.build.outputs.version }}"
多作业输出 #
yaml
jobs:
setup:
outputs:
matrix: ${{ steps.set-matrix.outputs.matrix }}
steps:
- id: set-matrix
run: |
echo 'matrix={"include":[{"node":"16"},{"node":"18"},{"node":"20"}]}' >> $GITHUB_OUTPUT
test:
needs: setup
strategy:
matrix: ${{ fromJSON(needs.setup.outputs.matrix) }}
runs-on: ubuntu-latest
steps:
- run: echo "Testing Node ${{ matrix.node }}"
复杂依赖示例 #
CI/CD流水线 #
yaml
name: CI/CD Pipeline
on:
push:
branches: [main]
pull_request:
branches: [main]
jobs:
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: npm ci
- run: npm run lint
type-check:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: npm ci
- run: npm run type-check
test-unit:
needs: [lint, type-check]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: npm ci
- run: npm run test:unit
test-integration:
needs: [lint, type-check]
runs-on: ubuntu-latest
services:
postgres:
image: postgres:15
env:
POSTGRES_PASSWORD: postgres
ports:
- 5432:5432
steps:
- uses: actions/checkout@v4
- run: npm ci
- run: npm run test:integration
test-e2e:
needs: [lint, type-check]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: npm ci
- run: npm run test:e2e
build:
needs: [test-unit, test-integration, test-e2e]
runs-on: ubuntu-latest
outputs:
version: ${{ steps.version.outputs.value }}
steps:
- uses: actions/checkout@v4
- run: npm ci
- run: npm run build
- id: version
run: echo "value=$(node -p "require('./package.json').version")" >> $GITHUB_OUTPUT
- uses: actions/upload-artifact@v4
with:
name: dist
path: dist/
deploy-staging:
needs: build
if: github.ref == 'refs/heads/develop'
runs-on: ubuntu-latest
environment: staging
steps:
- uses: actions/download-artifact@v4
with:
name: dist
- run: ./deploy.sh staging
deploy-production:
needs: build
if: github.ref == 'refs/heads/main'
runs-on: ubuntu-latest
environment: production
steps:
- uses: actions/download-artifact@v4
with:
name: dist
- run: ./deploy.sh production
notify:
needs: [deploy-staging, deploy-production]
if: always()
runs-on: ubuntu-latest
steps:
- name: Notify on success
if: success()
run: echo "Deployment successful"
- name: Notify on failure
if: failure()
run: echo "Deployment failed"
微服务构建 #
yaml
jobs:
detect-changes:
outputs:
service-a: ${{ steps.filter.outputs.service-a }}
service-b: ${{ steps.filter.outputs.service-b }}
service-c: ${{ steps.filter.outputs.service-c }}
steps:
- uses: dorny/paths-filter@v3
id: filter
with:
filters: |
service-a:
- 'services/a/**'
service-b:
- 'services/b/**'
service-c:
- 'services/c/**'
build-service-a:
needs: detect-changes
if: needs.detect-changes.outputs.service-a == 'true'
runs-on: ubuntu-latest
steps:
- run: echo "Building service A"
build-service-b:
needs: detect-changes
if: needs.detect-changes.outputs.service-b == 'true'
runs-on: ubuntu-latest
steps:
- run: echo "Building service B"
build-service-c:
needs: detect-changes
if: needs.detect-changes.outputs.service-c == 'true'
runs-on: ubuntu-latest
steps:
- run: echo "Building service C"
deploy:
needs: [build-service-a, build-service-b, build-service-c]
if: always() && (needs.build-service-a.result == 'success' || needs.build-service-b.result == 'success' || needs.build-service-c.result == 'success')
runs-on: ubuntu-latest
steps:
- run: echo "Deploying changed services"
依赖图可视化 #
简单依赖 #
text
build → test → deploy
并行依赖 #
text
┌──→ test-unit ──┐
build ──┼──→ test-int ───┼──→ deploy
└──→ test-e2e ───┘
复杂依赖 #
text
┌──→ lint ────────┐
│ │
├──→ type-check ───┤
│ │
setup ────────┼──→ test-unit ────┼──→ build ──→ deploy
│ │
├──→ test-int ─────┤
│ │
└──→ test-e2e ─────┘
最佳实践 #
1. 合理设置依赖 #
yaml
# 并行执行独立任务
jobs:
lint:
runs-on: ubuntu-latest
type-check:
runs-on: ubuntu-latest
test:
runs-on: ubuntu-latest
# 依赖多个任务
build:
needs: [lint, type-check, test]
2. 使用输出传递数据 #
yaml
jobs:
build:
outputs:
version: ${{ steps.version.outputs.value }}
3. 条件执行 #
yaml
jobs:
deploy:
needs: build
if: success() && github.ref == 'refs/heads/main'
4. 处理失败情况 #
yaml
jobs:
cleanup:
needs: [build, test, deploy]
if: always()
5. 使用环境保护 #
yaml
jobs:
deploy:
needs: build
environment: production
下一步学习 #
小结 #
- 使用needs设置作业依赖
- 支持单一和多个依赖
- 可以访问依赖作业的状态和输出
- 使用条件控制执行流程
- 合理设置依赖优化执行效率
- 使用环境保护敏感操作
最后更新:2026-03-28