提示:本网站现在为维护调试状态

CI/CD パイプライン設計:GitHub Actions + Cache + Matrix Build

Choyeon
Choyeon
2026年9月26日 1 分で読了 355 閲覧
723 字 4,434 文字 更新日 2026年11月8日
CI/CD パイプライン設計:GitHub Actions + Cache + Matrix Build
目次

CI/CD Pipeline Design: GitHub Actions + Cache + Matrix Build

CI/CD is the backbone of engineering throughput. Poor design forces 40+ min PR waits and random failures; well-designed pipelines deliver trusted feedback under 5 minutes, run matrix tests across versions/OSes, and cache hits make repeat builds instant.

Stage Split and Path Filtering

Classic 5 phases: (1) changes filter: skip entire untouched subtrees (docs-only PR bypasses backend tests); (2) lint stage fast-fails within 8 min max; (3) test multi-version matrix parallel; (4) build artifacts; (5) publish on git tags only. Concurrency auto-cancels prior runs on same ref, saves Action minutes.

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

on:
  push:
    branches: [main, develop]
    tags: ['v*.*.*']
  pull_request:
    branches: [main, develop]

concurrency:
  group: ${{ github.workflow }}-${{ github.ref }}
  cancel-in-progress: true

env:
  REGISTRY: ghcr.io
  IMAGE_NAME: ${{ github.repository }}

jobs:
  changes:
    runs-on: ubuntu-latest
    outputs:
      backend: ${{ steps.filter.outputs.backend }}
      frontend: ${{ steps.filter.outputs.frontend }}
      infra: ${{ steps.filter.outputs.infra }}
    steps:
      - uses: actions/checkout@v4
      - uses: dorny/paths-filter@v3
        id: filter
        with:
          filters: |
            backend:
              - 'apps/api/**'
              - 'packages/shared/**'
              - 'pyproject.toml'
            frontend:
              - 'apps/web/**'
              - 'packages/ui/**'
              - 'pnpm-lock.yaml'
            infra:
              - 'infra/**'
              - 'Dockerfile*'

  lint:
    needs: changes
    if: needs.changes.outputs.backend == 'true' || needs.changes.outputs.frontend == 'true'
    runs-on: ubuntu-latest
    timeout-minutes: 8
    steps:
      - uses: actions/checkout@v4
      - uses: pnpm/action-setup@v4
        with: { version: 9 }
      - uses: actions/setup-node@v4
        with:
          node-version: 20
          cache: pnpm
          cache-dependency-path: pnpm-lock.yaml
      - name: Install Node deps
        run: pnpm install --frozen-lockfile --prefer-offline
      - uses: actions/setup-python@v5
        with:
          python-version: '3.12'
          cache: pip
          cache-dependency-path: pyproject.toml
      - name: Install Python deps
        run: pip install -e ".[dev]" --retries 3
      - name: Run ESLint + Ruff
        run: |
          pnpm lint
          ruff check apps/api packages
      - name: Cache turbo setup
        uses: actions/cache@v4
        with:
          path: .turbo
          key: turbo-${{ github.sha }}
          restore-keys: turbo-

  test:
    needs: lint
    runs-on: ubuntu-latest
    timeout-minutes: 20
    strategy:
      fail-fast: false
      matrix:
        python-version: ['3.11', '3.12', '3.13']
        node-version: ['18', '20', '22']
        os: [ubuntu-latest]
        include:
          - os: macos-latest
            python-version: '3.12'
            node-version: '20'
    services:
      postgres:
        image: postgres:16-alpine
        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-alpine
        ports: ['6379:6379']
    steps:
      - uses: actions/checkout@v4
      - uses: pnpm/action-setup@v4; with: { version: 9 }
      - uses: actions/setup-node@v4
        with:
          node-version: ${{ matrix.node-version }}
          cache: pnpm
      - uses: actions/setup-python@v5
        with:
          python-version: ${{ matrix.python-version }}
          cache: pip
      - run: pnpm install --frozen-lockfile
      - run: pip install -e ".[test]"
      - name: Run tests with coverage
        run: |
          pnpm test -- --coverage --reporter=github
          pytest apps/api --cov=apps/api --cov-report=xml
        env:
          DATABASE_URL: postgresql://test:test@localhost:5432/test
          REDIS_URL: redis://localhost:6379
      - uses: codecov/codecov-action@v4
        if: matrix.os == 'ubuntu-latest' && matrix.node-version == '20' && matrix.python-version == '3.12'
        with: { fail_ci_if_error: false, token: ${{ secrets.CODECOV_TOKEN }} }

  build-and-push-image:
    needs: test
    if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/v')
    runs-on: ubuntu-latest
    permissions:
      contents: read
      packages: write
    steps:
      - uses: actions/checkout@v4
      - uses: docker/setup-buildx-action@v3
      - uses: docker/login-action@v3
        with:
          registry: ${{ env.REGISTRY }}
          username: ${{ github.actor }}
          password: ${{ secrets.GITHUB_TOKEN }}
      - name: Extract metadata
        id: meta
        uses: docker/metadata-action@v5
        with:
          images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
          tags: |
            type=semver,pattern={{version}}
            type=semver,pattern={{major}}.{{minor}}
            type=sha,prefix=
      - name: Build and push
        uses: docker/build-push-action@v6
        with:
          context: .
          push: true
          platforms: linux/amd64,linux/arm64
          tags: ${{ steps.meta.outputs.tags }}
          labels: ${{ steps.meta.outputs.labels }}
          cache-from: type=gha
          cache-to: type=gha,mode=max

