GitHub Actions 作业Job #
作业(Job)是工作流中的执行单元,由一组步骤组成,在同一个运行器上执行。本节深入探讨作业的各个方面。
作业概述 #
什么是作业? #
作业是工作流的基本执行单元,具有以下特点:
- 在同一个运行器上执行
- 共享相同的文件系统
- 可以并行或顺序执行
- 可以设置依赖关系
作业结构 #
yaml
jobs:
job-id: # 作业标识符
name: Job Display Name # 显示名称
runs-on: ubuntu-latest # 运行环境
needs: [other-job] # 依赖关系
if: condition # 条件执行
env: # 环境变量
VAR: value
steps: # 步骤列表
- run: echo "Hello"
运行器配置 #
GitHub托管运行器 #
yaml
jobs:
ubuntu-job:
runs-on: ubuntu-latest
steps:
- run: echo "Running on Ubuntu"
windows-job:
runs-on: windows-latest
steps:
- run: Write-Host "Running on Windows"
macos-job:
runs-on: macos-latest
steps:
- run: echo "Running on macOS"
运行器标签 #
yaml
# 使用特定版本
runs-on: ubuntu-22.04
runs-on: windows-2022
runs-on: macos-13
# 使用多个标签
runs-on: [self-hosted, linux, x64]
# 使用标签表达式
runs-on: ${{ matrix.os }}
自托管运行器 #
yaml
jobs:
self-hosted-job:
runs-on: self-hosted
steps:
- run: echo "Running on self-hosted runner"
# 带标签的自托管运行器
labeled-runner:
runs-on: [self-hosted, linux, gpu]
steps:
- run: echo "Running on GPU runner"
作业依赖 #
基本依赖 #
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..."
依赖图可视化 #
text
┌─────────┐
│ build │
└────┬────┘
│
┌─────────┼─────────┐
│ │ │
▼ ▼ ▼
┌─────────┐ ┌─────────┐ ┌─────────┐
│test-unit│ │test-int │ │ test-e2e│
└────┬────┘ └────┬────┘ └────┬────┘
│ │ │
└─────────┼─────────┘
│
▼
┌─────────┐
│ deploy │
└─────────┘
条件执行 #
基本条件 #
yaml
jobs:
deploy:
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:
build:
if: github.event_name == 'push'
runs-on: ubuntu-latest
steps:
- run: echo "Push event"
pr-check:
if: github.event_name == 'pull_request'
runs-on: ubuntu-latest
steps:
- run: echo "Pull request event"
使用作业状态 #
yaml
jobs:
build:
runs-on: ubuntu-latest
steps:
- run: exit 0
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"
notify-always:
needs: build
if: always()
runs-on: ubuntu-latest
steps:
- run: echo "Build finished"
矩阵构建 #
基本矩阵 #
yaml
jobs:
test:
strategy:
matrix:
node: [16, 18, 20]
runs-on: ubuntu-latest
steps:
- uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node }}
- run: node --version
多维度矩阵 #
yaml
jobs:
test:
strategy:
matrix:
node: [16, 18, 20]
os: [ubuntu-latest, windows-latest, macos-latest]
runs-on: ${{ matrix.os }}
steps:
- uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node }}
- run: node --version
包含配置 #
yaml
jobs:
test:
strategy:
matrix:
node: [16, 18, 20]
os: [ubuntu-latest]
include:
- node: 20
os: windows-latest
experimental: true
- node: 20
os: macos-latest
coverage: true
runs-on: ${{ matrix.os }}
steps:
- run: echo "Node ${{ matrix.node }} on ${{ matrix.os }}"
排除配置 #
yaml
jobs:
test:
strategy:
matrix:
node: [16, 18, 20]
os: [ubuntu-latest, windows-latest]
exclude:
- node: 16
os: windows-latest
runs-on: ${{ matrix.os }}
steps:
- uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node }}
矩阵策略选项 #
yaml
jobs:
test:
strategy:
matrix:
node: [16, 18, 20]
fail-fast: false # 一个失败不取消其他
max-parallel: 4 # 最大并行数
runs-on: ubuntu-latest
steps:
- run: echo "Testing"
作业输出 #
定义输出 #
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:
- run: echo "Deploying version ${{ needs.build.outputs.version }}"
环境配置 #
使用环境 #
yaml
jobs:
deploy:
runs-on: ubuntu-latest
environment:
name: production
url: https://example.com
steps:
- run: echo "Deploying to production"
环境变量 #
yaml
jobs:
build:
runs-on: ubuntu-latest
env:
CI: true
NODE_ENV: test
steps:
- run: echo $CI
使用环境Secrets #
yaml
jobs:
deploy:
runs-on: ubuntu-latest
environment: production
steps:
- run: |
echo "Deploying with token"
env:
TOKEN: ${{ secrets.DEPLOY_TOKEN }}
超时和重试 #
作业超时 #
yaml
jobs:
build:
runs-on: ubuntu-latest
timeout-minutes: 30
steps:
- run: echo "This job will timeout after 30 minutes"
步骤超时 #
yaml
jobs:
build:
runs-on: ubuntu-latest
steps:
- run: echo "This step will timeout after 5 minutes"
timeout-minutes: 5
容器支持 #
在容器中运行 #
yaml
jobs:
docker-job:
runs-on: ubuntu-latest
container:
image: node:20
options: --cpus 1
env:
NODE_ENV: test
volumes:
- my_volume:/volume_mount
steps:
- run: node --version
服务容器 #
yaml
jobs:
test:
runs-on: ubuntu-latest
services:
postgres:
image: postgres:15
env:
POSTGRES_USER: test
POSTGRES_PASSWORD: test
POSTGRES_DB: test
ports:
- 5432:5432
options: >-
--health-cmd pg_isready
--health-interval 10s
--health-timeout 5s
--health-retries 5
redis:
image: redis:7
ports:
- 6379:6379
options: >-
--health-cmd "redis-cli ping"
--health-interval 10s
--health-timeout 5s
--health-retries 5
steps:
- name: Test with services
run: |
psql -h localhost -U test -d test -c "SELECT 1"
redis-cli ping
env:
PGPASSWORD: test
作业示例 #
完整CI作业 #
yaml
jobs:
lint:
name: Lint
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm'
- run: npm ci
- run: npm run lint
test:
name: Test (Node ${{ matrix.node }})
needs: lint
runs-on: ubuntu-latest
strategy:
matrix:
node: [16, 18, 20]
fail-fast: false
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node }}
cache: 'npm'
- run: npm ci
- run: npm test -- --coverage
- uses: actions/upload-artifact@v4
if: matrix.node == '20'
with:
name: coverage
path: coverage/
build:
name: Build
needs: test
runs-on: ubuntu-latest
outputs:
artifact: dist
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm'
- run: npm ci
- run: npm run build
- uses: actions/upload-artifact@v4
with:
name: dist
path: dist/
带服务容器的测试 #
yaml
jobs:
integration-test:
runs-on: ubuntu-latest
services:
postgres:
image: postgres:15
env:
POSTGRES_USER: test
POSTGRES_PASSWORD: test
POSTGRES_DB: testdb
ports:
- 5432:5432
options: --health-cmd pg_isready --health-interval 10s --health-timeout 5s --health-retries 5
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm'
- run: npm ci
- run: npm run test:integration
env:
DATABASE_URL: postgresql://test:test@localhost:5432/testdb
最佳实践 #
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]
runs-on: ubuntu-latest
2. 使用矩阵优化测试 #
yaml
strategy:
matrix:
include:
- node: 20
os: ubuntu-latest
- node: 18
os: ubuntu-latest
3. 设置合理的超时 #
yaml
jobs:
build:
timeout-minutes: 30
4. 使用环境保护敏感操作 #
yaml
jobs:
deploy:
environment: production
下一步学习 #
小结 #
- 作业是工作流的执行单元
- 可以设置作业依赖关系
- 支持矩阵构建进行多配置测试
- 可以使用服务容器
- 支持容器化运行
- 可以定义和使用作业输出
- 使用环境保护敏感操作
最后更新:2026-03-28