OA0 = Omni AI 0
OA0 是一个探索 AI 的论坛
现在注册
已注册用户请  登录
OA0  ›  技能包  ›  cicd-pipeline:通过 GitHub Actions 自动化创建、调试与管理 CI/CD 流

cicd-pipeline:通过 GitHub Actions 自动化创建、调试与管理 CI/CD 流

 
  admin ·  2026-02-05 20:28:49 · 3 次点击  · 0 条评论  

名称: cicd-pipeline
描述: 使用 GitHub Actions 创建、调试和管理 CI/CD 流水线。适用于用户需要设置自动化测试、部署、发布或工作流时。涵盖工作流语法、常见模式、密钥管理、缓存、矩阵构建和故障排除。
元数据: {"clawdbot":{"emoji":"🚀","requires":{"anyBins":["gh","git"]},"os":["linux","darwin","win32"]}}


CI/CD 流水线 (GitHub Actions)

使用 GitHub Actions 设置和管理 CI/CD 流水线。涵盖工作流创建、测试、部署、发布自动化和调试。

使用场景

  • 在推送/拉取请求时设置自动化测试
  • 创建部署流水线(预发布、生产环境)
  • 使用变更日志和标签自动化发布流程
  • 调试失败的 CI 工作流
  • 为跨平台测试设置矩阵构建
  • 在 CI 中管理密钥和环境变量
  • 通过缓存和并行化优化 CI

快速开始:为项目添加 CI

Node.js 项目

# .github/workflows/ci.yml
名称: CI

on:
  push:
    branches: [main]
  pull_request:
    branches: [main]

jobs:
  test:
    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 test
      - run: npm run lint

Python 项目

# .github/workflows/ci.yml
名称: CI

on:
  push:
    branches: [main]
  pull_request:
    branches: [main]

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-python@v5
        with:
          python-version: "3.12"
          cache: pip
      - run: pip install -r requirements.txt
      - run: pytest
      - run: ruff check .

Go 项目

# .github/workflows/ci.yml
名称: CI

on:
  push:
    branches: [main]
  pull_request:
    branches: [main]

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-go@v5
        with:
          go-version: "1.22"
      - run: go test ./...
      - run: go vet ./...

Rust 项目

# .github/workflows/ci.yml
名称: CI

on:
  push:
    branches: [main]
  pull_request:
    branches: [main]

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: dtolnay/rust-toolchain@stable
      - uses: Swatinem/rust-cache@v2
      - run: cargo test
      - run: cargo clippy -- -D warnings

常见模式

矩阵构建(跨版本/操作系统测试)

jobs:
  test:
    strategy:
      fail-fast: false
      matrix:
        os: [ubuntu-latest, macos-latest, windows-latest]
        node-version: [18, 20, 22]
    runs-on: ${{ matrix.os }}
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: ${{ matrix.node-version }}
      - run: npm ci
      - run: npm test

条件作业

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - run: npm test

  deploy:
    needs: test
    if: github.ref == 'refs/heads/main' && github.event_name == 'push'
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - run: ./deploy.sh

缓存依赖项

# Node.js (使用 setup-node 自动缓存)
- uses: actions/setup-node@v4
  with:
    node-version: 20
    cache: npm  # 或 yarn, pnpm

# 通用缓存
- uses: actions/cache@v4
  with:
    path: |
      ~/.cache/pip
      ~/.cargo/registry
      node_modules
    key: ${{ runner.os }}-deps-${{ hashFiles('**/package-lock.json') }}
    restore-keys: |
      ${{ runner.os }}-deps-

制品(保存构建输出)

- uses: actions/upload-artifact@v4
  with:
    name: build-output
    path: dist/
    retention-days: 7

# 在另一个作业中下载
- uses: actions/download-artifact@v4
  with:
    name: build-output
    path: dist/

定时运行(cron)

on:
  schedule:
    - cron: "0 6 * * 1"  # 每周一 UTC 时间 6:00
  workflow_dispatch:  # 同时允许手动触发

部署工作流

在推送标签时部署到生产环境

名称: Release

on:
  push:
    tags:
      - "v*"

