ci-cd-pipeline-builder

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

CI/CD Pipeline Builder Skill

CI/CD 流水线构建技能

Overview

概述

This skill helps you build robust CI/CD pipelines for automated testing, building, and deployment. Covers GitHub Actions, Vercel integration, testing strategies, deployment patterns, and security best practices.
本技能可帮助你构建用于自动化测试、构建和部署的可靠CI/CD流水线,涵盖GitHub Actions、Vercel集成、测试策略、部署模式以及安全最佳实践。

CI/CD Philosophy

CI/CD 理念

Pipeline Principles

流水线原则

  1. Fast feedback: Fail early, inform quickly
  2. Reproducible: Same inputs = same outputs
  3. Secure: Secrets protected, dependencies verified
  4. Observable: Clear logs, status visibility
  1. 快速反馈:尽早失败,及时通知
  2. 可复现:相同输入产生相同输出
  3. 安全:保护密钥,验证依赖
  4. 可观测:日志清晰,状态可见

Pipeline Stages

流水线阶段

Trigger → Lint → Test → Build → Deploy → Verify
Trigger → Lint → Test → Build → Deploy → Verify

GitHub Actions Fundamentals

GitHub Actions 基础

Basic Workflow Structure

基础工作流结构

yaml
undefined
yaml
undefined

.github/workflows/ci.yml

.github/workflows/ci.yml

name: CI
on: push: branches: [main, develop] pull_request: branches: [main]
concurrency: group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true
jobs: 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: runs-on: ubuntu-latest needs: lint steps: - uses: actions/checkout@v4 - uses: actions/setup-node@v4 with: node-version: '20' cache: 'npm' - run: npm ci - run: npm test
build: runs-on: ubuntu-latest needs: [lint, test] steps: - uses: actions/checkout@v4 - uses: actions/setup-node@v4 with: node-version: '20' cache: 'npm' - run: npm ci - run: npm run build
undefined
name: CI
on: push: branches: [main, develop] pull_request: branches: [main]
concurrency: group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true
jobs: 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: runs-on: ubuntu-latest needs: lint steps: - uses: actions/checkout@v4 - uses: actions/setup-node@v4 with: node-version: '20' cache: 'npm' - run: npm ci - run: npm test
build: runs-on: ubuntu-latest needs: [lint, test] steps: - uses: actions/checkout@v4 - uses: actions/setup-node@v4 with: node-version: '20' cache: 'npm' - run: npm ci - run: npm run build
undefined

Complete Next.js CI/CD Pipeline

完整的Next.js CI/CD流水线

yaml
undefined
yaml
undefined

.github/workflows/ci-cd.yml

.github/workflows/ci-cd.yml

name: CI/CD Pipeline
on: push: branches: [main] pull_request: branches: [main]
env: NODE_VERSION: '20' VERCEL_ORG_ID: ${{ secrets.VERCEL_ORG_ID }} VERCEL_PROJECT_ID: ${{ secrets.VERCEL_PROJECT_ID }}
jobs:

===================

Quality Checks

===================

quality: name: Code Quality runs-on: ubuntu-latest steps: - name: Checkout uses: actions/checkout@v4
  - name: Setup Node.js
    uses: actions/setup-node@v4
    with:
      node-version: ${{ env.NODE_VERSION }}
      cache: 'npm'

  - name: Install dependencies
    run: npm ci

  - name: Type check
    run: npm run typecheck

  - name: Lint
    run: npm run lint

  - name: Format check
    run: npm run format:check

===================

Unit & Integration Tests

===================

test: name: Tests runs-on: ubuntu-latest needs: quality steps: - name: Checkout uses: actions/checkout@v4
  - name: Setup Node.js
    uses: actions/setup-node@v4
    with:
      node-version: ${{ env.NODE_VERSION }}
      cache: 'npm'

  - name: Install dependencies
    run: npm ci

  - name: Run tests
    run: npm run test:ci

  - name: Upload coverage
    uses: codecov/codecov-action@v3
    with:
      token: ${{ secrets.CODECOV_TOKEN }}
      files: ./coverage/lcov.info
      fail_ci_if_error: false

===================

Build

===================

