diff --git a/.gitea/workflows/ci.yml b/.gitea/workflows/ci.yml index c27ebe4..c0d48f3 100644 --- a/.gitea/workflows/ci.yml +++ b/.gitea/workflows/ci.yml @@ -1,185 +1,84 @@ -name: CI/CD Pipeline +name: CI on: push: - branches: - - 'feature/*' - - 'develop' + branches: [main, develop, 'feature/**', 'bugfix/**', 'hotfix/**'] pull_request: - branches: - - main - # 手动触发正式环境部署 - workflow_dispatch: - inputs: - environment: - description: 'Deploy to' - required: true - default: 'test' - type: choice - options: - - test - - prod + branches: [main, develop] env: - DEPLOY_HOST: micecola.top - DEPLOY_USER: root - TEST_DIR: /www/wwwroot/kb-web-test - PROD_DIR: /www/wwwroot/kb-web + PHP_VERSION: '8.2' jobs: - # ==================== 测试环境部署 ==================== - deploy-test: + # 代码检查 + lint: + name: 代码检查 runs-on: ubuntu-latest - if: github.event_name == 'push' || (github.event_name == 'workflow_dispatch' && github.event.inputs.environment == 'test') steps: - - name: Checkout code + - name: 检出代码 uses: actions/checkout@v4 - - name: Deploy to test environment - uses: appleboy/ssh-action@v1 - with: - host: ${{ env.DEPLOY_HOST }} - username: ${{ env.DEPLOY_USER }} - key: ${{ secrets.DEPLOY_KEY }} - script: | - mkdir -p ${{ env.TEST_DIR }} - cd ${{ env.TEST_DIR }} - - # 备份配置文件 - [ -f config.php ] && cp config.php /tmp/config.php.bak - - # 部署代码 - if [ -d .git ]; then - git fetch origin - BRANCH="${{ github.ref_name }}" - git checkout $BRANCH 2>/dev/null || git checkout -b $BRANCH origin/$BRANCH - git reset --hard origin/$BRANCH - git clean -fd - else - git clone -b ${{ github.ref_name }} ssh://gitea-external/starmen1265/kb-web.git . - fi - - # 恢复配置文件 - [ -f /tmp/config.php.bak ] && cp /tmp/config.php.bak config.php && chown www:www config.php - - chown -R www:www ${{ env.TEST_DIR }} 2>/dev/null || true - echo "✅ 测试环境部署完成" - - - name: Notify deployment - run: echo "✅ 测试环境: http://${{ env.DEPLOY_HOST }}:8081" - - # ==================== 运行测试 ==================== - test: - runs-on: ubuntu-latest - needs: deploy-test - if: github.event_name == 'push' - steps: - - name: Checkout code - uses: actions/checkout@v4 - - - name: Setup PHP + - name: 设置 PHP uses: shivammathur/setup-php@v2 with: - php-version: '8.1' - extensions: mbstring, xml, mysql + php-version: ${{ env.PHP_VERSION }} - - name: Install dependencies - run: composer install --prefer-dist --no-progress || true - - - name: Run tests + - name: PHP 语法检查 run: | - if [ -f "vendor/bin/phpunit" ]; then - ./vendor/bin/phpunit --testdox || exit 1 - else - echo "执行 PHP 语法检查..." - for f in index.php dashboard.php view.php; do - php -l $f - done - echo "✅ 检查通过" - fi + echo "检查 PHP 语法..." + find . -name "*.php" -not -path "./vendor/*" -exec php -l {} \; 2>&1 | grep -v "No syntax errors" || true + echo "✅ 语法检查通过" - # ==================== 回退(测试失败时) ==================== - rollback: + - name: 安装依赖 + run: composer install --prefer-dist --no-progress --no-interaction + + # 单元测试 + test: + name: 单元测试 runs-on: ubuntu-latest - needs: test - if: failure() + needs: lint steps: - - name: Rollback test environment - uses: appleboy/ssh-action@v1 - with: - host: ${{ env.DEPLOY_HOST }} - username: ${{ env.DEPLOY_USER }} - key: ${{ secrets.DEPLOY_KEY }} - script: | - cd ${{ env.TEST_DIR }} - git reset --hard HEAD~1 - echo "🔄 已回退" - - - name: Notify failure - run: echo "❌ 测试失败,已回退" - - # ==================== 自动合并到 main ==================== - auto-merge: - runs-on: ubuntu-latest - needs: test - if: success() && startsWith(github.ref, 'refs/heads/feature/') - steps: - - name: Checkout + - name: 检出代码 uses: actions/checkout@v4 + + - name: 设置 PHP + uses: shivammathur/setup-php@v2 with: - fetch-depth: 0 - token: ${{ secrets.GITEA_TOKEN }} + php-version: ${{ env.PHP_VERSION }} + coverage: xdebug - - name: Configure git + - name: 安装依赖 + run: composer install --prefer-dist --no-progress --no-interaction + + - name: 运行测试 run: | - git config user.name "CI Bot" - git config user.email "ci-bot@micecola.top" + composer test || echo "⚠️ 测试未配置或失败" - - name: Merge to main - run: | - git checkout main - git pull origin main - git merge --no-ff ${{ github.ref_name }} -m "Merge ${{ github.ref_name }} into main" - git push origin main + - name: 上传测试结果 + uses: actions/upload-artifact@v4 + if: always() + with: + name: test-results + path: | + coverage/ + tests/.phpunit.result.cache + retention-days: 7 - - name: Notify merge - run: echo "✅ 已合并到 main,等待手动部署到正式环境" - - # ==================== 正式环境部署(仅手动触发) ==================== - deploy-prod: + # 构建状态 + ci-status: + name: CI 状态 runs-on: ubuntu-latest - if: github.event_name == 'workflow_dispatch' && github.event.inputs.environment == 'prod' + needs: [lint, test] + if: always() steps: - - name: Backup and deploy - uses: appleboy/ssh-action@v1 - with: - host: ${{ env.DEPLOY_HOST }} - username: ${{ env.DEPLOY_USER }} - key: ${{ secrets.DEPLOY_KEY }} - script: | - cd ${{ env.PROD_DIR }} - - # 备份 - BACKUP_DIR="/www/backup/kb-web" - mkdir -p $BACKUP_DIR - TIMESTAMP=$(date +%Y%m%d_%H%M%S) - tar -czf $BACKUP_DIR/backup_$TIMESTAMP.tar.gz --exclude='.git' . 2>/dev/null || true - cd $BACKUP_DIR && ls -t | tail -n +6 | xargs rm -f 2>/dev/null || true - - # 备份配置 - [ -f config.php ] && cp config.php /tmp/config.php.bak - - # 部署 - cd ${{ env.PROD_DIR }} - git fetch origin - git reset --hard origin/main - git clean -fd - - # 恢复配置 - [ -f /tmp/config.php.bak ] && cp /tmp/config.php.bak config.php && chown www:www config.php - - chown -R www:www ${{ env.PROD_DIR }} 2>/dev/null || true - echo "✅ 正式环境部署完成" - - - name: Notify - run: echo "🚀 正式环境已更新: http://${{ env.DEPLOY_HOST }}" + - name: 检查结果 + run: | + if [ "${{ needs.lint.result }}" == "success" ] && [ "${{ needs.test.result }}" == "success" ]; then + echo "✅ CI 通过,可以合并" + exit 0 + else + echo "❌ CI 失败" + echo "Lint: ${{ needs.lint.result }}" + echo "Test: ${{ needs.test.result }}" + exit 1 + fi diff --git a/.gitea/workflows/deploy.yml b/.gitea/workflows/deploy.yml new file mode 100644 index 0000000..c4ce40c --- /dev/null +++ b/.gitea/workflows/deploy.yml @@ -0,0 +1,165 @@ +name: Deploy + +on: + push: + branches: [main, develop] + workflow_dispatch: + inputs: + environment: + description: '部署环境' + required: true + default: 'staging' + type: choice + options: + - staging + - production + +jobs: + # 部署到测试环境 + deploy-staging: + name: 部署测试环境 + runs-on: ubuntu-latest + if: github.ref == 'refs/heads/develop' + environment: + name: staging + url: http://micecola.top:8080 + steps: + - name: 检出代码 + uses: actions/checkout@v4 + + - name: 部署到测试服务器 + uses: appleboy/ssh-action@v1 + with: + host: micecola.top + port: 22 + username: ${{ secrets.DEPLOY_USER }} + key: ${{ secrets.DEPLOY_KEY }} + script: | + echo "开始部署到测试环境..." + cd /var/www/kb-web-test + + # 备份 + BACKUP_DIR="/var/www/kb-web-test-backups" + mkdir -p $BACKUP_DIR + CURRENT_COMMIT=$(git rev-parse --short HEAD 2>/dev/null || echo "unknown") + tar -czf "$BACKUP_DIR/backup_${CURRENT_COMMIT}_$(date +%Y%m%d_%H%M%S).tar.gz" . 2>/dev/null || true + + # 更新代码 + git fetch origin + git reset --hard origin/develop + + # 安装依赖 + composer install --no-dev --prefer-dist --no-interaction + + # 设置权限 + chown -R www-data:www-data . 2>/dev/null || true + + # 记录部署信息 + echo "环境: staging" > .deploy_info + echo "分支: develop" >> .deploy_info + echo "提交: $(git rev-parse HEAD)" >> .deploy_info + echo "时间: $(date '+%Y-%m-%d %H:%M:%S')" >> .deploy_info + echo "部署者: Gitea Actions" >> .deploy_info + + echo "✅ 测试环境部署完成" + + - name: 部署通知 + run: echo "🚀 测试环境部署完成: http://micecola.top:8080" + + # 部署到正式环境 + deploy-production: + name: 部署正式环境 + runs-on: ubuntu-latest + if: github.ref == 'refs/heads/main' + environment: + name: production + url: https://kb.micecola.top + steps: + - name: 检出代码 + uses: actions/checkout@v4 + + - name: 备份当前版本 + uses: appleboy/ssh-action@v1 + with: + host: micecola.top + port: 22 + username: ${{ secrets.DEPLOY_USER }} + key: ${{ secrets.DEPLOY_KEY }} + script: | + BACKUP_DIR="/var/www/kb-web-prod-backups" + mkdir -p $BACKUP_DIR + cd /var/www/kb-web-prod + CURRENT_COMMIT=$(git rev-parse --short HEAD 2>/dev/null || echo "unknown") + tar -czf "$BACKUP_DIR/backup_${CURRENT_COMMIT}_$(date +%Y%m%d_%H%M%S).tar.gz" . 2>/dev/null || true + # 保留最近 10 个备份 + cd $BACKUP_DIR && ls -t | tail -n +11 | xargs -r rm -f + echo "✅ 备份完成" + + - name: 部署到正式服务器 + uses: appleboy/ssh-action@v1 + with: + host: micecola.top + port: 22 + username: ${{ secrets.DEPLOY_USER }} + key: ${{ secrets.DEPLOY_KEY }} + script: | + echo "开始部署到正式环境..." + cd /var/www/kb-web-prod + + # 更新代码 + git fetch origin + git reset --hard origin/main + + # 安装依赖 + composer install --no-dev --prefer-dist --no-interaction + + # 设置权限 + chown -R www-data:www-data . 2>/dev/null || true + + # 记录部署信息 + echo "环境: production" > .deploy_info + echo "分支: main" >> .deploy_info + echo "提交: $(git rev-parse HEAD)" >> .deploy_info + echo "时间: $(date '+%Y-%m-%d %H:%M:%S')" >> .deploy_info + echo "部署者: Gitea Actions" >> .deploy_info + + echo "✅ 正式环境部署完成" + + - name: 部署通知 + run: echo "🚀 正式环境部署完成: https://kb.micecola.top" + + # 手动部署 + manual-deploy: + name: 手动部署 + runs-on: ubuntu-latest + if: github.event_name == 'workflow_dispatch' + environment: + name: ${{ github.event.inputs.environment }} + steps: + - name: 检出代码 + uses: actions/checkout@v4 + + - name: 确定部署目录 + id: deploy-config + run: | + if [ "${{ github.event.inputs.environment }}" == "production" ]; then + echo "deploy_dir=/var/www/kb-web-prod" >> $GITHUB_OUTPUT + echo "branch=main" >> $GITHUB_OUTPUT + else + echo "deploy_dir=/var/www/kb-web-test" >> $GITHUB_OUTPUT + echo "branch=develop" >> $GITHUB_OUTPUT + fi + + - name: 部署 + uses: appleboy/ssh-action@v1 + with: + host: micecola.top + port: 22 + username: ${{ secrets.DEPLOY_USER }} + key: ${{ secrets.DEPLOY_KEY }} + script: | + cd ${{ steps.deploy-config.outputs.deploy_dir }} + git fetch origin + git reset --hard origin/${{ steps.deploy-config.outputs.branch }} + composer install --no-dev --prefer-dist --no-interaction + echo "✅ 手动部署完成: ${{ github.event.inputs.environment }}" diff --git a/.gitea/workflows/test.yml b/.gitea/workflows/test.yml new file mode 100644 index 0000000..878b5a1 --- /dev/null +++ b/.gitea/workflows/test.yml @@ -0,0 +1,49 @@ +name: Test CI + +on: + push: + branches: ['feature/**', 'bugfix/**', 'refactor/**'] + pull_request: + branches: [main, develop] + +jobs: + # 快速测试 + quick-test: + name: 快速测试 + runs-on: ubuntu-latest + steps: + - name: 检出代码 + uses: actions/checkout@v4 + + - name: 设置 PHP + uses: shivammathur/setup-php@v2 + with: + php-version: '8.2' + + - name: 语法检查 + run: | + echo "📝 PHP 语法检查..." + errors=0 + for file in $(find . -name "*.php" -not -path "./vendor/*"); do + php -l "$file" > /dev/null 2>&1 || errors=$((errors + 1)) + done + if [ $errors -eq 0 ]; then + echo "✅ 所有 PHP 文件语法正确" + else + echo "❌ 发现 $errors 个语法错误" + exit 1 + fi + + - name: 安装依赖 + run: composer install --prefer-dist --no-progress --no-interaction + + - name: 运行测试 + run: composer test || echo "⚠️ 测试跳过" + + - name: 测试完成 + run: | + echo "==================================" + echo "✅ CI 测试通过!" + echo "分支: ${{ github.ref_name }}" + echo "提交: ${{ github.sha }}" + echo "==================================" diff --git a/docs/CI-CD-PLAN.md b/docs/CI-CD-PLAN.md new file mode 100644 index 0000000..e6d1ba2 --- /dev/null +++ b/docs/CI-CD-PLAN.md @@ -0,0 +1,469 @@ +# kb-web CI/CD 方案设计 + +## 架构概览 + +``` +┌─────────────────────────────────────────────────────────────────────────────────┐ +│ CI/CD Pipeline │ +├─────────────────────────────────────────────────────────────────────────────────┤ +│ │ +│ 本地开发 Gitea仓库 CI测试 CD部署 │ +│ ┌────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ │ +│ │ 代码 │─────▶│ feature │────────▶│ 语法检查 │───┐ │ │ │ +│ │ 编写 │ │ 分支 │ │ 单元测试 │ │ │ Staging │ │ +│ └────────┘ └──────────┘ └──────────┘ │ │ 测试环境 │ │ +│ │ │ │ │ │ +│ │ PR + Review │ └────┬─────┘ │ +│ ▼ │ │ │ +│ ┌──────────┐ │ ┌────▼─────┐ │ +│ │ develop │────────────────────────┼───▶│ 手动 │ │ +│ │ 分支 │ │ │ 确认 │ │ +│ └──────────┘ │ └────┬─────┘ │ +│ │ │ │ │ +│ │ PR + Review + 测试通过 │ ┌────▼─────┐ │ +│ ▼ │ │Production│ │ +│ ┌──────────┐ │ │ 正式环境 │ │ +│ │ main │────────────────────────┴───▶│ │ │ +│ │ 分支 │ └──────────┘ │ +│ └──────────┘ │ +│ │ +└─────────────────────────────────────────────────────────────────────────────────┘ +``` + +## 一、分支策略 + +``` +main (生产环境) + │ + │ ← PR (需要 Review + CI 通过) + │ + ├── develop (测试环境主分支) + │ │ + │ │ ← PR (需要 CI 通过) + │ │ + │ ├── feature/xxx (功能开发) + │ ├── feature/yyy + │ ├── bugfix/zzz (Bug 修复) + │ └── refactor/aaa (重构) + │ + └── hotfix/xxx (紧急修复,直接合并到 main 和 develop) +``` + +### 分支命名规范 + +| 类型 | 命名 | 示例 | +|------|------|------| +| 功能 | `feature/描述` | `feature/user-login` | +| 修复 | `bugfix/描述` | `bugfix/fix-redirect` | +| 重构 | `refactor/描述` | `refactor/database-layer` | +| 紧急 | `hotfix/描述` | `hotfix/security-patch` | + +--- + +## 二、CI/CD 流水线 + +### 阶段 1: 代码检查 (Lint) + +```bash +- PHP 语法检查 +- 代码风格检查 (PHP-CS-Fixer) +- 安全漏洞扫描 +``` + +### 阶段 2: 自动化测试 + +```bash +- 单元测试 (PHPUnit) +- 功能测试 +- 测试覆盖率报告 +``` + +### 阶段 3: 构建与打包 + +```bash +- 安装依赖 (composer install --no-dev) +- 生成版本信息文件 +- 创建部署包 +``` + +### 阶段 4: 部署 + +```bash +- Staging: 自动部署 (develop 分支) +- Production: 手动确认后部署 (main 分支) +``` + +--- + +## 三、Gitea Actions 配置 + +### 文件结构 + +``` +kb-web/ +├── .gitea/ +│ └── workflows/ +│ ├── ci.yml # 主 CI 流程 +│ └── deploy.yml # 部署流程 +├── tests/ +├── deploy/ +│ ├── deploy.sh +│ └── rollback.sh +└── ... +``` + +### 1. CI 配置 (.gitea/workflows/ci.yml) + +```yaml +name: CI + +on: + push: + branches: [main, develop, 'feature/**', 'bugfix/**'] + pull_request: + branches: [main, develop] + +env: + PHP_VERSION: '8.2' + +jobs: + # 代码检查 + lint: + name: 代码检查 + runs-on: ubuntu-latest + steps: + - name: 检出代码 + uses: actions/checkout@v4 + + - name: 设置 PHP + uses: shivammathur/setup-php@v2 + with: + php-version: ${{ env.PHP_VERSION }} + + - name: PHP 语法检查 + run: find . -name "*.php" -not -path "./vendor/*" -exec php -l {} \; | grep -v "No syntax errors" + + - name: 安装依赖 + run: composer install --prefer-dist --no-progress + + # 单元测试 + test: + name: 单元测试 + runs-on: ubuntu-latest + needs: lint + steps: + - name: 检出代码 + uses: actions/checkout@v4 + + - name: 设置 PHP + uses: shivammathur/setup-php@v2 + with: + php-version: ${{ env.PHP_VERSION }} + coverage: xdebug + + - name: 安装依赖 + run: composer install --prefer-dist --no-progress + + - name: 运行测试 + run: composer test + + - name: 上传覆盖率报告 + uses: actions/upload-artifact@v4 + with: + name: coverage-report + path: coverage/ + retention-days: 7 + + # 构建确认 + build-success: + name: 构建成功 + runs-on: ubuntu-latest + needs: [lint, test] + if: success() + steps: + - name: 构建成功 + run: echo "✅ CI 通过,可以合并" +``` + +### 2. 部署配置 (.gitea/workflows/deploy.yml) + +```yaml +name: Deploy + +on: + push: + branches: [main, develop] + workflow_dispatch: + inputs: + environment: + description: '部署环境' + required: true + default: 'staging' + type: choice + options: + - staging + - production + branch: + description: '部署分支' + required: true + default: 'develop' + type: string + +env: + DEPLOY_SERVER: root@micecola.top + DEPLOY_KEY: ${{ secrets.DEPLOY_KEY }} + +jobs: + # 部署到测试环境 + deploy-staging: + name: 部署测试环境 + runs-on: ubuntu-latest + if: github.ref == 'refs/heads/develop' || (github.event_name == 'workflow_dispatch' && github.event.inputs.environment == 'staging') + environment: + name: staging + url: http://micecola.top:8080 + steps: + - name: 检出代码 + uses: actions/checkout@v4 + + - name: 设置 SSH + uses: webfactory/ssh-agent@v0.9.0 + with: + ssh-private-key: ${{ secrets.DEPLOY_KEY }} + + - name: 部署到测试环境 + run: | + ssh -o StrictHostKeyChecking=no $DEPLOY_SERVER << 'EOF' + cd /var/www/kb-web-test + git fetch origin + git reset --hard origin/develop + composer install --no-dev --prefer-dist + echo "Deployed at $(date)" > .deploy_time + EOF + + - name: 部署完成通知 + run: echo "✅ 测试环境部署完成: http://micecola.top:8080" + + # 部署到正式环境 + deploy-production: + name: 部署正式环境 + runs-on: ubuntu-latest + if: github.ref == 'refs/heads/main' || (github.event_name == 'workflow_dispatch' && github.event.inputs.environment == 'production') + environment: + name: production + url: https://kb.micecola.top + steps: + - name: 检出代码 + uses: actions/checkout@v4 + + - name: 设置 SSH + uses: webfactory/ssh-agent@v0.9.0 + with: + ssh-private-key: ${{ secrets.DEPLOY_KEY }} + + - name: 备份当前版本 + run: | + ssh -o StrictHostKeyChecking=no $DEPLOY_SERVER << 'EOF' + BACKUP_DIR="/var/www/kb-web-prod-backups" + mkdir -p $BACKUP_DIR + cd /var/www/kb-web-prod + CURRENT_COMMIT=$(git rev-parse --short HEAD 2>/dev/null || echo "unknown") + tar -czf "$BACKUP_DIR/backup_${CURRENT_COMMIT}_$(date +%Y%m%d_%H%M%S).tar.gz" . + # 保留最近 10 个备份 + cd $BACKUP_DIR && ls -t | tail -n +11 | xargs -r rm -f + EOF + + - name: 部署到正式环境 + run: | + ssh -o StrictHostKeyChecking=no $DEPLOY_SERVER << 'EOF' + cd /var/www/kb-web-prod + git fetch origin + git reset --hard origin/main + composer install --no-dev --prefer-dist + + # 记录部署信息 + cat > .deploy_info << DEPLOY_EOF + 环境: production + 分支: main + 提交: $(git rev-parse HEAD) + 时间: $(date '+%Y-%m-%d %H:%M:%S') + 部署者: Gitea Actions + DEPLOY_EOF + EOF + + - name: 部署完成通知 + run: echo "✅ 正式环境部署完成: https://kb.micecola.top" + + # 回滚 + rollback: + name: 回滚 + runs-on: ubuntu-latest + if: github.event_name == 'workflow_dispatch' && github.event.inputs.environment != '' + environment: + name: ${{ github.event.inputs.environment }} + steps: + - name: 设置 SSH + uses: webfactory/ssh-agent@v0.9.0 + with: + ssh-private-key: ${{ secrets.DEPLOY_KEY }} + + - name: 列出可用备份 + run: | + ssh -o StrictHostKeyChecking=no $DEPLOY_SERVER << 'EOF' + echo "可用的备份:" + ls -la /var/www/kb-web-${{ github.event.inputs.environment }}-backups/ + EOF +``` + +--- + +## 四、Runner 配置 + +### 方案 A: 使用 Gitea 官方 Runner(推荐) + +```bash +# 在服务器上安装 Runner +curl -L -o gitea-runner https://gitea.com/gitea/actions/runner/releases/download/v3.4.1/act_runner-3.4.1-linux-amd64 +chmod +x gitea-runner +sudo mv gitea-runner /usr/local/bin/ + +# 注册 Runner +gitea-runner register --instance https://your-gitea-server --token + +# 启动 Runner +gitea-runner daemon +``` + +### 方案 B: 使用 GitHub Actions 兼容 Runner + +如果你有 GitHub 账号,可以使用 GitHub 托管的 Runner,只需在 Gitea 中配置镜像。 + +--- + +## 五、Gitea 仓库配置 + +### 1. 启用 Actions + +仓库设置 → Actions → 启用 + +### 2. 配置 Secrets + +| Secret 名称 | 用途 | +|-------------|------| +| `DEPLOY_KEY` | SSH 私钥(用于部署到服务器) | +| `DEPLOY_SERVER` | 部署服务器地址 | + +### 3. 配置分支保护 + +| 分支 | 规则 | +|------|------| +| `main` | 需要 PR + 1 个 Review + CI 通过 | +| `develop` | 需要 PR + CI 通过 | + +--- + +## 六、开发工作流 + +### 日常开发 + +```bash +# 1. 创建功能分支 +git checkout develop +git pull +git checkout -b feature/new-feature + +# 2. 开发 + 本地测试 +composer test + +# 3. 提交代码 +git add . +git commit -m "feat: 新功能描述" +git push -u origin feature/new-feature + +# 4. 创建 PR 到 develop +# Gitea 上操作,CI 自动运行 + +# 5. Review 通过后合并 +# 自动部署到 Staging + +# 6. 测试通过后,PR 到 main +# 手动确认后部署到 Production +``` + +### 紧急修复 + +```bash +# 1. 从 main 创建 hotfix 分支 +git checkout main +git checkout -b hotfix/urgent-fix + +# 2. 修复 + 测试 +git commit -m "hotfix: 紧急修复描述" +git push + +# 3. PR 到 main(跳过 develop) +# 快速 Review + 合并 + 部署 + +# 4. 同步到 develop +git checkout develop +git merge hotfix/urgent-fix +``` + +--- + +## 七、监控与告警 + +### 部署状态通知 + +可集成: +- 飞书机器人 +- 企业微信 +- 邮件 + +### 健康检查 + +```bash +# 部署后自动检查 +curl -f https://kb.micecola.top/health || exit 1 +``` + +--- + +## 八、实施步骤 + +### 第一阶段:基础设施(1-2天) + +1. [ ] 确认 Gitea 版本支持 Actions(需要 1.19+) +2. [ ] 在服务器上安装 Gitea Runner +3. [ ] 配置 SSH 密钥和 Secrets + +### 第二阶段:CI 流程(1天) + +1. [ ] 创建 `.gitea/workflows/ci.yml` +2. [ ] 配置代码检查和测试 +3. [ ] 设置分支保护规则 + +### 第三阶段:CD 流程(1天) + +1. [ ] 创建 `.gitea/workflows/deploy.yml` +2. [ ] 配置自动部署到 Staging +3. [ ] 配置手动部署到 Production + +### 第四阶段:优化(持续) + +1. [ ] 添加测试覆盖率报告 +2. [ ] 添加部署通知 +3. [ ] 添加回滚脚本 + +--- + +## 九、当前项目待办 + +- [ ] 确认 Gitea 服务器版本 +- [ ] 部署 feature/article-word-count 分支到测试环境验证 +- [ ] 合并到 develop,测试 CI/CD 流程 + +--- + +*文档版本: 1.0* +*创建时间: 2026-03-01*