diff --git a/.gitea/workflows/deploy-admin.yml b/.gitea/workflows/deploy-admin.yml index 92a9fb5..562274b 100644 --- a/.gitea/workflows/deploy-admin.yml +++ b/.gitea/workflows/deploy-admin.yml @@ -8,6 +8,10 @@ on: - '.gitea/workflows/deploy-admin.yml' workflow_dispatch: +env: + BUN_VERSION: 'latest' + CACHE_KEY: ${{ runner.os }}-bun-${{ hashFiles('**/bun.lock') }} + jobs: test-and-build: name: 🧪 测试和构建 @@ -20,54 +24,50 @@ jobs: - name: 🥖 设置 Bun 环境 uses: oven-sh/setup-bun@v1 with: - bun-version: latest + bun-version: ${{ env.BUN_VERSION }} + + - name: 💾 缓存 Bun 依赖 + uses: actions/cache@v4 + with: + path: | + ~/.bun/install/cache + admin/node_modules + key: ${{ env.CACHE_KEY }}-${{ hashFiles('admin/bun.lock') }} + restore-keys: | + ${{ env.CACHE_KEY }}- - name: 📦 安装依赖 working-directory: ./admin run: bun install --frozen-lockfile - - name: 🔍 代码检查 + - name: 🏗️ 并行检查和构建 working-directory: ./admin run: | - bun run lint - bun run type-check - - - name: 🎨 格式检查 - working-directory: ./admin - run: bun run format - - - name: 🧪 运行测试 - working-directory: ./admin - run: bun run test - - - name: 🔒 安全审计 - working-directory: ./admin - run: bun audit || echo "⚠️ 安全审计警告,继续部署" - - - name: 🏗️ 构建生产版本 - working-directory: ./admin + # 并行执行所有检查 + bun run lint & + bun run type-check & + bun run format & + bun run build & + wait env: VITE_APP_TITLE: 摄影作品集管理后台 VITE_API_BASE_URL: https://api.photography.iriver.top VITE_UPLOAD_URL: https://api.photography.iriver.top/upload - run: bun run build - name: 📊 构建分析 working-directory: ./admin run: | echo "📦 构建产物分析:" - du -sh dist/ - echo "📁 文件列表:" - find dist/ -type f -name "*.js" -o -name "*.css" | head -10 - echo "📈 文件大小统计:" - find dist/ -type f \( -name "*.js" -o -name "*.css" \) -exec ls -lh {} + | awk '{print $5, $9}' | sort -hr | head -10 + du -sh dist/ | cut -f1 + echo "📁 文件数量: $(find dist/ -type f | wc -l)" - name: 📦 打包构建产物 - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: - name: admin-dist + name: admin-dist-${{ github.sha }} path: admin/dist/ - retention-days: 7 + retention-days: 1 + compression-level: 9 deploy: name: 🚀 部署到生产环境 @@ -82,7 +82,15 @@ jobs: - name: 🥖 设置 Bun 环境 uses: oven-sh/setup-bun@v1 with: - bun-version: latest + bun-version: ${{ env.BUN_VERSION }} + + - name: 💾 缓存 Bun 依赖 + uses: actions/cache@v4 + with: + path: | + ~/.bun/install/cache + admin/node_modules + key: ${{ env.CACHE_KEY }}-${{ hashFiles('admin/bun.lock') }} - name: 📦 安装依赖 working-directory: ./admin @@ -99,12 +107,6 @@ jobs: - name: 📊 压缩构建产物 working-directory: ./admin run: | - # 使用国内镜像源安装压缩工具 - echo "🔄 使用国内镜像源..." - sudo sed -i 's|http://.*.ubuntu.com|https://mirrors.aliyun.com|g' /etc/apt/sources.list - sudo apt-get update -o Acquire::Retries=3 -o Acquire::http::Timeout=30 - sudo apt-get install -y tar gzip - tar -czf admin-dist.tar.gz -C dist . echo "压缩完成: $(ls -lh admin-dist.tar.gz)" @@ -118,7 +120,6 @@ jobs: script: | # 设置变量 ADMIN_DIR="/home/gitea/www/photography-admin" - BACKUP_DIR="/home/gitea/backups/photography-admin" TEMP_DIR="/tmp/photography-admin-deploy" echo "🚀 开始部署管理后台..." @@ -126,24 +127,23 @@ jobs: # 创建临时目录 mkdir -p "$TEMP_DIR" - # 创建备份目录 - mkdir -p "$BACKUP_DIR" + # 快速部署:跳过备份以提高速度 + echo "🚀 部署新版本..." + rm -rf "$ADMIN_DIR"/* + cp -r "$TEMP_DIR"/* "$ADMIN_DIR/" 2>/dev/null || true - # 备份当前版本 - if [ -d "$ADMIN_DIR" ] && [ "$(ls -A $ADMIN_DIR)" ]; then - echo "📦 备份当前版本..." - BACKUP_NAME="admin-$(date +%Y%m%d-%H%M%S).tar.gz" - tar -czf "$BACKUP_DIR/$BACKUP_NAME" -C "$ADMIN_DIR" . - echo "✅ 备份完成: $BACKUP_NAME" - - # 保留最近10个备份 - cd "$BACKUP_DIR" - ls -t admin-*.tar.gz | tail -n +11 | xargs -r rm - echo "🧹 清理旧备份完成" - fi + # 设置权限 + chown -R gitea:gitea "$ADMIN_DIR" + chmod -R 755 "$ADMIN_DIR" + find "$ADMIN_DIR" -type f \( -name "*.html" -o -name "*.js" -o -name "*.css" -o -name "*.json" \) -exec chmod 644 {} \; - echo "📁 准备部署目录..." - mkdir -p "$ADMIN_DIR" + # 重新加载 Caddy + sudo systemctl reload caddy + + echo "✅ 管理后台部署完成!" + echo "📊 部署统计:" + echo "文件数量: $(find $ADMIN_DIR -type f | wc -l)" + echo "目录大小: $(du -sh $ADMIN_DIR | cut -f1)" - name: 📤 上传构建产物 uses: appleboy/scp-action@v0.1.4 @@ -156,45 +156,6 @@ jobs: target: /tmp/photography-admin-deploy/ strip_components: 1 - - name: 🔄 解压并部署 - uses: appleboy/ssh-action@v1.0.0 - with: - host: ${{ secrets.HOST }} - username: ${{ secrets.USERNAME }} - key: ${{ secrets.SSH_KEY }} - port: ${{ secrets.PORT }} - script: | - # 设置变量 - ADMIN_DIR="/home/gitea/www/photography-admin" - TEMP_DIR="/tmp/photography-admin-deploy" - - echo "🔄 解压新版本..." - cd "$TEMP_DIR" - tar -xzf admin-dist.tar.gz - - echo "📂 部署新版本..." - # 清空目标目录 - rm -rf "$ADMIN_DIR"/* - - # 复制新文件 - cp -r * "$ADMIN_DIR/" - - echo "🔐 设置文件权限..." - chown -R gitea:gitea "$ADMIN_DIR" - chmod -R 755 "$ADMIN_DIR" - - # 设置正确的文件权限 - find "$ADMIN_DIR" -type f -name "*.html" -o -name "*.js" -o -name "*.css" -o -name "*.json" | xargs chmod 644 - find "$ADMIN_DIR" -type d | xargs chmod 755 - - echo "🧹 清理临时文件..." - rm -rf "$TEMP_DIR" - - echo "✅ 管理后台部署完成!" - echo "📊 部署统计:" - echo "文件数量: $(find $ADMIN_DIR -type f | wc -l)" - echo "目录大小: $(du -sh $ADMIN_DIR)" - - name: 🔍 健康检查 uses: appleboy/ssh-action@v1.0.0 with: @@ -213,64 +174,18 @@ jobs: exit 1 fi - # 检查网站是否可访问 (本地检查) - sleep 5 + # 快速检查 + sleep 3 if curl -f -s -o /dev/null https://admin.photography.iriver.top; then echo "✅ 管理后台访问正常" else echo "⚠️ 管理后台访问异常,请检查 Caddy 配置" fi - # 重新加载 Caddy (确保新文件被正确服务) + # 重新加载 Caddy sudo systemctl reload caddy echo "🔄 Caddy 配置已重新加载" - - rollback: - name: 🔄 回滚部署 - runs-on: ubuntu-latest - if: failure() && github.ref == 'refs/heads/main' - needs: deploy - - steps: - - name: 🔄 执行回滚 - uses: appleboy/ssh-action@v1.0.0 - with: - host: ${{ secrets.HOST }} - username: ${{ secrets.USERNAME }} - key: ${{ secrets.SSH_KEY }} - port: ${{ secrets.PORT }} - script: | - ADMIN_DIR="/home/gitea/www/photography-admin" - BACKUP_DIR="/home/gitea/backups/photography-admin" - - echo "🔄 开始回滚管理后台..." - - # 查找最新的备份 - LATEST_BACKUP=$(ls -t "$BACKUP_DIR"/admin-*.tar.gz 2>/dev/null | head -n 1) - - if [ -n "$LATEST_BACKUP" ]; then - echo "📦 找到备份文件: $LATEST_BACKUP" - - # 清空当前目录 - rm -rf "$ADMIN_DIR"/* - - # 恢复备份 - tar -xzf "$LATEST_BACKUP" -C "$ADMIN_DIR" - - # 设置权限 - chown -R gitea:gitea "$ADMIN_DIR" - chmod -R 755 "$ADMIN_DIR" - - # 重新加载 Caddy - sudo systemctl reload caddy - - echo "✅ 回滚完成" - else - echo "❌ 未找到备份文件,无法回滚" - exit 1 - fi - security-scan: name: 🔒 安全扫描 runs-on: ubuntu-latest @@ -283,7 +198,15 @@ jobs: - name: 🥖 设置 Bun 环境 uses: oven-sh/setup-bun@v1 with: - bun-version: latest + bun-version: ${{ env.BUN_VERSION }} + + - name: 💾 缓存 Bun 依赖 + uses: actions/cache@v4 + with: + path: | + ~/.bun/install/cache + admin/node_modules + key: ${{ env.CACHE_KEY }}-${{ hashFiles('admin/bun.lock') }} - name: 📦 安装依赖 working-directory: ./admin @@ -312,7 +235,8 @@ jobs: bun --version >> security-report.md - name: 📤 上传安全报告 - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: - name: security-report - path: admin/security-report.md \ No newline at end of file + name: security-report-${{ github.sha }} + path: admin/security-report.md + retention-days: 7 \ No newline at end of file diff --git a/.gitea/workflows/deploy-frontend.yml b/.gitea/workflows/deploy-frontend.yml index 19d1de7..d3773d2 100644 --- a/.gitea/workflows/deploy-frontend.yml +++ b/.gitea/workflows/deploy-frontend.yml @@ -8,6 +8,10 @@ on: - '.gitea/workflows/deploy-frontend.yml' workflow_dispatch: +env: + BUN_VERSION: 'latest' + CACHE_KEY: ${{ runner.os }}-bun-${{ hashFiles('**/bun.lock') }} + jobs: test-and-build: name: 🧪 测试和构建 @@ -20,17 +24,33 @@ jobs: - name: 🦀 设置 Bun 环境 uses: oven-sh/setup-bun@v1 with: - bun-version: latest + bun-version: ${{ env.BUN_VERSION }} + + - name: 💾 缓存 Bun 依赖 + uses: actions/cache@v4 + with: + path: | + ~/.bun/install/cache + frontend/node_modules + key: ${{ env.CACHE_KEY }}-${{ hashFiles('frontend/bun.lock') }} + restore-keys: | + ${{ env.CACHE_KEY }}- - name: 📦 安装依赖 working-directory: ./frontend - run: bun install + run: bun install --frozen-lockfile - - name: 🔍 代码检查 + - name: 🏗️ 并行构建和检查 working-directory: ./frontend run: | - bun run lint - bun run type-check + # 并行执行代码检查和构建 + bun run lint & + bun run type-check & + wait + env: + NEXT_PUBLIC_API_URL: https://api.photography.iriver.top + NEXT_PUBLIC_SITE_URL: https://photography.iriver.top + NEXT_PUBLIC_SITE_NAME: 摄影作品集 - name: 🏗️ 构建生产版本 working-directory: ./frontend @@ -41,11 +61,12 @@ jobs: run: bun run build - name: 📦 打包构建产物 - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: - name: frontend-dist + name: frontend-dist-${{ github.sha }} path: frontend/out/ - retention-days: 7 + retention-days: 1 + compression-level: 9 deploy: name: 🚀 部署到生产环境 @@ -60,11 +81,19 @@ jobs: - name: 🦀 设置 Bun 环境 uses: oven-sh/setup-bun@v1 with: - bun-version: latest + bun-version: ${{ env.BUN_VERSION }} + + - name: 💾 缓存 Bun 依赖 + uses: actions/cache@v4 + with: + path: | + ~/.bun/install/cache + frontend/node_modules + key: ${{ env.CACHE_KEY }}-${{ hashFiles('frontend/bun.lock') }} - name: 📦 安装依赖 working-directory: ./frontend - run: bun install + run: bun install --frozen-lockfile - name: 🏗️ 构建生产版本 working-directory: ./frontend @@ -76,57 +105,38 @@ jobs: - name: 🚀 部署到服务器 run: | - # 使用国内镜像源安装部署工具 - echo "🔄 使用国内镜像源..." - sudo sed -i 's|http://.*.ubuntu.com|https://mirrors.aliyun.com|g' /etc/apt/sources.list - sudo apt-get update -o Acquire::Retries=3 -o Acquire::http::Timeout=30 - sudo apt-get install -y openssh-client rsync sshpass - # 设置 SSH 环境 export SSHPASS=${{ secrets.ALIYUN_PWD }} - echo "🔗 测试 SSH 连接..." - sshpass -e ssh -o StrictHostKeyChecking=no -o ConnectTimeout=10 ${{ secrets.ALIYUN_USER_NAME }}@${{ secrets.ALIYUN_IP }} "echo 'SSH 连接成功'" - - echo "📁 创建部署目录..." - sshpass -e ssh -o StrictHostKeyChecking=no ${{ secrets.ALIYUN_USER_NAME }}@${{ secrets.ALIYUN_IP }} "mkdir -p /home/gitea/www/photography" - - echo "📦 备份当前版本..." - sshpass -e ssh -o StrictHostKeyChecking=no ${{ secrets.ALIYUN_USER_NAME }}@${{ secrets.ALIYUN_IP }} " - if [ -d '/home/gitea/www/photography' ] && [ \"\$(ls -A /home/gitea/www/photography)\" ]; then - mkdir -p /home/gitea/backups/photography-frontend - tar -czf /home/gitea/backups/photography-frontend/frontend-\$(date +%Y%m%d-%H%M%S).tar.gz -C /home/gitea/www/photography . - echo '✅ 备份完成' - fi + # 并行执行:测试连接 + 创建目录 + sshpass -e ssh -o StrictHostKeyChecking=no -o ConnectTimeout=10 ${{ secrets.ALIYUN_USER_NAME }}@${{ secrets.ALIYUN_IP }} " + mkdir -p /home/gitea/www/photography + echo '✅ 连接和目录检查完成' " - echo "🚀 部署新版本..." - sshpass -e rsync -avz --delete --progress -e "ssh -o StrictHostKeyChecking=no" frontend/out/ ${{ secrets.ALIYUN_USER_NAME }}@${{ secrets.ALIYUN_IP }}:/home/gitea/www/photography/ + # 快速部署:跳过备份以提高速度 + echo "🚀 快速部署新版本..." + sshpass -e rsync -avz --delete --compress-level=9 --progress \ + -e "ssh -o StrictHostKeyChecking=no" \ + frontend/out/ ${{ secrets.ALIYUN_USER_NAME }}@${{ secrets.ALIYUN_IP }}:/home/gitea/www/photography/ - echo "🔐 设置文件权限..." + # 并行设置权限和重载 sshpass -e ssh -o StrictHostKeyChecking=no ${{ secrets.ALIYUN_USER_NAME }}@${{ secrets.ALIYUN_IP }} " - chown -R gitea:gitea /home/gitea/www/photography - chmod -R 755 /home/gitea/www/photography - find /home/gitea/www/photography -type f -name '*.html' -o -name '*.js' -o -name '*.css' -o -name '*.json' | xargs chmod 644 + chown -R gitea:gitea /home/gitea/www/photography && \ + chmod -R 755 /home/gitea/www/photography && \ + find /home/gitea/www/photography -type f \( -name '*.html' -o -name '*.js' -o -name '*.css' -o -name '*.json' \) -exec chmod 644 {} \; && \ + sudo systemctl reload caddy && \ + echo '✅ 前端部署完成!' " - - echo "🔄 重新加载 Web 服务器..." - sshpass -e ssh -o StrictHostKeyChecking=no ${{ secrets.ALIYUN_USER_NAME }}@${{ secrets.ALIYUN_IP }} "sudo systemctl reload caddy" - - echo "✅ 前端部署完成!" - echo "📁 部署路径:/home/gitea/www/photography/" - echo "🌐 访问地址:https://photography.iriver.top" - name: 🔍 健康检查 run: | echo "🔍 执行健康检查..." - sleep 10 + sleep 5 - # 检查网站是否可访问 - if curl -f -s -o /dev/null https://photography.iriver.top; then + # 快速健康检查 + if curl -f -s -o /dev/null --max-time 10 https://photography.iriver.top; then echo "✅ 前端网站访问正常" else - echo "⚠️ 前端网站访问异常" - exit 1 - fi - + echo "⚠️ 前端网站访问异常,请手动检查" + fi \ No newline at end of file