ci-cd-pipeline-builder
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseCI/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
流水线原则
- Fast feedback: Fail early, inform quickly
- Reproducible: Same inputs = same outputs
- Secure: Secrets protected, dependencies verified
- Observable: Clear logs, status visibility
- 快速反馈:尽早失败,及时通知
- 可复现:相同输入产生相同输出
- 安全:保护密钥,验证依赖
- 可观测:日志清晰,状态可见
Pipeline Stages
流水线阶段
Trigger → Lint → Test → Build → Deploy → VerifyTrigger → Lint → Test → Build → Deploy → VerifyGitHub Actions Fundamentals
GitHub Actions 基础
Basic Workflow Structure
基础工作流结构
yaml
undefinedyaml
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
undefinedname: 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
undefinedComplete Next.js CI/CD Pipeline
完整的Next.js CI/CD流水线
yaml
undefinedyaml
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 }}undefinedname: 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 }}undefinedTesting Strategies
测试策略
Parallel Test Execution
并行测试执行
yaml
undefinedyaml
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 }}/4merge-results:
needs: test
runs-on: ubuntu-latest
steps:
- name: Report results
run: echo "All test shards passed!"
undefinedname: 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 }}/4merge-results:
needs: test
runs-on: ubuntu-latest
steps:
- name: Report results
run: echo "All test shards passed!"
undefinedMatrix Testing
矩阵测试
yaml
undefinedyaml
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
undefinedname: 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
undefinedDatabase Integration
数据库集成
Supabase in CI
CI中的Supabase
yaml
undefinedyaml
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 }}undefinedname: 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 }}undefinedRelease Automation
发布自动化
Automated Releases
自动发布
yaml
undefinedyaml
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 }}undefinedname: 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 }}undefinedChangelog Generation
变更日志生成
yaml
undefinedyaml
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.mdundefinedname: 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.mdundefinedSecurity Scanning
安全扫描
Dependency & Code Scanning
依赖与代码扫描
yaml
undefinedyaml
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 }}
undefinedname: 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 }}
undefinedCaching Strategies
缓存策略
Effective Caching
高效缓存
yaml
undefinedyaml
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 buildundefinedname: 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 buildundefinedEnvironment Management
环境管理
Environment-Based Deployments
基于环境的部署
yaml
undefinedyaml
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 }}undefinedname: 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 }}undefinedWorkflow Optimization
工作流优化
Conditional Jobs
条件式任务
yaml
undefinedyaml
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
undefinedname: 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
undefinedNotification & Reporting
通知与报告
Slack Notifications
Slack通知
yaml
undefinedyaml
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
undefinedname: 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
undefinedPipeline 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流水线
- 优化缓慢的流水线
- 添加部署自动化
- 实现发布管理
- 配置安全扫描
- 设置基于环境的部署
- 创建预览环境