跳到主要内容

GitHub Actions

核心概念

概念说明
Workflow一条自动化流水线,存放在 .github/workflows/
Event触发 Workflow 的事件(push、pull_request、schedule 等)
JobWorkflow 中的一个任务,默认并行执行
StepJob 中的一个步骤(运行命令或使用 Action)
Action可复用的步骤(Marketplace 中有大量社区 Action)
Runner执行 Job 的服务器(GitHub-hosted 或 self-hosted)

完整示例

.github/workflows/ci.yml
name: CI/CD Pipeline

# 触发条件
on:
push:
branches: [main, develop]
pull_request:
branches: [main]
# 定时触发
schedule:
- cron: '0 2 * * 1' # 每周一凌晨 2 点

# 环境变量
env:
REGISTRY: ghcr.io
IMAGE_NAME: ${{ github.repository }}

jobs:
# ===== 代码检查 =====
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- uses: actions/setup-node@v4
with:
node-version: 20
cache: 'pnpm'

- run: pnpm install --frozen-lockfile
- run: pnpm lint
- run: pnpm type-check

# ===== 测试 =====
test:
runs-on: ubuntu-latest
needs: lint
strategy:
# 矩阵构建:多版本并行测试
matrix:
node-version: [18, 20, 22]
steps:
- uses: actions/checkout@v4

- uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node-version }}
cache: 'pnpm'

- run: pnpm install --frozen-lockfile
- run: pnpm test -- --coverage

# 上传测试覆盖率
- uses: codecov/codecov-action@v4
if: matrix.node-version == 20

# ===== 构建并推送镜像 =====
build:
runs-on: ubuntu-latest
needs: test
# 仅 main 分支触发
if: github.ref == 'refs/heads/main'
permissions:
contents: read
packages: write
outputs:
image-tag: ${{ steps.meta.outputs.tags }}
steps:
- uses: actions/checkout@v4

# Docker Buildx
- uses: docker/setup-buildx-action@v3

# 登录 GitHub Container Registry
- uses: docker/login-action@v3
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}

# 生成镜像标签
- id: meta
uses: docker/metadata-action@v5
with:
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
tags: |
type=sha,prefix=
type=raw,value=latest

# 构建并推送
- uses: docker/build-push-action@v5
with:
context: .
push: true
tags: ${{ steps.meta.outputs.tags }}
cache-from: type=gha
cache-to: type=gha,mode=max

# ===== 部署 =====
deploy:
runs-on: ubuntu-latest
needs: build
environment: production # 需要审批
steps:
- uses: actions/checkout@v4

# 部署到 K8s
- uses: azure/k8s-set-context@v4
with:
kubeconfig: ${{ secrets.KUBE_CONFIG }}

- run: |
kubectl set image deployment/myapp \
myapp=${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ github.sha }} \
-n production
kubectl rollout status deployment/myapp -n production --timeout=300s

常用技巧

缓存依赖

- uses: actions/cache@v4
with:
path: |
~/.pnpm-store
node_modules
key: ${{ runner.os }}-pnpm-${{ hashFiles('pnpm-lock.yaml') }}
restore-keys: |
${{ runner.os }}-pnpm-

条件执行

steps:
# 仅 PR 时运行
- if: github.event_name == 'pull_request'
run: echo "This is a PR"

# 仅文件变更时运行
- uses: dorny/paths-filter@v3
id: changes
with:
filters: |
backend:
- 'src/server/**'
frontend:
- 'src/client/**'

- if: steps.changes.outputs.backend == 'true'
run: pnpm test:backend

Secrets 管理

# 在 Settings → Secrets and variables → Actions 中配置
steps:
- run: |
echo "Deploying to ${{ vars.DEPLOY_ENV }}"
env:
API_KEY: ${{ secrets.API_KEY }} # 密钥
DB_URL: ${{ secrets.DATABASE_URL }}

可复用 Workflow

.github/workflows/reusable-deploy.yml
on:
workflow_call:
inputs:
environment:
required: true
type: string
secrets:
KUBE_CONFIG:
required: true

jobs:
deploy:
runs-on: ubuntu-latest
environment: ${{ inputs.environment }}
steps:
- run: echo "Deploying to ${{ inputs.environment }}"
调用方
jobs:
deploy-staging:
uses: ./.github/workflows/reusable-deploy.yml
with:
environment: staging
secrets:
KUBE_CONFIG: ${{ secrets.KUBE_CONFIG_STAGING }}

常见面试问题

Q1: GitHub Actions 的触发方式有哪些?

答案

  • push / pull_request:代码事件(可过滤分支和路径)
  • schedule:定时触发(cron 语法)
  • workflow_dispatch:手动触发(可带参数)
  • workflow_call:被其他 Workflow 调用
  • release:发布事件
  • repository_dispatch:外部 API 触发

Q2: 如何优化 CI 构建速度?

答案

  1. 缓存依赖actions/cache 缓存 node_modules / Maven 仓库
  2. 并行 Job:独立的 lint / test / build 并行运行
  3. 路径过滤paths-filter 只运行受影响的测试
  4. Docker 层缓存:使用 cache-from: type=gha
  5. Self-hosted Runner:自建 Runner 避免队列等待
  6. 矩阵构建:利用多 Runner 并行测试不同版本

相关链接