build: name: Build runs-on: ubuntu-latest needs: [quality, test] steps: - name: Checkout uses: actions/checkout@v4
  - name: Setup Node.js
    uses: actions/setup-node@v4
    with:
      node-version: ${{ env.NODE_VERSION }}
      cache: 'npm'

  - name: Install dependencies
    run: npm ci

  - name: Build
    run: npm run build
    env:
      NEXT_PUBLIC_SUPABASE_URL: ${{ secrets.NEXT_PUBLIC_SUPABASE_URL }}
      NEXT_PUBLIC_SUPABASE_ANON_KEY: ${{ secrets.NEXT_PUBLIC_SUPABASE_ANON_KEY }}

  - name: Upload build artifact
    uses: actions/upload-artifact@v4
    with:
      name: build
      path: .next
      retention-days: 1

===================

E2E Tests

===================

e2e: name: E2E Tests runs-on: ubuntu-latest needs: build steps: - name: Checkout uses: actions/checkout@v4
  - name: Setup Node.js
    uses: actions/setup-node@v4
    with:
      node-version: ${{ env.NODE_VERSION }}
      cache: 'npm'

  - name: Install dependencies
    run: npm ci

  - name: Install Playwright browsers
    run: npx playwright install --with-deps chromium

  - name: Download build
    uses: actions/download-artifact@v4
    with:
      name: build
      path: .next

  - name: Run E2E tests
    run: npm run test:e2e
    env:
      NEXT_PUBLIC_SUPABASE_URL: ${{ secrets.NEXT_PUBLIC_SUPABASE_URL }}
      NEXT_PUBLIC_SUPABASE_ANON_KEY: ${{ secrets.NEXT_PUBLIC_SUPABASE_ANON_KEY }}

  - name: Upload test results
    if: failure()
    uses: actions/upload-artifact@v4
    with:
      name: playwright-report
      path: playwright-report
      retention-days: 7

===================

Deploy Preview (PRs)

===================

deploy-preview: name: Deploy Preview runs-on: ubuntu-latest needs: [build, e2e] if: github.event_name == 'pull_request' environment: name: preview url: ${{ steps.deploy.outputs.url }} steps: - name: Checkout uses: actions/checkout@v4
  - name: Install Vercel CLI
    run: npm install -g vercel

  - name: Pull Vercel Environment
    run: vercel pull --yes --environment=preview --token=${{ secrets.VERCEL_TOKEN }}

  - name: Build Project
    run: vercel build --token=${{ secrets.VERCEL_TOKEN }}

  - name: Deploy to Vercel
    id: deploy
    run: |
      url=$(vercel deploy --prebuilt --token=${{ secrets.VERCEL_TOKEN }})
      echo "url=$url" >> $GITHUB_OUTPUT

  - name: Comment PR with URL
    uses: actions/github-script@v7
    with:
      script: |
        github.rest.issues.createComment({
          issue_number: context.issue.number,
          owner: context.repo.owner,
          repo: context.repo.repo,
          body: `🚀 Preview deployed to: ${{ steps.deploy.outputs.url }}`
        })

===================

Deploy Production

===================

deploy-production: name: Deploy Production runs-on: ubuntu-latest needs: [build, e2e] if: github.ref == 'refs/heads/main' && github.event_name == 'push' environment: name: production url: https://myapp.com steps: - name: Checkout uses: actions/checkout@v4
  - name: Install Vercel CLI
    run: npm install -g vercel

  - name: Pull Vercel Environment
    run: vercel pull --yes --environment=production --token=${{ secrets.VERCEL_TOKEN }}

  - name: Build Project
    run: vercel build --prod --token=${{ secrets.VERCEL_TOKEN }}

  - name: Deploy to Vercel
    run: vercel deploy --prebuilt --prod --token=${{ secrets.VERCEL_TOKEN }}
undefined
name: CI/CD Pipeline
on: push: branches: [main] pull_request: branches: [main]
env: NODE_VERSION: '20' VERCEL_ORG_ID: ${{ secrets.VERCEL_ORG_ID }} VERCEL_PROJECT_ID: ${{ secrets.VERCEL_PROJECT_ID }}
jobs:

===================

质量检查

===================