jobs:
  release:
    runs-on: ubuntu-latest
    permissions:
      contents: write
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: 20
          cache: npm
      - run: npm ci
      - run: npm run build
      - run: npm test

      # 创建 GitHub Release
      - uses: softprops/action-gh-release@v2
        with:
          generate_release_notes: true
          files: |
            dist/*.js
            dist/*.css

部署到多个环境

名称: Deploy

on:
  push:
    branches: [main, staging]

jobs:
  deploy:
    runs-on: ubuntu-latest
    environment: ${{ github.ref == 'refs/heads/main' && 'production' || 'staging' }}
    steps:
      - uses: actions/checkout@v4
      - run: npm ci && npm run build
      - run: |
          if [ "${{ github.ref }}" = "refs/heads/main" ]; then
            ./deploy.sh production
          else
            ./deploy.sh staging
          fi
        env:
          DEPLOY_TOKEN: ${{ secrets.DEPLOY_TOKEN }}

Docker 构建与推送

名称: Docker

on:
  push:
    branches: [main]
    tags: ["v*"]

jobs:
  build:
    runs-on: ubuntu-latest
    permissions:
      packages: write
    steps:
      - uses: actions/checkout@v4
      - uses: docker/setup-buildx-action@v3
      - uses: docker/login-action@v3
        with:
          registry: ghcr.io
          username: ${{ github.actor }}
          password: ${{ secrets.GITHUB_TOKEN }}
      - uses: docker/build-push-action@v6
        with:
          push: true
          tags: |
            ghcr.io/${{ github.repository }}:latest
            ghcr.io/${{ github.repository }}:${{ github.sha }}
          cache-from: type=gha
          cache-to: type=gha,mode=max

发布时自动发布到 npm

名称: Publish

on:
  release:
    types: [published]

jobs:
  publish:
    runs-on: ubuntu-latest
    permissions:
      id-token: write
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: 20
          registry-url: https://registry.npmjs.org
      - run: npm ci
      - run: npm test
      - run: npm publish --provenance
        env:
          NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}

密钥管理

通过 CLI 设置密钥

# 设置仓库密钥
gh secret set DEPLOY_TOKEN --body "my-secret-value"

# 从文件设置
gh secret set SSH_KEY < ~/.ssh/deploy_key

# 为特定环境设置
gh secret set DB_PASSWORD --env production --body "p@ssw0rd"

# 列出密钥
gh secret list

# 删除密钥
gh secret delete OLD_SECRET

在工作流中使用密钥

env:
  # 此作业中所有步骤可用
  DATABASE_URL: ${{ secrets.DATABASE_URL }}

steps:
  - run: echo "Deploying..."
    env:
      # 仅此步骤可用
      API_KEY: ${{ secrets.API_KEY }}

环境保护规则

通过 GitHub UI 或 API 设置:
- 部署前需要审核者
- 等待计时器
- 分支限制
- 自定义部署分支策略

# 查看环境
gh api repos/{owner}/{repo}/environments | jq '.environments[].name'

工作流调试

重新运行失败的作业

# 列出最近的工作流运行
gh run list --limit 10

# 查看特定运行
gh run view <run-id>

# 查看失败作业的日志
gh run view <run-id> --log-failed

# 仅重新运行失败的作业
gh run rerun <run-id> --failed

# 重新运行整个工作流
gh run rerun <run-id>

使用 SSH 调试(通过 tmate)

# 在失败步骤前添加此步骤
- uses: mxschmitt/action-tmate@v3
  if: failure()
  with:
    limit-access-to-actor: true

常见故障及修复

脚本“权限被拒绝”

- run: chmod +x ./scripts/deploy.sh && ./scripts/deploy.sh

“找不到 Node 模块”

# 确保 npm ci 在 npm test 之前运行
- run: npm ci     # 安装 lockfile 中精确的版本
- run: npm test   # 现在 node_modules 已存在

“集成无法访问资源”

# 添加权限块
permissions:
  contents: write
  packages: write
  pull-requests: write

缓存未恢复

# 检查缓存键是否匹配 - 对 lockfile 使用 hashFiles
key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
# 不要用: key: ${{ runner.os }}-node-${{ hashFiles('package.json') }}

工作流未触发
- 检查:工作流文件是否在默认分支上?
- 检查:触发事件是否匹配?(pushpull_request
- 检查:分支过滤器是否正确?

# 手动触发工作流
gh workflow run ci.yml --ref main

工作流验证

推送前本地验证

# 检查 YAML 语法
python3 -c "import yaml; yaml.safe_load(open('.github/workflows/ci.yml'))" && echo "Valid"

# 使用 actionlint(如果已安装)
actionlint .github/workflows/ci.yml

# 或通过 Docker
docker run --rm -v "$(pwd):/repo" -w /repo rhysd/actionlint:latest

查看工作流图

# 列出所有工作流
gh workflow list

# 查看工作流定义
gh workflow view ci.yml

# 监视正在运行的工作流
gh run watch

高级模式

可重用工作流

# .github/workflows/reusable-test.yml
名称: Reusable Test
on:
  workflow_call:
    inputs:
      node-version:
        required: false
        type: string
        default: "20"
    secrets:
      npm-token:
        required: false

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: ${{ inputs.node-version }}
      - run: npm ci
      - run: npm test
# .github/workflows/ci.yml - 调用者
名称: CI
on: [push, pull_request]
jobs:
  test:
    uses: ./.github/workflows/reusable-test.yml
    with:
      node-version: "20"

并发控制(防止重复运行)

concurrency:
  group: ${{ github.workflow }}-${{ github.ref }}
  cancel-in-progress: true  # 取消同一分支的先前运行

路径过滤器(仅对相关变更运行)

on:
  push:
    paths:
      - "src/**"
      - "package.json"
      - "package-lock.json"
      - ".github/workflows/ci.yml"
    paths-ignore:
      - "docs/**"
      - "*.md"

单体仓库:仅测试变更的包

jobs:
  changes:
    runs-on: ubuntu-latest
    outputs:
      api: ${{ steps.filter.outputs.api }}
      web: ${{ steps.filter.outputs.web }}
    steps:
      - uses: actions/checkout@v4
      - uses: dorny/paths-filter@v3
        id: filter
        with:
          filters: |
            api:
              - 'packages/api/**'
            web:
              - 'packages/web/**'

  test-api:
    needs: changes
    if: needs.changes.outputs.api == 'true'
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - run: cd packages/api && npm ci && npm test

  test-web:
    needs: changes
    if: needs.changes.outputs.web == 'true'
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - run: cd packages/web && npm ci && npm test

提示

  • 在每个工作流中使用 workflow_dispatch,以便在调试时手动触发
  • 为保障供应链安全,使用 SHA 固定 Action 版本:uses: actions/checkout@b4ffde...
  • 对非关键步骤(如代码检查)使用 continue-on-error: true
  • 在作业上设置 timeout-minutes 以防止失控的构建(默认为 360 分钟)
  • 使用作业输出在作业间传递数据:outputs: result: ${{ steps.step-id.outputs.value }}
  • 对于自托管运行器:runs-on: self-hosted 并使用标签定位特定机器
3 次点击  ∙  0 人收藏  
登录后收藏  
目前尚无回复
0 条回复
About   ·   Help   ·    
OA0 - Omni AI 0 一个探索 AI 的社区
沪ICP备2024103595号-2
Developed with Cursor