CI/CD 自动化部署
持续集成和持续部署(CI/CD)可以帮助你自动化构建和部署流程,提高开发效率。本文将介绍几种常用的 CI/CD 配置方案。
GitHub Actions
基础配置
创建 .github/workflows/deploy.yml:
yaml
name: Deploy VitePress site to Pages
on:
push:
branches: [main]
workflow_dispatch:
permissions:
contents: read
pages: write
id-token: write
concurrency:
group: pages
cancel-in-progress: false
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Setup Node
uses: actions/setup-node@v4
with:
node-version: 20
cache: npm
- name: Setup Pages
uses: actions/configure-pages@v4
- name: Install dependencies
run: npm ci
- name: Build with VitePress
run: npm run docs:build
- name: Upload artifact
uses: actions/upload-pages-artifact@v3
with:
path: docs/.vitepress/dist
deploy:
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
needs: build
runs-on: ubuntu-latest
steps:
- name: Deploy to GitHub Pages
id: deployment
uses: actions/deploy-pages@v4带 PR 预览的配置
yaml
name: Deploy VitePress site
on:
push:
branches: [main]
pull_request:
branches: [main]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup Node
uses: actions/setup-node@v4
with:
node-version: 20
cache: npm
- name: Install
run: npm ci
- name: Build
run: npm run docs:build
- name: Upload artifact
uses: actions/upload-artifact@v4
with:
name: dist
path: docs/.vitepress/dist
deploy-production:
if: github.event_name == 'push'
needs: build
runs-on: ubuntu-latest
steps:
- name: Download artifact
uses: actions/download-artifact@v4
with:
name: dist
- name: Deploy
uses: peaceiris/actions-gh-pages@v3
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
publish_dir: .
preview-pr:
if: github.event_name == 'pull_request'
needs: build
runs-on: ubuntu-latest
steps:
- name: Download artifact
uses: actions/download-artifact@v4
with:
name: dist
- name: Deploy Preview
uses: rossjrw/pr-preview-action@v1
with:
source-dir: .Vercel 部署
自动部署
Vercel 原生支持 VitePress:
- 导入 GitHub 仓库
- Vercel 自动检测 VitePress
- 配置构建命令和输出目录
| 配置项 | 值 |
|---|---|
| Build Command | npm run docs:build |
| Output Directory | docs/.vitepress/dist |
| Install Command | npm install |
vercel.json 配置
json
{
"buildCommand": "npm run docs:build",
"outputDirectory": "docs/.vitepress/dist",
"framework": "vitepress",
"rewrites": [
{ "source": "/api/(.*)", "destination": "/api/$1" }
],
"headers": [
{
"source": "/(.*)",
"headers": [
{ "key": "X-Content-Type-Options", "value": "nosniff" },
{ "key": "X-Frame-Options", "value": "DENY" }
]
}
]
}Netlify 部署
netlify.toml 配置
toml
[build]
command = "npm run docs:build"
publish = "docs/.vitepress/dist"
[build.environment]
NODE_VERSION = "20"
[[redirects]]
from = "/*"
to = "/index.html"
status = 200
[[headers]]
for = "/*"
[headers.values]
X-Frame-Options = "DENY"
X-XSS-Protection = "1; mode=block"
X-Content-Type-Options = "nosniff"Netlify Functions 示例
javascript
// netlify/functions/api.js
export async function handler(event, context) {
return {
statusCode: 200,
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
message: 'Hello from Netlify Functions!'
})
}
}Cloudflare Pages 部署
构建配置
| 配置项 | 值 |
|---|---|
| Build command | npm run docs:build |
| Build output directory | docs/.vitepress/dist |
| Node version | 20 (环境变量设置) |
wrangler.toml 配置
toml
name = "vitepress-site"
compatibility_date = "2024-01-01"
pages_build_output_dir = "docs/.vitepress/dist"
[vars]
NODE_VERSION = "20"自建服务器部署
Docker 部署
创建 Dockerfile:
dockerfile
FROM node:20-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run docs:build
FROM nginx:alpine
COPY --from=builder /app/docs/.vitepress/dist /usr/share/nginx/html
COPY nginx.conf /etc/nginx/nginx.conf
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]nginx.conf 配置
nginx
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
server {
listen 80;
server_name localhost;
root /usr/share/nginx/html;
index index.html;
# SPA 路由支持
location / {
try_files $uri $uri/ /index.html;
}
# 静态资源缓存
location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2)$ {
expires 1y;
add_header Cache-Control "public, immutable";
}
# Gzip 压缩
gzip on;
gzip_types text/plain text/css application/json application/javascript text/xml application/xml;
gzip_min_length 1000;
}
}Docker Compose 部署
yaml
version: '3.8'
services:
vitepress:
build: .
ports:
- "80:80"
restart: unless-stopped缓存优化
GitHub Actions 缓存
yaml
- name: Cache dependencies
uses: actions/cache@v4
with:
path: |
~/.npm
node_modules
key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
restore-keys: |
${{ runner.os }}-node-构建产物缓存
yaml
- name: Cache VitePress
uses: actions/cache@v4
with:
path: |
docs/.vitepress/cache
docs/.vitepress/dist
key: vitepress-${{ github.sha }}
restore-keys: |
vitepress-部署通知
Slack 通知
yaml
- name: Notify Slack
if: always()
uses: 8398a7/action-slack@v3
with:
status: ${{ job.status }}
fields: repo,message,commit,author
env:
SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK }}邮件通知
yaml
- name: Send email
if: failure()
uses: dawidd6/action-send-mail@v3
with:
server_address: smtp.gmail.com
server_port: 465
username: ${{ secrets.EMAIL_USERNAME }}
password: ${{ secrets.EMAIL_PASSWORD }}
subject: Build Failed
to: your-email@example.com
from: CI/CD Bot
body: |
Build failed for ${{ github.repository }}
Commit: ${{ github.sha }}
Author: ${{ github.actor }}部署检查清单
构建前检查
- [ ] 代码已通过测试
- [ ] 代码已通过 Lint 检查
- [ ] 依赖版本已锁定
- [ ] 环境变量已配置
构建后检查
- [ ] 构建产物正确
- [ ] 页面可正常访问
- [ ] 静态资源加载正常
- [ ] 路由跳转正常
部署后检查
- [ ] 网站可访问
- [ ] HTTPS 证书有效
- [ ] CDN 缓存已刷新
- [ ] 监控告警正常
最佳实践
1. 分环境部署
main 分支 -> 生产环境
develop 分支 -> 测试环境
PR -> 预览环境2. 回滚机制
yaml
- name: Rollback on failure
if: failure()
run: |
# 回滚到上一个稳定版本
echo "Rolling back..."3. 自动化测试
yaml
- name: Run tests
run: npm test
- name: Run e2e tests
run: npm run test:e2e自动化优势
使用 CI/CD 可以减少人为错误,确保每次部署的一致性和可靠性。