quality: name: Code Quality runs-on: ubuntu-latest steps: - name: Checkout uses: actions/checkout@v4
  - name: Setup Node.js
    uses: actions/setup-node@v4
    with:
      node-version: ${{ env.NODE_VERSION }}
      cache: 'npm'

  - name: Install dependencies
    run: npm ci

  - name: Type check
    run: npm run typecheck

  - name: Lint
    run: npm run lint

  - name: Format check
    run: npm run format:check

===================

单元与集成测试

===================

test: name: Tests runs-on: ubuntu-latest needs: quality steps: - name: Checkout uses: actions/checkout@v4
  - name: Setup Node.js
    uses: actions/setup-node@v4
    with:
      node-version: ${{ env.NODE_VERSION }}
      cache: 'npm'

  - name: Install dependencies
    run: npm ci

  - name: Run tests
    run: npm run test:ci

  - name: Upload coverage
    uses: codecov/codecov-action@v3
    with:
      token: ${{ secrets.CODECOV_TOKEN }}
      files: ./coverage/lcov.info
      fail_ci_if_error: false

===================

构建

===================

build: name: Build runs-on: ubuntu-latest needs: [quality, test] steps: - name: Checkout uses: actions/checkout@v4
  - name: Setup Node.js
    uses: actions/setup-node@v4
    with:
      node-version: ${{ env.NODE_VERSION }}
      cache: 'npm'

  - name: Install dependencies
    run: npm ci

  - name: Build
    run: npm run build
    env:
      NEXT_PUBLIC_SUPABASE_URL: ${{ secrets.NEXT_PUBLIC_SUPABASE_URL }}
      NEXT_PUBLIC_SUPABASE_ANON_KEY: ${{ secrets.NEXT_PUBLIC_SUPABASE_ANON_KEY }}

  - name: Upload build artifact
    uses: actions/upload-artifact@v4
    with:
      name: build
      path: .next
      retention-days: 1

===================

端到端测试

===================

e2e: name: E2E Tests runs-on: ubuntu-latest needs: build steps: - name: Checkout uses: actions/checkout@v4
  - name: Setup Node.js
    uses: actions/setup-node@v4
    with:
      node-version: ${{ env.NODE_VERSION }}
      cache: 'npm'

  - name: Install dependencies
    run: npm ci

  - name: Install Playwright browsers
    run: npx playwright install --with-deps chromium

  - name: Download build
    uses: actions/download-artifact@v4
    with:
      name: build
      path: .next

  - name: Run E2E tests
    run: npm run test:e2e
    env:
      NEXT_PUBLIC_SUPABASE_URL: ${{ secrets.NEXT_PUBLIC_SUPABASE_URL }}
      NEXT_PUBLIC_SUPABASE_ANON_KEY: ${{ secrets.NEXT_PUBLIC_SUPABASE_ANON_KEY }}

  - name: Upload test results
    if: failure()
    uses: actions/upload-artifact@v4
    with:
      name: playwright-report
      path: playwright-report
      retention-days: 7

===================

预览部署(PR)

===================

deploy-preview: name: Deploy Preview runs-on: ubuntu-latest needs: [build, e2e] if: github.event_name == 'pull_request' environment: name: preview url: ${{ steps.deploy.outputs.url }} steps: - name: Checkout uses: actions/checkout@v4
  - name: Install Vercel CLI
    run: npm install -g vercel

  - name: Pull Vercel Environment
    run: vercel pull --yes --environment=preview --token=${{ secrets.VERCEL_TOKEN }}

  - name: Build Project
    run: vercel build --token=${{ secrets.VERCEL_TOKEN }}

  - name: Deploy to Vercel
    id: deploy
    run: |
      url=$(vercel deploy --prebuilt --token=${{ secrets.VERCEL_TOKEN }})
      echo "url=$url" >> $GITHUB_OUTPUT

  - name: Comment PR with URL
    uses: actions/github-script@v7
    with:
      script: |
        github.rest.issues.createComment({
          issue_number: context.issue.number,
          owner: context.repo.owner,
          repo: context.repo.repo,
          body: `🚀 Preview deployed to: ${{ steps.deploy.outputs.url }}`
        })

===================

生产环境部署

===================

