1. 选择 CI/CD 工具
常见的前端 CI/CD 工具选择:
- GitHub Actions (与 GitHub 深度集成)
- GitLab CI/CD (与 GitLab 深度集成)
- Jenkins (自托管,高度可定制)
- CircleCI (云服务)
- Travis CI (云服务)
2. 基础 CI/CD 流程设计
典型的前端 CI/CD 流程包括以下阶段:
- 代码提交 → 2. 自动构建 → 3. 代码检查 → 4. 自动化测试 → 5. 部署
3. 使用 GitHub Actions 示例
一、前期准备
-
项目要求
- 代码托管在 GitHub 仓库
- 项目根目录有
package.json
文件 - 有基本的构建脚本 (如
npm run build
)
-
环境准备
- 在项目根目录创建
.github/workflows
文件夹 - 准备部署目标的相关凭据 (如需)
- 在项目根目录创建
二、基础 CI/CD 配置文件
创建 .github/workflows/main.yml
文件:
yaml
name: Frontend CI/CD Pipeline
on:
push:
branches: [ main, develop ] # 监听 main 和 develop 分支的推送
pull_request:
branches: [ main ] # PR 到 main 分支时触发
env:
NODE_VERSION: '18.x' # 统一 Node.js 版本
jobs:
# 第一个 job:代码检查和测试
lint-and-test:
name: Lint & Test
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3 # 检出代码
- name: Setup Node.js
uses: actions/setup-node@v3
with:
node-version: ${{ env.NODE_VERSION }}
cache: 'npm' # 启用 npm 缓存
- name: Install dependencies
run: npm ci # 使用 ci 而不是 install 保证依赖一致
- name: Run ESLint
run: npm run lint
- name: Run unit tests
run: npm test
- name: Upload test coverage
uses: codecov/codecov-action@v3
with:
token: ${{ secrets.CODECOV_TOKEN }} # 可选:上传测试覆盖率到 Codecov
# 第二个 job:构建和部署
build-and-deploy:
name: Build & Deploy
needs: lint-and-test # 依赖 lint-and-test 成功
runs-on: ubuntu-latest
if: github.ref == 'refs/heads/main' || github.ref == 'refs/heads/develop'
steps:
- uses: actions/checkout@v3
- name: Setup Node.js
uses: actions/setup-node@v3
with:
node-version: ${{ env.NODE_VERSION }}
- name: Install dependencies
run: npm ci
- name: Build project
run: npm run build
- name: Archive production artifacts
uses: actions/upload-artifact@v3
with:
name: build-artifacts
path: dist/ # 假设构建输出在 dist 目录
- name: Deploy to Staging
if: github.ref == 'refs/heads/develop'
run: npm run deploy:staging
env:
DEPLOY_TOKEN: ${{ secrets.STAGING_DEPLOY_TOKEN }}
- name: Deploy to Production
if: github.ref == 'refs/heads/main'
run: npm run deploy:production
env:
DEPLOY_TOKEN: ${{ secrets.PROD_DEPLOY_TOKEN }}
三、详细配置说明
1. 触发条件 (on)
yaml
on:
push:
branches: [ main, develop ] # 指定触发分支
tags: [ 'v*' ] # 可选:标签推送触发
pull_request:
branches: [ main ] # PR 到 main 时触发
schedule: # 可选:定时触发
- cron: '0 0 * * *' # 每天 UTC 午夜
2. 环境变量管理
yaml
env:
NODE_VERSION: '18.x'
BUILD_DIR: 'dist'
jobs:
deploy:
env:
API_BASE_URL: ${{ secrets.API_BASE_URL }}
3. 矩阵构建 (多环境测试)
yaml
jobs:
test:
strategy:
matrix:
node-version: ['16.x', '18.x', '20.x']
os: [ubuntu-latest, windows-latest]
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v3
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v3
with:
node-version: ${{ matrix.node-version }}
4. 缓存优化
yaml
- name: Cache node modules
uses: actions/cache@v3
id: cache
with:
path: |
node_modules
.next/cache
key: ${{ runner.os }}-${{ hashFiles('**/package-lock.json') }}
5. 人工审核 (生产部署)
yaml
- name: Wait for manual approval
uses: trstringer/manual-approval@v1
with:
secret: ${{ github.token }}
approvers: 'team-lead,product-owner'
minimum-approvals: 1
四、部署到不同平台的配置示例
1. 部署到 GitHub Pages
yaml
- name: Deploy to GitHub Pages
uses: peaceiris/actions-gh-pages@v3
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
publish_dir: ./dist
keep_files: true # 保留历史文件
2. 部署到 AWS S3 + CloudFront
yaml
- name: Configure AWS Credentials
uses: aws-actions/configure-aws-credentials@v2
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
aws-region: us-east-1
- name: Deploy to S3
run: |
aws s3 sync ./dist s3://your-bucket-name --delete
aws cloudfront create-invalidation \
--distribution-id ${{ secrets.CF_DISTRIBUTION_ID }} \
--paths "/*"
3. 部署到 Vercel
yaml
- name: Install Vercel CLI
run: npm install -g vercel@latest
- name: Deploy to Vercel
run: vercel --prod --token ${{ secrets.VERCEL_TOKEN }}
env:
VERCEL_ORG_ID: ${{ secrets.VERCEL_ORG_ID }}
VERCEL_PROJECT_ID: ${{ secrets.VERCEL_PROJECT_ID }}
五、完整高级示例
yaml
name: Advanced Frontend CI/CD
on:
push:
branches: [ main, develop ]
tags: [ 'v*' ]
pull_request:
branches: [ main ]
workflow_dispatch: # 允许手动触发
inputs:
environment:
description: 'Deploy environment'
required: true
default: 'staging'
type: choice
options:
- staging
- production
env:
NODE_VERSION: '18.x'
BUILD_DIR: 'dist'
jobs:
setup:
runs-on: ubuntu-latest
outputs:
should_deploy: ${{ steps.check-ref.outputs.should_deploy }}
steps:
- name: Check branch/tag
id: check-ref
run: |
if [[ $GITHUB_REF == refs/heads/main || $GITHUB_REF == refs/heads/develop || $GITHUB_REF == refs/tags/v* ]]; then
echo "should_deploy=true" >> $GITHUB_OUTPUT
else
echo "should_deploy=false" >> $GITHUB_OUTPUT
fi
lint-test:
needs: setup
if: ${{ needs.setup.outputs.should_deploy == 'true' }}
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Setup Node.js
uses: actions/setup-node@v3
with:
node-version: ${{ env.NODE_VERSION }}
- name: Cache dependencies
uses: actions/cache@v3
with:
path: node_modules
key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
restore-keys: |
${{ runner.os }}-node-
- name: Install dependencies
run: npm ci
- name: Run linter
run: npm run lint
- name: Run tests
run: npm test -- --coverage
- name: Upload coverage
uses: codecov/codecov-action@v3
build:
needs: lint-test
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Setup Node.js
uses: actions/setup-node@v3
with:
node-version: ${{ env.NODE_VERSION }}
- name: Install dependencies
run: npm ci
- name: Build project
run: npm run build
- name: Upload artifacts
uses: actions/upload-artifact@v3
with:
name: build-output
path: ${{ env.BUILD_DIR }}
deploy:
needs: build
runs-on: ubuntu-latest
environment:
name: ${{ github.event.inputs.environment || (github.ref == 'refs/heads/main' && 'production') || 'staging' }}
url: ${{ steps.deploy.outputs.deployment_url }}
steps:
- name: Download artifacts
uses: actions/download-artifact@v3
with:
name: build-output
path: ${{ env.BUILD_DIR }}
- name: Deploy to environment
id: deploy
run: |
if [ "${{ github.event.inputs.environment || (github.ref == 'refs/heads/main' && 'production') || 'staging' }}" == "production" ]; then
npm run deploy:production
echo "deployment_url=https://production.example.com" >> $GITHUB_OUTPUT
else
npm run deploy:staging
echo "deployment_url=https://staging.example.com" >> $GITHUB_OUTPUT
fi
六、最佳实践建议
-
分阶段执行:将流程分为 lint/test/build/deploy 等独立阶段
-
失败快速:将最容易失败的步骤放在前面
-
缓存优化:缓存 node_modules 和构建缓存
-
环境隔离:严格区分 staging 和 production 环境
-
安全防护:
- 使用 GitHub Secrets 存储敏感信息
- 生产部署添加人工审批
-
监控通知:
- 集成 Slack/Teams 通知
- 失败时自动通知相关人员
-
定期清理:设置 artifacts 和 cache 的保留策略
通过以上配置,你可以建立一个健壮、高效的前端 CI/CD 流程,实现从代码提交到自动化部署的完整链路。