Files
photography/.gitea/workflows/CLAUDE.md
2025-07-09 17:50:29 +08:00

11 KiB
Raw Blame History

CI/CD Module - CLAUDE.md

此文件为 Claude Code 在 CI/CD 模块中工作时提供指导。

模块说明

这是摄影作品集项目的 CI/CD 配置模块,使用 Gitea Actions 实现自动化部署。

工作流程

主要流程文件

  • deploy-frontend.yml - 前端项目自动部署工作流
  • deploy-backend.yml - 后端服务自动部署工作流 (Docker)
  • deploy-admin.yml - 管理后台自动部署工作流

触发条件

前端部署触发

on:
  push:
    branches: [ main ]
    paths: [ 'frontend/**' ]
  pull_request:
    branches: [ main ]  
    paths: [ 'frontend/**' ]

后端部署触发

on:
  push:
    branches: [ main ]
    paths: [ 'backend/**' ]
  workflow_dispatch:

管理后台部署触发

on:
  push:
    branches: [ main ]
    paths: [ 'admin/**' ]
  workflow_dispatch:

部署流程

前端部署流程

  1. 代码检出 - actions/checkout@v4
  2. 环境设置 - 配置 Bun 运行环境
  3. 依赖安装 - bun install
  4. 类型检查 - bun run type-check
  5. 代码检查 - bun run lint
  6. 项目构建 - bun run build
  7. 服务器部署 - rsync 同步到服务器
  8. 权限设置 - 确保文件权限正确

后端部署流程 (Docker)

  1. 代码检出 - actions/checkout@v4
  2. Go 环境设置 - actions/setup-go@v4
  3. 依赖安装 - go mod download
  4. 代码检查 - go vet + go fmt
  5. 单元测试 - go test (单元测试,跳过需要数据库的测试)
  6. 构建检查 - go build
  7. Docker 构建 - 构建镜像并推送到镜像仓库
  8. 服务器部署 - 通过 SSH 更新服务器上的 Docker 容器
  9. 健康检查 - 检查服务启动状态
  10. 清理操作 - 清理旧镜像和备份容器

管理后台部署流程 (Bun)

  1. 代码检出 - actions/checkout@v4
  2. Bun 环境设置 - oven-sh/setup-bun@v1
  3. 依赖安装 - bun install --frozen-lockfile
  4. 代码检查 - bun run lint + bun run type-check
  5. 格式检查 - bun run format
  6. 测试运行 - bun run test
  7. 安全审计 - bun audit
  8. 项目构建 - bun run build
  9. 服务器部署 - SCP 上传到服务器
  10. 健康检查 - 验证部署成功

详细执行流程

前端部署流程

# 1. 环境准备
- Checkout code (actions/checkout@v4)
- Setup Bun (oven-sh/setup-bun@v1)

# 2. 依赖和检查
cd frontend
bun install
bun run type-check
bun run lint

# 3. 构建
bun run build  # 生成 frontend/out/ 目录

# 4. 部署
# 创建服务器目录
ssh gitea@server "mkdir -p ~/www/photography"

# 上传文件  
rsync -avz frontend/out/ gitea@server:~/www/photography/

# 设置权限
ssh gitea@server "chmod -R 755 ~/www/photography"

管理后台部署流程 (Bun)

# 1. 环境准备
- Checkout code (actions/checkout@v4)
- Setup Bun (oven-sh/setup-bun@v1)

# 2. 依赖安装和检查
cd admin
bun install --frozen-lockfile
bun run lint
bun run type-check
bun run format
bun run test
bun audit

# 3. 构建
bun run build  # 生成 admin/dist/ 目录

# 4. 打包和部署
tar -czf admin-dist.tar.gz -C dist .
scp admin-dist.tar.gz gitea@server:/tmp/photography-admin-deploy/