deploy-production: name: Deploy Production runs-on: ubuntu-latest needs: [build, e2e] if: github.ref == 'refs/heads/main' && github.event_name == 'push' environment: name: production url: https://myapp.com steps: - name: Checkout uses: actions/checkout@v4
  - name: Install Vercel CLI
    run: npm install -g vercel

  - name: Pull Vercel Environment
    run: vercel pull --yes --environment=production --token=${{ secrets.VERCEL_TOKEN }}

  - name: Build Project
    run: vercel build --prod --token=${{ secrets.VERCEL_TOKEN }}

  - name: Deploy to Vercel
    run: vercel deploy --prebuilt --prod --token=${{ secrets.VERCEL_TOKEN }}
undefined

Testing Strategies

测试策略

Parallel Test Execution

并行测试执行

yaml
undefined
yaml
undefined

.github/workflows/test-parallel.yml

.github/workflows/test-parallel.yml

name: Parallel Tests
on: [push, pull_request]
jobs: test: runs-on: ubuntu-latest strategy: fail-fast: false matrix: shard: [1, 2, 3, 4] steps: - uses: actions/checkout@v4 - uses: actions/setup-node@v4 with: node-version: '20' cache: 'npm'
  - run: npm ci

  - name: Run tests (shard ${{ matrix.shard }}/4)
    run: npm run test -- --shard=${{ matrix.shard }}/4
merge-results: needs: test runs-on: ubuntu-latest steps: - name: Report results run: echo "All test shards passed!"
undefined
name: Parallel Tests
on: [push, pull_request]
jobs: test: runs-on: ubuntu-latest strategy: fail-fast: false matrix: shard: [1, 2, 3, 4] steps: - uses: actions/checkout@v4 - uses: actions/setup-node@v4 with: node-version: '20' cache: 'npm'
  - run: npm ci

  - name: Run tests (shard ${{ matrix.shard }}/4)
    run: npm run test -- --shard=${{ matrix.shard }}/4
merge-results: needs: test runs-on: ubuntu-latest steps: - name: Report results run: echo "All test shards passed!"
undefined

Matrix Testing

矩阵测试

yaml
undefined
yaml
undefined

.github/workflows/matrix-test.yml

.github/workflows/matrix-test.yml

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

Database Integration

数据库集成

Supabase in CI

CI中的Supabase

yaml
undefined
yaml
undefined

.github/workflows/test-with-db.yml

.github/workflows/test-with-db.yml

name: Tests with Database
on: [push, pull_request]
jobs: test: runs-on: ubuntu-latest services: postgres: image: postgres:15 env: POSTGRES_USER: postgres POSTGRES_PASSWORD: postgres POSTGRES_DB: test_db 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'

  - name: Install dependencies
    run: npm ci

  - name: Setup Supabase CLI
    uses: supabase/setup-cli@v1

  - name: Start Supabase
    run: supabase start

  - name: Run migrations
    run: supabase db reset
    env:
      SUPABASE_DB_URL: postgresql://postgres:postgres@localhost:54322/postgres

  - name: Run tests
    run: npm run test:integration
    env:
      DATABASE_URL: postgresql://postgres:postgres@localhost:54322/postgres
      SUPABASE_URL: http://localhost:54321
      SUPABASE_ANON_KEY: ${{ secrets.SUPABASE_ANON_KEY }}
undefined
name: Tests with Database
on: [push, pull_request]
jobs: test: runs-on: ubuntu-latest services: postgres: image: postgres:15 env: POSTGRES_USER: postgres POSTGRES_PASSWORD: postgres POSTGRES_DB: test_db 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'

  - name: Install dependencies
    run: npm ci

  - name: Setup Supabase CLI
    uses: supabase/setup-cli@v1

  - name: Start Supabase
    run: supabase start

  - name: Run migrations
    run: supabase db reset
    env:
      SUPABASE_DB_URL: postgresql://postgres:postgres@localhost:54322/postgres

  - name: Run tests
    run: npm run test:integration
    env:
      DATABASE_URL: postgresql://postgres:postgres@localhost:54322/postgres
      SUPABASE_URL: http://localhost:54321
      SUPABASE_ANON_KEY: ${{ secrets.SUPABASE_ANON_KEY }}
undefined

Release Automation

发布自动化

Automated Releases

自动发布

yaml
undefined
yaml
undefined

.github/workflows/release.yml

.github/workflows/release.yml

