增加wiki #37
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Deploy TinyFlow | |
| on: | |
| push: | |
| branches: [master, main] | |
| workflow_dispatch: # 支持手动触发 | |
| jobs: | |
| build-and-deploy: | |
| runs-on: ubuntu-latest | |
| steps: | |
| # 1. 检出代码 | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| # 2. 设置 Node.js 环境 | |
| - name: Setup Node.js | |
| uses: actions/setup-node@v4 | |
| with: | |
| node-version: '18' | |
| cache: 'npm' | |
| cache-dependency-path: web/package-lock.json | |
| # 3. 安装前端依赖并构建 | |
| - name: Build Frontend | |
| run: | | |
| cd web | |
| npm ci | |
| npm run build | |
| env: | |
| VITE_SHORT_BASE: ${{ secrets.APP_DOMAIN }} | |
| VITE_API_BASE: ${{ secrets.API_BASE || '' }} | |
| # 4. 设置 Java 环境 | |
| - name: Setup Java | |
| uses: actions/setup-java@v4 | |
| with: | |
| distribution: 'temurin' | |
| java-version: '17' | |
| cache: 'maven' | |
| # 5. 运行后端测试 | |
| - name: Run Backend Tests | |
| run: mvn clean test | |
| env: | |
| APP_DOMAIN: ${{ secrets.APP_DOMAIN }} | |
| DB_PASSWORD: ${{ secrets.DB_PASSWORD }} | |
| JWT_SECRET: ${{ secrets.JWT_SECRET }} | |
| REDIS_PASSWORD: ${{ secrets.REDIS_PASSWORD }} | |
| # 6. 构建后端(跳过测试,因为已经运行过) | |
| - name: Build Backend Package | |
| run: mvn clean package -DskipTests | |
| env: | |
| APP_DOMAIN: ${{ secrets.APP_DOMAIN }} | |
| DB_PASSWORD: ${{ secrets.DB_PASSWORD }} | |
| JWT_SECRET: ${{ secrets.JWT_SECRET }} | |
| REDIS_PASSWORD: ${{ secrets.REDIS_PASSWORD }} | |
| # 7. 上传 JAR 包到服务器 | |
| - name: Upload JAR to Server | |
| uses: appleboy/[email protected] | |
| with: | |
| host: ${{ secrets.SERVER_HOST }} | |
| port: ${{ secrets.SERVER_PORT }} | |
| username: ${{ secrets.SERVER_USER }} | |
| key: ${{ secrets.SERVER_SSH_KEY }} | |
| source: "target/TinyFlow-0.0.1-SNAPSHOT.jar" | |
| target: "/opt/TinyFlow/" | |
| strip_components: 1 | |
| # 8. 上传前端构建产物到服务器 | |
| - name: Upload Frontend to Server | |
| uses: appleboy/[email protected] | |
| with: | |
| host: ${{ secrets.SERVER_HOST }} | |
| port: ${{ secrets.SERVER_PORT }} | |
| username: ${{ secrets.SERVER_USER }} | |
| key: ${{ secrets.SERVER_SSH_KEY }} | |
| source: "web/dist/*" | |
| target: "/opt/TinyFlow/web/dist/" | |
| strip_components: 2 | |
| # 9. 重启服务 | |
| - name: Restart Service | |
| uses: appleboy/[email protected] | |
| env: | |
| APP_DOMAIN: ${{ secrets.APP_DOMAIN }} | |
| DB_PASSWORD: ${{ secrets.DB_PASSWORD }} | |
| JWT_SECRET: ${{ secrets.JWT_SECRET }} | |
| REDIS_PASSWORD: ${{ secrets.REDIS_PASSWORD }} | |
| with: | |
| host: ${{ secrets.SERVER_HOST }} | |
| port: ${{ secrets.SERVER_PORT }} | |
| username: ${{ secrets.SERVER_USER }} | |
| key: ${{ secrets.SERVER_SSH_KEY }} | |
| envs: APP_DOMAIN,DB_PASSWORD,JWT_SECRET,REDIS_PASSWORD | |
| script: | | |
| echo "🚀 开始部署..." | |
| # 复制 JAR 包到运行目录 | |
| sudo mkdir -p /opt/tinyflow | |
| sudo cp /opt/TinyFlow/TinyFlow-0.0.1-SNAPSHOT.jar /opt/tinyflow/app.jar | |
| # 更新 systemd 环境变量 | |
| sudo sed -i "s|Environment=\"APP_DOMAIN=.*\"|Environment=\"APP_DOMAIN=$APP_DOMAIN\"|g" /etc/systemd/system/tinyflow.service | |
| sudo sed -i "s|Environment=\"DB_PASSWORD=.*\"|Environment=\"DB_PASSWORD=$DB_PASSWORD\"|g" /etc/systemd/system/tinyflow.service | |
| sudo sed -i "s|Environment=\"JWT_SECRET=.*\"|Environment=\"JWT_SECRET=$JWT_SECRET\"|g" /etc/systemd/system/tinyflow.service | |
| sudo sed -i "s|Environment=\"REDIS_PASSWORD=.*\"|Environment=\"REDIS_PASSWORD=$REDIS_PASSWORD\"|g" /etc/systemd/system/tinyflow.service | |
| # 重启服务 | |
| sudo systemctl daemon-reload | |
| sudo systemctl restart tinyflow | |
| echo "⏳ 等待服务启动..." | |
| sleep 10 | |
| # 检查服务状态 | |
| if ! systemctl is-active --quiet tinyflow; then | |
| echo "❌ 服务未运行,查看日志:" | |
| journalctl -u tinyflow -n 50 --no-pager | |
| exit 1 | |
| fi | |
| echo "✅ systemd服务已启动,等待应用完全就绪..." | |
| # 健康检查 | |
| MAX_RETRY=12 | |
| RETRY_COUNT=0 | |
| while [ $RETRY_COUNT -lt $MAX_RETRY ]; do | |
| HTTP_CODE=$(curl -s -o /dev/null -w "%{http_code}" http://localhost:8080/actuator/health) | |
| if [ "$HTTP_CODE" = "200" ]; then | |
| echo "✅ 部署完成!服务健康检查通过 (HTTP $HTTP_CODE)" | |
| exit 0 | |
| elif [ "$HTTP_CODE" != "000" ]; then | |
| echo "⚠️ 服务响应但状态不是OK (HTTP $HTTP_CODE),继续等待..." | |
| fi | |
| RETRY_COUNT=$((RETRY_COUNT+1)) | |
| echo "⏳ 第 $RETRY_COUNT/$MAX_RETRY 次检查,等待 10 秒后重试..." | |
| sleep 10 | |
| done | |
| echo "❌ 健康检查超时,最后状态码: $HTTP_CODE" | |
| journalctl -u tinyflow -n 100 --no-pager | grep -E "ERROR|WARN|Exception" || journalctl -u tinyflow -n 50 --no-pager | |
| exit 1 | |
| # 10. 部署失败通知(可选) | |
| - name: Deployment Failed | |
| if: failure() | |
| run: echo "❌ TinyFlow 部署失败!请检查 GitHub Actions 日志" | |
| # 11. 部署成功通知 | |
| - name: Deployment Success | |
| if: success() | |
| run: echo "✅ TinyFlow 部署成功!" |