Cache + Matrix Build: Three Musketeers of Speed

(1) Dep cache: setup-node pnpm cache + pip cache skip install on 90%+ builds; (2) Task artifact cache: turbo cache shares builds across workflow runs; (3) Docker layer cache: buildx gha cache reuses layers, push drops from 5 min to 40s. Matrix spans Python 3.11-3.13 × Node 18-22 across OSes; matrix include injects macOS single run to catch Unix-compat regressions.

Optimization Baseline Duration Optimized Savings
npm/pip install 3 min 20s (95% hit) 89%
Turborepo build 6 min 15s (full hit) 96%
Docker image push 5 min 40s 87%
Matrix sequential 30 min 6 min (5 parallel) 80%
Path filtering skip 20 min / PR 3 min 85%

Best Practices

Every job sets timeout-minutes hard cap against hangs. services use Postgres/Redis healthcheck before test start. fail-fast:false keeps all matrix combos running to surface every failure. Only semver tags trigger publish; main branch stops at build+test only.

X微博Telegram

筆者について

投票

你最希望 Rosetta 优先加入哪项功能?

社区投票(演示数据,可后台删除)

コメント (4)

0 / 3000
算法小菜鸟
算法小菜鸟2026年9月7日

建议可以再加一下关于成本优化的部分,云上资源如果不注意优化的话,账单真的会吓死个人。

DBA界的卷王
DBA界的卷王2026年9月7日

博主太懂运维的痛了!那个日志系统选型的部分我太有共鸣了,之前选型踩的坑和你说的一模一样。

奶茶味程序媛
奶茶味程序媛2026年9月7日

哈哈,备份不验证等于没备份那段我笑了,我之前就是吃了这个大亏,数据库备份了半年才发现根本恢复不了。

全栈打工人
全栈打工人2026年9月7日

想请教一下:生产环境的 etcd 集群一般推荐几个节点?3 个和 5 个在性能和可用性上该怎么权衡?

関連記事

Monorepo ツールチェーン:Turborepo + pnpm workspace

Monorepo ツールチェーン:Turborepo + pnpm workspace

大規模フルスタックプロジェクト向けMonorepo完全ガイド:pnpm workspaceによる依存関係統合管理、Turborepoによるタスクオーケストレーション・インクリメンタルビルド・リモートキャッシュ。Nx/Lerna比較、コード共通化とリリースベストプラクティス。

1 分で読了
Git 高度なワークフロー

Git 高度なワークフロー

Git上級操作:Interactive Rebase、Cherry-pick、Bisectによるバグ特定、reflogとresetによる誤操作からの復旧。

1 分で読了
Docker Compose 本番デプロイ実践

Docker Compose 本番デプロイ実践

Docker Composeの本番環境ベストプラクティス:マルチステージビルド、ヘルスチェック、リソース制限、ログ設定、ネットワーク分離、シークレット管理を解説。

1 分で読了
Alembic ディープガイド:DBマイグレーション + 自動生成 + ブランチマージ

Alembic ディープガイド:DBマイグレーション + 自動生成 + ブランチマージ

SQLAlchemy公式マイグレーションツール Alembic 完全ガイド:env.py設定、autogenerateによるモデル変更検出(カラム・インデックス・制約)、バッチスクリプト、ダウングレードロールバック戦略、複数人開発時のマイグレーションコンフリクトとhead分岐マージの標準SOP、本番デプロイチェックリスト付き。

1 分で読了
テストピラミッド:単体/結合/E2E 比率と実践

テストピラミッド:単体/結合/E2E 比率と実践

テストピラミッド体系解説:下層 単体テスト(多数・高速・Mock分離)、中層 結合テスト(実DB/メッセージ協調)、上層 E2E(少数・重要ユーザーフロー)。推奨比率 70/20/10、カバレッジ指標と実践ガイド。

1 分で読了
JWT 認証セキュリティ + OAuth2 vs SAML

JWT 認証セキュリティ + OAuth2 vs SAML

JWT脆弱性と対策:alg混乱攻撃、鍵総当たり、KIDインジェクション、リプレイ対策。さらにOAuth2+PKCE、OIDC、SAML2.0の3プロトコル多次元比較。

1 分で読了