name: Release
on: push: branches: [main]
jobs: release: runs-on: ubuntu-latest permissions: contents: write pull-requests: write steps: - uses: actions/checkout@v4 with: fetch-depth: 0
  - name: Setup Node.js
    uses: actions/setup-node@v4
    with:
      node-version: '20'
      cache: 'npm'

  - name: Install dependencies
    run: npm ci

  - name: Create Release
    uses: google-github-actions/release-please-action@v4
    with:
      release-type: node
      package-name: my-app

  - name: Publish to npm
    if: ${{ steps.release.outputs.release_created }}
    run: npm publish
    env:
      NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
undefined
name: Release
on: push: branches: [main]
jobs: release: runs-on: ubuntu-latest permissions: contents: write pull-requests: write steps: - uses: actions/checkout@v4 with: fetch-depth: 0
  - name: Setup Node.js
    uses: actions/setup-node@v4
    with:
      node-version: '20'
      cache: 'npm'

  - name: Install dependencies
    run: npm ci

  - name: Create Release
    uses: google-github-actions/release-please-action@v4
    with:
      release-type: node
      package-name: my-app

  - name: Publish to npm
    if: ${{ steps.release.outputs.release_created }}
    run: npm publish
    env:
      NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
undefined

Changelog Generation

变更日志生成

yaml
undefined
yaml
undefined

.github/workflows/changelog.yml

.github/workflows/changelog.yml

name: Changelog
on: release: types: [published]
jobs: update-changelog: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 with: ref: main
  - name: Update CHANGELOG
    uses: stefanzweifel/changelog-updater-action@v1
    with:
      latest-version: ${{ github.event.release.tag_name }}
      release-notes: ${{ github.event.release.body }}

  - name: Commit changes
    uses: stefanzweifel/git-auto-commit-action@v5
    with:
      commit_message: "docs: update CHANGELOG for ${{ github.event.release.tag_name }}"
      file_pattern: CHANGELOG.md
undefined
name: Changelog
on: release: types: [published]
jobs: update-changelog: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 with: ref: main
  - name: Update CHANGELOG
    uses: stefanzweifel/changelog-updater-action@v1
    with:
      latest-version: ${{ github.event.release.tag_name }}
      release-notes: ${{ github.event.release.body }}

  - name: Commit changes
    uses: stefanzweifel/git-auto-commit-action@v5
    with:
      commit_message: "docs: update CHANGELOG for ${{ github.event.release.tag_name }}"
      file_pattern: CHANGELOG.md
undefined

Security Scanning

安全扫描

Dependency & Code Scanning

依赖与代码扫描

yaml
undefined
yaml
undefined

.github/workflows/security.yml

.github/workflows/security.yml

name: Security
on: push: branches: [main] pull_request: branches: [main] schedule: - cron: '0 0 * * 0' # Weekly
jobs: dependency-audit: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: actions/setup-node@v4 with: node-version: '20' - run: npm audit --audit-level=high
codeql: runs-on: ubuntu-latest permissions: security-events: write steps: - uses: actions/checkout@v4 - uses: github/codeql-action/init@v3 with: languages: javascript - uses: github/codeql-action/analyze@v3
secrets-scan: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 with: fetch-depth: 0 - uses: gitleaks/gitleaks-action@v2 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
undefined
name: Security
on: push: branches: [main] pull_request: branches: [main] schedule: - cron: '0 0 * * 0' # Weekly
jobs: dependency-audit: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: actions/setup-node@v4 with: node-version: '20' - run: npm audit --audit-level=high
codeql: runs-on: ubuntu-latest permissions: security-events: write steps: - uses: actions/checkout@v4 - uses: github/codeql-action/init@v3 with: languages: javascript - uses: github/codeql-action/analyze@v3
secrets-scan: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 with: fetch-depth: 0 - uses: gitleaks/gitleaks-action@v2 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
undefined

Caching Strategies

缓存策略

Effective Caching

高效缓存

yaml
undefined
yaml
undefined

.github/workflows/cached-build.yml

.github/workflows/cached-build.yml

