name: CI/CD Pipeline on: push: branches: - 'feature/*' - 'develop' pull_request: branches: - main # 手动触发正式环境部署 workflow_dispatch: inputs: environment: description: 'Deploy to' required: true default: 'test' type: choice options: - test - prod env: DEPLOY_HOST: micecola.top DEPLOY_USER: root TEST_DIR: /www/wwwroot/kb-web-test PROD_DIR: /www/wwwroot/kb-web jobs: # ==================== 测试环境部署 ==================== deploy-test: runs-on: ubuntu-latest if: github.event_name == 'push' || (github.event_name == 'workflow_dispatch' && github.event.inputs.environment == 'test') steps: - name: Checkout code 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 uses: shivammathur/setup-php@v2 with: php-version: '8.1' extensions: mbstring, xml, mysql - name: Install dependencies run: composer install --prefer-dist --no-progress || true - name: Run tests 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 # ==================== 回退(测试失败时) ==================== rollback: runs-on: ubuntu-latest needs: test if: failure() 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 uses: actions/checkout@v4 with: fetch-depth: 0 token: ${{ secrets.GITEA_TOKEN }} - name: Configure git run: | git config user.name "CI Bot" git config user.email "ci-bot@micecola.top" - 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: Notify merge run: echo "✅ 已合并到 main,等待手动部署到正式环境" # ==================== 正式环境部署(仅手动触发) ==================== deploy-prod: runs-on: ubuntu-latest if: github.event_name == 'workflow_dispatch' && github.event.inputs.environment == 'prod' 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 }}"