GitHub Actions是GitHub原生的CI/CD平台,用YAML定义工作流,与代码仓库深度集成。它将持续集成从"配置Jenkins"变成了"写YAML文件",大幅降低了CI/CD门槛。
事件触发 工作流 运行器
┌──────┐ ┌──────────┐ ┌──────────┐
│ push │ │ Workflow │ │ Runner │
│ PR │──触发────▶│ .yaml │──调度───▶│ (VM/容器)│
│定时 │ │ │ │ │
│手动 │ │ Job1 │──▶ Step1 │ npm ci │
└──────┘ │ Job2 │──▶ Step2 │ npm test │
│ Job3 │──▶ Step3 │ docker │
└──────────┘ └──────────┘
│
┌────┴────┐
│ Actions │
│ Market │
│ place │
│ (复用) │
└─────────┘
.github/workflows/中# .github/workflows/ci.yml
name: CI Pipeline
on:
push:
branches: [main, develop]
pull_request:
branches: [main]
env:
NODE_VERSION: '20'
REGISTRY: ghcr.io
IMAGE_NAME: ${{ github.repository }}
jobs:
test:
runs-on: ubuntu-latest
strategy:
matrix:
node-version: [18, 20, 22]
steps:
- uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node-version }}
cache: 'npm'
- name: Install dependencies
run: npm ci
- name: Lint
run: npm run lint
- name: Unit tests
run: npm test -- --coverage
- name: Upload coverage
uses: codecov/codecov-action@v4
with:
token: ${{ secrets.CODECOV_TOKEN }}
build:
needs: test
runs-on: ubuntu-latest
outputs:
image-tag: ${{ steps.meta.outputs.tags }}
steps:
- uses: actions/checkout@v4
- name: Login to Registry
uses: docker/login-action@v3
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Build and Push
uses: docker/build-push-action@v5
with:
push: true
tags: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ github.sha }}
# .github/workflows/cd.yml
name: CD Pipeline
on:
workflow_run:
workflows: ["CI Pipeline"]
types: [completed]
branches: [main]
jobs:
deploy-staging:
if: ${{ github.event.workflow_run.conclusion == 'success' }}
runs-on: ubuntu-latest
environment: staging
steps:
- uses: actions/checkout@v4
- name: Deploy to Staging
run: |
kubectl set image deployment/app app=${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ github.sha }} -n staging
kubectl rollout status deployment/app -n staging --timeout=300s
- name: Smoke Test
run: |
sleep 30
curl -f https://staging.example.com/health || exit 1
deploy-production:
needs: deploy-staging
runs-on: ubuntu-latest
environment: production
steps:
- name: Deploy to Production
run: |
kubectl set image deployment/app app=${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ github.sha }} -n production
- name: Canary Check
run: |
# 检查错误率是否上升
ERROR_RATE=$(curl -s prometheus:9090/api/v1/query | jq '.data.result[0].value[1]')
if (( $(echo "$ERROR_RATE > 0.01" | bc -l) )); then
echo "❌ Error rate too high, rolling back"
kubectl rollout undo deployment/app -n production
exit 1
fi
# actions/deploy-slx/action.yml
name: 'Deploy SLX'
description: 'Deploy service to Kubernetes with canary'
inputs:
environment:
description: 'Target environment'
required: true
image-tag:
description: 'Container image tag'
required: true
canary-weight:
description: 'Canary traffic percentage'
default: '10'
outputs:
deploy-url:
description: 'Deployed service URL'
runs:
using: 'composite'
steps:
- name: Validate inputs
shell: bash
run: |
[[ "${{ inputs.environment }}" =~ ^(staging|production)$ ]] || exit 1
- name: Deploy
shell: bash
run: |
echo "Deploying ${{ inputs.image-tag }} to ${{ inputs.environment }}"
kubectl apply -f k8s/${{ inputs.environment }}/
- name: Wait for rollout
shell: bash
run: |
kubectl rollout status deployment/app -n ${{ inputs.environment }} --timeout=300s
开发者 GitHub Runners 部署
┌──────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐
│ git │ │ Repo │ │ Runner 1 │ │ │
│ push │─────▶│ .github/ │──调度──▶│ Lint+Test│ │ Staging │
└──────┘ │ workflows│ └──────────┘ │ K8s │
└────┬─────┘ ┌──────────┐ │ │
│ ──调度──▶│ Runner 2 │──部署──▶│ │
│ │ Build │ └──────────┘
│ └──────────┘
│ ┌──────────┐ ┌──────────┐
│ ──调度──▶│ Runner 3 │──部署──▶│ Prod K8s │
│ │ Deploy │ │ │
│ └──────────┘ └──────────┘
│
│ 通知
▼
┌──────────┐
│ Slack/ │
│ 钉钉 │
└──────────┘
# 常见原因:
# 1. YAML语法错误 → 用actionlint检查
# 2. 分支过滤器不匹配
# 3. 使用了secrets但fork PR无权限
# 4. 工作流文件在错误的分支
# 调试方法:
# 1. 查看Actions标签页的错误信息
# 2. 启用debug日志
# A: 设置secrets: ACTIONS_STEP_DEBUG=true
# A: 设置secrets: ACTIONS_RUNNER_DEBUG=true
# 3. 使用act本地运行
brew install act
act push # 本地模拟push事件
.github/workflows/# .github/workflows/cd.yml
name: CD Pipeline
on:
workflow_run:
workflows: ["CI Pipeline"]
types: [completed]
branches: [main]
jobs:
deploy-staging:
runs-on: ubuntu-latest
environment: staging
steps:
- uses: actions/checkout@v4
- name: Deploy to Staging
run: |
kubectl set image deployment/app \
app=ghcr.io/myapp:${{ github.sha }} -n staging
kubectl rollout status deployment/app -n staging
- name: Smoke Test
run: |
sleep 30
curl -f https://staging.example.com/health
deploy-production:
needs: deploy-staging
runs-on: ubuntu-latest
environment: production
steps:
- name: Deploy to Production
run: |
kubectl set image deployment/app \
app=ghcr.io/myapp:${{ github.sha }} -n production
# actions/deploy/action.yml
name: 'Deploy to K8s'
description: 'Deploy service with canary rollout'
inputs:
environment:
description: 'Target environment'
required: true
image-tag:
description: 'Container image tag'
required: true
runs:
using: 'composite'
steps:
- name: Validate
shell: bash
run: |
[[ "${{ inputs.environment }}" =~ ^(staging|production)$ ]] || exit 1
- name: Deploy
shell: bash
run: |
kubectl apply -f k8s/${{ inputs.environment }}/
kubectl rollout status deployment/app \
-n ${{ inputs.environment }} --timeout=300s
# 常见原因:
# 1. YAML语法错误 → 用actionlint检查
# 2. 分支过滤器不匹配
# 3. fork PR无secrets权限
# 调试方法:
# 1. 查看Actions标签页错误信息
# 2. 启用debug: 设置secrets ACTIONS_STEP_DEBUG=true
# 3. 使用act本地运行
brew install act && act push
掌握GitHub Actions工作流、自定义Action、CI/CD流水线设计——这是现代DevOps的核心技能。