name: Cached Build
on: [push, pull_request]
jobs: build: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4
  - uses: actions/setup-node@v4
    with:
      node-version: '20'
      cache: 'npm'

  # Cache Next.js build
  - name: Cache Next.js
    uses: actions/cache@v4
    with:
      path: |
        .next/cache
      key: ${{ runner.os }}-nextjs-${{ hashFiles('**/package-lock.json') }}-${{ hashFiles('**/*.js', '**/*.jsx', '**/*.ts', '**/*.tsx') }}
      restore-keys: |
        ${{ runner.os }}-nextjs-${{ hashFiles('**/package-lock.json') }}-

  # Cache Playwright browsers
  - name: Cache Playwright
    uses: actions/cache@v4
    with:
      path: ~/.cache/ms-playwright
      key: ${{ runner.os }}-playwright-${{ hashFiles('**/package-lock.json') }}

  - run: npm ci
  - run: npm run build
undefined
name: Cached Build
on: [push, pull_request]
jobs: build: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4
  - uses: actions/setup-node@v4
    with:
      node-version: '20'
      cache: 'npm'

  # Cache Next.js build
  - name: Cache Next.js
    uses: actions/cache@v4
    with:
      path: |
        .next/cache
      key: ${{ runner.os }}-nextjs-${{ hashFiles('**/package-lock.json') }}-${{ hashFiles('**/*.js', '**/*.jsx', '**/*.ts', '**/*.tsx') }}
      restore-keys: |
        ${{ runner.os }}-nextjs-${{ hashFiles('**/package-lock.json') }}-

  # Cache Playwright browsers
  - name: Cache Playwright
    uses: actions/cache@v4
    with:
      path: ~/.cache/ms-playwright
      key: ${{ runner.os }}-playwright-${{ hashFiles('**/package-lock.json') }}

  - run: npm ci
  - run: npm run build
undefined

Environment Management

环境管理

Environment-Based Deployments

基于环境的部署

yaml
undefined
yaml
undefined

.github/workflows/deploy.yml

.github/workflows/deploy.yml

name: Deploy
on: push: branches: - main - develop
jobs: deploy: runs-on: ubuntu-latest environment: name: ${{ github.ref == 'refs/heads/main' && 'production' || 'staging' }} url: ${{ github.ref == 'refs/heads/main' && 'https://myapp.com' || 'https://staging.myapp.com' }} steps: - uses: actions/checkout@v4
  - name: Deploy to ${{ github.ref == 'refs/heads/main' && 'production' || 'staging' }}
    run: |
      echo "Deploying to ${{ github.ref == 'refs/heads/main' && 'production' || 'staging' }}"
    env:
      API_URL: ${{ vars.API_URL }}
      API_KEY: ${{ secrets.API_KEY }}
undefined
name: Deploy
on: push: branches: - main - develop
jobs: deploy: runs-on: ubuntu-latest environment: name: ${{ github.ref == 'refs/heads/main' && 'production' || 'staging' }} url: ${{ github.ref == 'refs/heads/main' && 'https://myapp.com' || 'https://staging.myapp.com' }} steps: - uses: actions/checkout@v4
  - name: Deploy to ${{ github.ref == 'refs/heads/main' && 'production' || 'staging' }}
    run: |
      echo "Deploying to ${{ github.ref == 'refs/heads/main' && 'production' || 'staging' }}"
    env:
      API_URL: ${{ vars.API_URL }}
      API_KEY: ${{ secrets.API_KEY }}
undefined

Workflow Optimization

工作流优化

Conditional Jobs

条件式任务

yaml
undefined
yaml
undefined

.github/workflows/smart-ci.yml

.github/workflows/smart-ci.yml

