diff --git a/.github/workflows/qiuqiu-deploy.yml b/.github/workflows/qiuqiu-deploy.yml new file mode 100644 index 00000000..9d24b5f8 --- /dev/null +++ b/.github/workflows/qiuqiu-deploy.yml @@ -0,0 +1,182 @@ +name: ๐ŸŒธ ็ง‹็ง‹ๆœๅŠกๅ™จ ยท ้ƒจ็ฝฒ + +# โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ• +# ็ง‹็ง‹(ไน‹ไน‹)ๆœๅŠกๅ™จ้ƒจ็ฝฒๅทฅไฝœๆต +# ็ผ–ๅท: ZZ-WF-็ง‹็ง‹้ƒจ็ฝฒ +# ๅฎˆๆŠค: ้“ธๆธŠ ยท ICE-GL-ZY001 +# ็‰ˆๆƒ: ๅ›ฝไฝœ็™ปๅญ—-2026-A-00037559 +# โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ• +# +# ๆœๅŠกๅ™จ: ZZ ๆœๅŠกๅ™จ +# ๅฏ†้’ฅ: ZZ_SERVER_KEY / ZZ_SERVER_HOST / ZZ_SERVER_USER / ZZ_SERVER_PATH +# LLM: ZZ_LLM_API_KEY / ZZ_LLM_BASE_URL + +on: + workflow_dispatch: + inputs: + action: + description: '้ƒจ็ฝฒๅŠจไฝœ' + required: true + default: 'deploy' + type: choice + options: + - deploy + - health-check + +concurrency: + group: qiuqiu-server-deploy + cancel-in-progress: false + +permissions: + contents: read + +jobs: + # โ•โ•โ• ยง1 ้ƒจ็ฝฒๅบ”็”จ โ•โ•โ• + deploy: + name: ๐Ÿš€ ้ƒจ็ฝฒ็ง‹็ง‹ๆœๅŠก + if: github.event.inputs.action == 'deploy' + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - name: ๐Ÿ” ้…็ฝฎSSHๅฏ†้’ฅ + env: + SSH_KEY: ${{ secrets.ZZ_SERVER_KEY }} + run: | + mkdir -p ~/.ssh + echo "$SSH_KEY" > ~/.ssh/id_zz + chmod 600 ~/.ssh/id_zz + + if ! head -1 ~/.ssh/id_zz | grep -q "BEGIN"; then + echo "โŒ SSHๅฏ†้’ฅๆ ผๅผๅผ‚ๅธธ" + exit 1 + fi + echo "โœ… SSHๅฏ†้’ฅๆ ผๅผๆญฃ็กฎ" + + ssh-keyscan -H ${{ secrets.ZZ_SERVER_HOST }} >> ~/.ssh/known_hosts 2>/dev/null + + cat > ~/.ssh/config << EOF + Host zz-server + HostName ${{ secrets.ZZ_SERVER_HOST }} + User ${{ secrets.ZZ_SERVER_USER }} + IdentityFile ~/.ssh/id_zz + StrictHostKeyChecking accept-new + BatchMode yes + ConnectTimeout 30 + EOF + chmod 600 ~/.ssh/config + + - name: ๐Ÿ” SSH่ฟžๆŽฅๆต‹่ฏ• + run: | + ssh zz-server 'echo "โœ… SSH่ฟžๆŽฅๆˆๅŠŸ ยท $(hostname) ยท $(date)"' + + - name: ๐Ÿ“ฆ ๅŒๆญฅๅบ”็”จไปฃ็  + run: | + ZZ_PATH="${{ secrets.ZZ_SERVER_PATH }}" + echo "๐Ÿ“ฆ ้ƒจ็ฝฒ็›ฎๆ ‡: ${ZZ_PATH}" + + ssh zz-server "mkdir -p ${ZZ_PATH}/app" + + rsync -avz --delete \ + -e "ssh -F ~/.ssh/config" \ + server/app/ \ + zz-server:${ZZ_PATH}/app/ + + - name: โš™๏ธ ๅ†™ๅ…ฅ LLM ็Žฏๅขƒ้…็ฝฎ + run: | + ZZ_PATH="${{ secrets.ZZ_SERVER_PATH }}" + ssh zz-server "cat > ${ZZ_PATH}/app/.env << 'ENVEOF' + LLM_API_KEY=${{ secrets.ZZ_LLM_API_KEY }} + LLM_BASE_URL=${{ secrets.ZZ_LLM_BASE_URL }} + ENVEOF + chmod 600 ${ZZ_PATH}/app/.env" + + - name: ๐Ÿ“ฅ ๅฎ‰่ฃ…ไพ่ต– & ้‡ๅฏ + run: | + ZZ_PATH="${{ secrets.ZZ_SERVER_PATH }}" + COMMIT_SHA="${{ github.sha }}" + ssh zz-server << DEPLOY_CMD + + set -e + cd ${ZZ_PATH}/app + + if [ ! -f server.js ]; then + echo "โŒ ้”™่ฏฏ: server.js ไธๅญ˜ๅœจ" + exit 1 + fi + + npm install --production 2>&1 + + pm2 delete qiuqiu 2>/dev/null || true + pm2 start server.js --name qiuqiu + pm2 save + + sleep 3 + curl -sf http://localhost:3000/api/health && echo "โœ… ็ง‹็ง‹ๆœๅŠกๅทฒไธŠ็บฟ" || echo "โŒ ็ง‹็ง‹ๆœๅŠกๅฏๅŠจๅคฑ่ดฅ" + + DEPLOY_CMD + + - name: ๐Ÿงน ๆธ…็†SSHๅฏ†้’ฅ + if: always() + run: rm -f ~/.ssh/id_zz ~/.ssh/config + + # โ•โ•โ• ยง2 ๅฅๅบทๆฃ€ๆŸฅ โ•โ•โ• + health-check: + name: ๐Ÿ’š ็ง‹็ง‹ๆœๅŠกๅฅๅบทๆฃ€ๆŸฅ + if: github.event.inputs.action == 'health-check' + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - name: ๐Ÿ” ้…็ฝฎSSHๅฏ†้’ฅ + env: + SSH_KEY: ${{ secrets.ZZ_SERVER_KEY }} + run: | + mkdir -p ~/.ssh + echo "$SSH_KEY" > ~/.ssh/id_zz + chmod 600 ~/.ssh/id_zz + + ssh-keyscan -H ${{ secrets.ZZ_SERVER_HOST }} >> ~/.ssh/known_hosts 2>/dev/null + + cat > ~/.ssh/config << EOF + Host zz-server + HostName ${{ secrets.ZZ_SERVER_HOST }} + User ${{ secrets.ZZ_SERVER_USER }} + IdentityFile ~/.ssh/id_zz + StrictHostKeyChecking accept-new + BatchMode yes + ConnectTimeout 30 + EOF + chmod 600 ~/.ssh/config + + - name: ๐Ÿ’š ๆ‰ง่กŒๅฅๅบทๆฃ€ๆŸฅ + run: | + ssh zz-server << 'HEALTH_CMD' + + echo "โ•โ•โ• ็ง‹็ง‹ๆœๅŠกๅ™จๅฅๅบทๆŠฅๅ‘Š โ•โ•โ•" + echo "" + + echo "ยง1 ็ณป็ปŸ็Šถๆ€:" + uptime + echo "" + + echo "ยง2 ็ฃ็›˜ไฝฟ็”จ:" + df -h / + echo "" + + echo "ยง3 ๅ†…ๅญ˜ไฝฟ็”จ:" + free -m + echo "" + + echo "ยง4 PM2 ่ฟ›็จ‹:" + pm2 list 2>/dev/null || echo "PM2 ๆœช่ฟ่กŒ" + echo "" + + echo "ยง5 ๅบ”็”จๅฅๅบท:" + curl -sf http://localhost:3000/api/health | jq . 2>/dev/null || echo "ๅบ”็”จๆœชๅ“ๅบ”" + + HEALTH_CMD + + - name: ๐Ÿงน ๆธ…็†SSHๅฏ†้’ฅ + if: always() + run: rm -f ~/.ssh/id_zz ~/.ssh/config