name: Deploy on: push: branches: [main] jobs: deploy: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: actions/setup-go@v5 with: go-version-file: backend/go.mod cache-dependency-path: backend/go.sum - name: Go tests working-directory: backend run: go test ./... - uses: subosito/flutter-action@v2 with: channel: stable cache: true - name: Flutter tests working-directory: client run: flutter test - name: Build backend (linux/amd64) working-directory: backend run: GOOS=linux GOARCH=amd64 CGO_ENABLED=0 go build -o jiu-server . - name: Build Flutter Web working-directory: client run: flutter build web --release --dart-define=BASE_URL=https://jiu.51yanmei.com --dart-define=PUBLIC_URL=https://jiu.51yanmei.com - name: Package artifacts run: | tar -czf web.tar.gz -C client/build web echo "VERSION=v$(date +%Y%m%d.%H%M)" >> $GITHUB_ENV - name: Create Forgejo Release env: FORGEJO_TOKEN: ${{ secrets.FORGEJO_TOKEN }} FORGEJO_URL: ${{ secrets.FORGEJO_URL }} run: | # 创建 Release,获取 ID RELEASE_ID=$(curl -sf -X POST "${FORGEJO_URL}/api/v1/repos/${{ gitea.repository }}/releases" \ -H "Authorization: token ${FORGEJO_TOKEN}" \ -H "Content-Type: application/json" \ -d "{\"tag_name\":\"${VERSION}\",\"name\":\"Release ${VERSION}\",\"draft\":false,\"prerelease\":false}" \ | python3 -c "import sys,json; print(json.load(sys.stdin)['id'])") # 上传 Go 二进制 curl -sf -X POST "${FORGEJO_URL}/api/v1/repos/${{ gitea.repository }}/releases/${RELEASE_ID}/assets" \ -H "Authorization: token ${FORGEJO_TOKEN}" \ -F "attachment=@backend/jiu-server" # 上传 Flutter Web curl -sf -X POST "${FORGEJO_URL}/api/v1/repos/${{ gitea.repository }}/releases/${RELEASE_ID}/assets" \ -H "Authorization: token ${FORGEJO_TOKEN}" \ -F "attachment=@web.tar.gz" echo "Release ${VERSION} created: ${FORGEJO_URL}/${{ gitea.repository }}/releases/tag/${VERSION}" - name: Setup SSH run: | mkdir -p ~/.ssh echo "${{ secrets.EC2_SSH_KEY }}" > ~/.ssh/ec2.pem chmod 600 ~/.ssh/ec2.pem ssh-keyscan -H ${{ secrets.EC2_HOST }} >> ~/.ssh/known_hosts - name: Deploy to EC2 env: EC2_HOST: ${{ secrets.EC2_HOST }} EC2_USER: ${{ secrets.EC2_USER }} run: | scp -i ~/.ssh/ec2.pem backend/jiu-server ${EC2_USER}@${EC2_HOST}:/tmp/jiu-server rsync -avz --delete -e "ssh -i ~/.ssh/ec2.pem" \ client/build/web/ ${EC2_USER}@${EC2_HOST}:/tmp/jiu-web-new/ ssh -i ~/.ssh/ec2.pem ${EC2_USER}@${EC2_HOST} << 'ENDSSH' sudo systemctl stop jiu cp /tmp/jiu-server /opt/jiu/backend/jiu-server chmod +x /opt/jiu/backend/jiu-server sudo systemctl start jiu for i in $(seq 1 30); do curl -sf http://localhost:8080/health && break sleep 2 done rm -rf /opt/jiu/web-old mv /opt/jiu/web /opt/jiu/web-old 2>/dev/null || true mv /tmp/jiu-web-new /opt/jiu/web sudo nginx -s reload ENDSSH - name: Cleanup SSH key if: always() run: rm -f ~/.ssh/ec2.pem