name: Smart CI
on: push: branches: [main] pull_request: branches: [main]
jobs: changes: runs-on: ubuntu-latest outputs: frontend: ${{ steps.filter.outputs.frontend }} backend: ${{ steps.filter.outputs.backend }} docs: ${{ steps.filter.outputs.docs }} steps: - uses: actions/checkout@v4 - uses: dorny/paths-filter@v3 id: filter with: filters: | frontend: - 'src/app/' - 'src/components/' backend: - 'src/api/' - 'src/lib/' docs: - 'docs/**' - '*.md'
test-frontend: needs: changes if: ${{ needs.changes.outputs.frontend == 'true' }} runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - run: npm ci - run: npm run test:frontend
test-backend: needs: changes if: ${{ needs.changes.outputs.backend == 'true' }} runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - run: npm ci - run: npm run test:backend
deploy-docs: needs: changes if: ${{ needs.changes.outputs.docs == 'true' }} runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - run: npm run build:docs
undefined
name: Smart CI
on: push: branches: [main] pull_request: branches: [main]
jobs: changes: runs-on: ubuntu-latest outputs: frontend: ${{ steps.filter.outputs.frontend }} backend: ${{ steps.filter.outputs.backend }} docs: ${{ steps.filter.outputs.docs }} steps: - uses: actions/checkout@v4 - uses: dorny/paths-filter@v3 id: filter with: filters: | frontend: - 'src/app/' - 'src/components/' backend: - 'src/api/' - 'src/lib/' docs: - 'docs/**' - '*.md'
test-frontend: needs: changes if: ${{ needs.changes.outputs.frontend == 'true' }} runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - run: npm ci - run: npm run test:frontend
test-backend: needs: changes if: ${{ needs.changes.outputs.backend == 'true' }} runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - run: npm ci - run: npm run test:backend
deploy-docs: needs: changes if: ${{ needs.changes.outputs.docs == 'true' }} runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - run: npm run build:docs
undefined

Notification & Reporting

通知与报告

Slack Notifications

Slack通知

yaml
undefined
yaml
undefined

.github/workflows/notify.yml

.github/workflows/notify.yml

name: CI with Notifications
on: [push]
jobs: build: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - run: npm ci - run: npm run build
notify: needs: build runs-on: ubuntu-latest if: always() steps: - name: Notify Slack uses: slackapi/slack-github-action@v1 with: payload: | { "text": "${{ needs.build.result == 'success' && '✅' || '❌' }} Build ${{ needs.build.result }}", "blocks": [ { "type": "section", "text": { "type": "mrkdwn", "text": "${{ github.repository }} - ${{ github.ref_name }}\nCommit: ${{ github.sha }}\nBy: ${{ github.actor }}" } } ] } env: SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }} SLACK_WEBHOOK_TYPE: INCOMING_WEBHOOK
undefined
name: CI with Notifications
on: [push]
jobs: build: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - run: npm ci - run: npm run build
notify: needs: build runs-on: ubuntu-latest if: always() steps: - name: Notify Slack uses: slackapi/slack-github-action@v1 with: payload: | { "text": "${{ needs.build.result == 'success' && '✅' || '❌' }} Build ${{ needs.build.result }}", "blocks": [ { "type": "section", "text": { "type": "mrkdwn", "text": "${{ github.repository }} - ${{ github.ref_name }}\nCommit: ${{ github.sha }}\nBy: ${{ github.actor }}" } } ] } env: SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }} SLACK_WEBHOOK_TYPE: INCOMING_WEBHOOK
undefined

Pipeline Checklist

流水线检查清单

Essential Components

核心组件

  • Lint and format checks
  • Type checking (TypeScript)
  • Unit and integration tests
  • Build verification
  • Security scanning
  • 代码规范与格式检查
  • 类型检查(TypeScript)
  • 单元与集成测试
  • 构建验证
  • 安全扫描

Deployment

部署

  • Preview deployments for PRs
  • Production deployment on main
  • Environment-specific configs
  • Rollback capability
  • PR预览部署
  • 主分支生产环境部署
  • 环境专属配置
  • 回滚能力

Performance

性能

  • Effective caching strategy
  • Parallel job execution
  • Conditional job execution
  • Build artifact reuse
  • 高效缓存策略
  • 任务并行执行
  • 条件式任务执行
  • 构建产物复用

Security

安全

  • Secrets properly managed
  • Dependency auditing
  • Code scanning enabled
  • Protected environments
  • 密钥妥善管理
  • 依赖审计
  • 代码扫描启用
  • 受保护环境

When to Use This Skill

何时使用本技能

Invoke this skill when:
  • Setting up CI/CD for a new project
  • Optimizing slow pipelines
  • Adding deployment automation
  • Implementing release management
  • Setting up security scanning
  • Configuring environment-based deployments
  • Creating preview environments
在以下场景调用本技能:
  • 为新项目搭建CI/CD流水线
  • 优化缓慢的流水线
  • 添加部署自动化
  • 实现发布管理
  • 配置安全扫描
  • 设置基于环境的部署
  • 创建预览环境