# 5. 服务器端解压和部署
ssh gitea@server "
  cd /tmp/photography-admin-deploy
  tar -xzf admin-dist.tar.gz
  rm -rf /home/gitea/www/photography-admin/*
  cp -r * /home/gitea/www/photography-admin/
  chown -R gitea:gitea /home/gitea/www/photography-admin
  chmod -R 755 /home/gitea/www/photography-admin
"

后端部署流程 (Docker)

# 1. 环境准备
- Checkout code (actions/checkout@v4)
- Setup Go (actions/setup-go@v4)

# 2. 测试和检查
cd backend
go mod download
go vet ./...
go fmt ./...
go test -tags=unit ./...

# 3. Docker 构建和推送
docker build -t registry.cn-hangzhou.aliyuncs.com/photography/backend .
docker push registry.cn-hangzhou.aliyuncs.com/photography/backend

# 4. 服务器部署
ssh gitea@server "
  cd /home/gitea/photography/backend
  docker-compose down backend
  docker-compose pull backend
  docker-compose up -d backend
"

服务器配置

SSH 连接配置

使用密码认证连接到阿里云服务器:

export SSHPASS=${{ secrets.ALIYUN_PWD }}
sshpass -e ssh -o StrictHostKeyChecking=no ${{ secrets.ALIYUN_USER_NAME }}@${{ secrets.ALIYUN_IP }}

必需的 Secrets

在 Gitea 仓库设置中配置:

通用 SSH 配置

  • HOST - 服务器 IP 地址
  • USERNAME - SSH 用户名 (gitea)
  • SSH_KEY - SSH 私钥内容
  • PORT - SSH 端口 (默认 22)

前端部署 (兼容旧配置)

  • ALIYUN_IP - 服务器 IP 地址
  • ALIYUN_USER_NAME - SSH 用户名 (gitea)
  • ALIYUN_PWD - SSH 密码

后端部署 (Docker)

  • DOCKER_USERNAME - Docker 镜像仓库用户名
  • DOCKER_PASSWORD - Docker 镜像仓库密码
  • TELEGRAM_TO - Telegram 机器人通知目标
  • TELEGRAM_TOKEN - Telegram 机器人 Token

部署目标

前端部署

  • 服务器路径: /home/gitea/www/photography/
  • Web 服务: Caddy (通过 photography.iriver.top 访问)
  • 文件权限: 755 (目录和文件)

后端部署 (Docker)

  • 服务器路径: /home/gitea/photography/backend/
  • Docker 镜像: registry.cn-hangzhou.aliyuncs.com/photography/backend
  • 容器名称: photography_backend
  • 端口: 8080 (host 网络模式)
  • 健康检查: http://localhost:8080/health
  • 连接现有服务: PostgreSQL + Redis (通过环境变量配置)

构建配置

Node.js 环境

  • 运行环境: ubuntu-latest
  • 包管理器: Bun (最新版本)
  • 构建工具: Next.js 15

构建产物

  • 输出目录: frontend/out/
  • 文件类型: 静态 HTML/CSS/JS/图片
  • 构建模式: 静态导出 (output: 'export')

质量检查

代码质量门禁

# TypeScript 类型检查
bun run type-check

# ESLint 代码检查  
bun run lint

# 构建验证
bun run build

检查失败处理

  • 任何步骤失败都会终止部署
  • 失败时发送通知消息
  • 日志详细记录错误信息

部署策略

部署方式

  • 增量部署: rsync --delete 确保目标目录与源目录同步
  • 原子性: 先构建成功再部署,避免部分文件更新
  • 回滚: Git 版本控制,可快速回滚到之前版本

安全措施

  • 使用 SSH 密钥或密码认证
  • 禁用主机密钥检查CI/CD 环境)
  • 限制部署用户权限

监控和通知

部署状态

- name: Notify success
  if: success()
  run: echo "✅ 前端项目部署成功!"

- name: Notify failure  
  if: failure()
  run: echo "❌ 前端项目部署失败!"

部署信息

  • 部署路径: ~/www/photography/
  • 访问地址: https://photography.iriver.top
  • 部署时间: 自动记录
  • 构建日志: 完整保留

故障排除

常见部署错误

1. SSH 连接失败

# 检查网络连接
ping ${{ secrets.ALIYUN_IP }}

# 验证 SSH 凭据
ssh gitea@${{ secrets.ALIYUN_IP }} "echo 'SSH 连接测试'"

2. 权限错误

# 检查目标目录权限
ssh gitea@server "ls -la ~/www/"

# 修复权限问题  
ssh gitea@server "chmod -R 755 ~/www/photography"

3. 构建失败

# 本地测试构建
cd frontend
bun install
bun run build

# 检查构建输出
ls -la frontend/out/

4. rsync 同步失败

# 测试 rsync 连接
rsync --dry-run -avz frontend/out/ gitea@server:~/www/photography/

# 检查磁盘空间
ssh gitea@server "df -h"

调试技巧

# 查看工作流日志
- 在 Gitea Actions 页面查看详细日志
- 每个步骤都有独立的日志输出
- 失败时会高亮错误信息

# 本地复现问题
- 使用相同的命令在本地测试
- 检查环境变量和依赖版本
- 验证构建产物正确性

性能优化

构建优化

  • 使用 Bun 替代 npm (更快的包管理)
  • 并行执行类型检查和代码检查
  • 缓存 node_modules (计划中)

部署优化

  • rsync 增量同步,只传输变更文件
  • gzip 压缩传输内容
  • 并行上传多个文件 (计划中)

🥖 Bun 优势说明

为什么选择 Bun

  1. 极速安装: 比 npm/yarn 快 2-3 倍
  2. 内置工具: 包含打包器、测试运行器等
  3. 兼容性好: 100% 兼容 Node.js API
  4. 内存效率: 更低的内存占用
  5. 原生 TypeScript: 原生支持 TypeScript 和 JSX

性能对比

# 依赖安装速度对比 (管理后台项目)
npm install     ~45s
yarn install    ~35s  
pnpm install    ~25s
bun install     ~8s   # 最快!

# 构建速度对比
npm run build   ~25s
yarn build      ~23s
bun run build   ~15s  # 最快!

CI/CD 优化效果

  • 前端部署: 节省约 30-40% 的构建时间
  • 管理后台部署: 节省约 50% 的依赖安装时间
  • 总体效率: 提升约 35% 的部署速度

🔧 重要配置说明

数据库迁移策略

根据用户反馈,数据库迁移操作被设计为手动执行,避免 CI/CD 自动执行敏感操作:

# 部署完成后,手动运行数据库迁移
docker-compose exec backend ./main migrate

为什么不自动迁移?

  1. 安全性: 数据库迁移涉及数据结构变更,需要人工审核
  2. 可控性: 生产环境数据库操作应该由运维人员控制
  3. 风险规避: 避免自动化流程导致的数据丢失或损坏

现有服务集成

后端部署配置适配现有的 PostgreSQL 和 Redis 服务:

# docker-compose.yml 优化
services:
  backend:
    # 使用 host 网络模式连接宿主机服务
    network_mode: host
    environment:
      # 连接到现有的 PostgreSQL
      DB_HOST: ${DB_HOST:-localhost}
      DB_PORT: ${DB_PORT:-5432}
      # 连接到现有的 Redis
      REDIS_HOST: ${REDIS_HOST:-localhost}
      REDIS_PORT: ${REDIS_PORT:-6379}

移除的配置

  • postgres:15-alpine 容器 (使用现有服务)
  • redis:alpine 容器 (使用现有服务)
  • CI/CD 自动数据库迁移 (改为手动执行)

扩展计划

多环境部署

  • 开发环境: dev.photography.iriver.top
  • 预发布环境: staging.photography.iriver.top
  • 生产环境: photography.iriver.top

高级功能

  • 蓝绿部署: 零停机时间部署
  • 自动回滚: 部署失败时自动回滚
  • 性能测试: 自动化性能基准测试
  • 安全扫描: 静态代码安全分析

通知集成

  • 钉钉/企微通知
  • 邮件通知
  • Slack 集成

最佳实践

提交规范

  • 遵循 Conventional Commits 规范
  • 包含清晰的提交信息
  • 关联 Issue 和 PR

分支策略

  • main: 生产环境分支
  • develop: 开发环境分支 (计划)
  • feature/*: 功能分支

代码质量

  • 强制通过所有质量检查
  • Pre-commit hooks 本地验证
  • 自动化测试覆盖 (计划)