212 lines
8.1 KiB
YAML
212 lines
8.1 KiB
YAML
name: Build and Deploy
|
||
|
||
on:
|
||
push:
|
||
branches:
|
||
- main
|
||
- master
|
||
|
||
jobs:
|
||
build-and-deploy:
|
||
runs-on: runner
|
||
steps:
|
||
- name: Build and Deploy on Host
|
||
run: |
|
||
echo "=== Starting build and deploy ==="
|
||
|
||
# 检查并安装 Node.js 和 pnpm(容器内)
|
||
if ! command -v node &> /dev/null; then
|
||
echo "Installing Node.js in container..."
|
||
apk add --no-cache nodejs npm
|
||
fi
|
||
|
||
if ! command -v pnpm &> /dev/null; then
|
||
echo "Installing pnpm..."
|
||
npm install -g pnpm
|
||
fi
|
||
|
||
if ! command -v zip &> /dev/null; then
|
||
echo "Installing zip..."
|
||
apk add --no-cache zip
|
||
fi
|
||
|
||
if ! command -v scp &> /dev/null; then
|
||
echo "Installing openssh-client..."
|
||
apk add --no-cache openssh-client sshpass
|
||
fi
|
||
|
||
echo "Node version: $(node --version)"
|
||
echo "NPM version: $(npm --version)"
|
||
echo "PNPM version: $(pnpm --version)"
|
||
|
||
# 记录开始时间
|
||
START_TIME=$(date +%s)
|
||
|
||
WORK_DIR="/workspace/zy-client-a"
|
||
GITEA_REPO_PATH="/data/gitea/git/repositories/zy/zy-client-a.git"
|
||
|
||
# 初始化部署状态变量
|
||
DEPLOY_STATUS="success"
|
||
BUILT_PROJECTS=""
|
||
|
||
# 更新代码
|
||
if [ ! -d "$WORK_DIR/.git" ]; then
|
||
mkdir -p "$WORK_DIR"
|
||
git clone --depth 1 "file://$GITEA_REPO_PATH" "$WORK_DIR"
|
||
cd "$WORK_DIR"
|
||
OLD_HEAD=$(git rev-parse HEAD)
|
||
else
|
||
cd "$WORK_DIR"
|
||
OLD_HEAD=$(git rev-parse HEAD)
|
||
git fetch origin main
|
||
git reset --hard origin/main
|
||
fi
|
||
|
||
NEW_HEAD=$(git rev-parse HEAD)
|
||
CHANGED_FILES=$(git diff --name-only "$OLD_HEAD" "$NEW_HEAD" 2>/dev/null || git diff-tree --no-commit-id --name-only -r HEAD)
|
||
|
||
echo "Changed files: $CHANGED_FILES"
|
||
CHANGED_DIRS=$(echo "$CHANGED_FILES" | cut -d'/' -f1 | sort -u)
|
||
|
||
# 清空zip目录,确保只上传本次构建的文件
|
||
rm -rf zip
|
||
mkdir -p zip
|
||
|
||
# 构建项目
|
||
for dir in $CHANGED_DIRS; do
|
||
if [ -d "$dir" ] && [ -f "$dir/package.json" ]; then
|
||
echo "========================================="
|
||
echo "Building: $dir"
|
||
echo "========================================="
|
||
|
||
cd "$dir"
|
||
|
||
if ! pnpm install; then
|
||
echo "Error: pnpm install failed for $dir"
|
||
DEPLOY_STATUS="failed"
|
||
cd "$WORK_DIR"
|
||
continue
|
||
fi
|
||
|
||
if ! pnpm run build; then
|
||
echo "Error: pnpm run build failed for $dir"
|
||
DEPLOY_STATUS="failed"
|
||
cd "$WORK_DIR"
|
||
continue
|
||
fi
|
||
|
||
# 从 zip.js 提取 zip 文件名并打包 dist
|
||
if [ -d "dist" ]; then
|
||
if [ -f "zip.js" ]; then
|
||
ZIP_NAME=$(grep -o 'zip/[^"]*\.zip' zip.js | head -1 | sed 's|zip/||')
|
||
else
|
||
ZIP_NAME="${dir}.zip"
|
||
fi
|
||
if [ -n "$ZIP_NAME" ]; then
|
||
echo "Creating zip: $ZIP_NAME"
|
||
cd dist
|
||
if zip -r "../$ZIP_NAME" ./*; then
|
||
cd ..
|
||
mv "$ZIP_NAME" "$WORK_DIR/zip/$ZIP_NAME"
|
||
echo "Zip created: $WORK_DIR/zip/$ZIP_NAME"
|
||
BUILT_PROJECTS="${BUILT_PROJECTS}${dir}:${ZIP_NAME};"
|
||
else
|
||
echo "Error: Failed to create zip for $dir"
|
||
DEPLOY_STATUS="failed"
|
||
cd ..
|
||
fi
|
||
fi
|
||
fi
|
||
|
||
cd "$WORK_DIR"
|
||
fi
|
||
done
|
||
|
||
# 上传
|
||
if ls zip/*.zip 1> /dev/null 2>&1; then
|
||
echo "Uploading..."
|
||
|
||
if command -v sshpass &> /dev/null; then
|
||
# 直接上传,scp会自动覆盖同名文件
|
||
if sshpass -p '${{ secrets.SSH_REMOTE }}' scp -P 22 -o StrictHostKeyChecking=no zip/*.zip root@74.50.99.168:/opt/1panel/www/sites/aoe.jtgapp.cc/index/page/; then
|
||
echo "Upload completed!"
|
||
else
|
||
echo "Error: Upload failed"
|
||
DEPLOY_STATUS="failed"
|
||
fi
|
||
else
|
||
# 降级:直接使用 scp(需要配置 SSH 密钥)
|
||
if scp -P 22 -o StrictHostKeyChecking=no zip/*.zip root@74.50.99.168:/opt/1panel/www/sites/aoe.jtgapp.cc/index/page/; then
|
||
echo "Upload completed!"
|
||
else
|
||
echo "Error: Upload failed"
|
||
DEPLOY_STATUS="failed"
|
||
fi
|
||
fi
|
||
fi
|
||
|
||
# 发送 Telegram 通知
|
||
END_TIME=$(date +%s)
|
||
DURATION=$((END_TIME - START_TIME))
|
||
DURATION_MIN=$((DURATION / 60))
|
||
DURATION_SEC=$((DURATION % 60))
|
||
|
||
if [ -n "${{ secrets.TELEGRAM_BOT_TOKEN }}" ] && [ -n "${{ secrets.TELEGRAM_CHAT_ID }}" ]; then
|
||
echo "Sending Telegram notification..."
|
||
|
||
# 构建消息
|
||
if [ "$DEPLOY_STATUS" = "success" ]; then
|
||
MESSAGE="<b>🚀 部署通知</b>%0A%0A"
|
||
MESSAGE="${MESSAGE}<b>✅ 部署状态: 成功</b>%0A%0A"
|
||
MESSAGE="${MESSAGE}<b>📊 基本信息:</b>%0A"
|
||
MESSAGE="${MESSAGE}• <b>分支:</b> ${{ github.ref_name }}%0A"
|
||
MESSAGE="${MESSAGE}• <b>提交:</b> <code>${NEW_HEAD:0:8}</code>%0A"
|
||
MESSAGE="${MESSAGE}• <b>耗时:</b> ${DURATION_MIN}分${DURATION_SEC}秒%0A"
|
||
MESSAGE="${MESSAGE}• <b>日期:</b> $(date '+%Y-%m-%d %H:%M:%S')%0A%0A"
|
||
|
||
if [ -n "$BUILT_PROJECTS" ]; then
|
||
MESSAGE="${MESSAGE}<b>📦 部署项目:</b>%0A"
|
||
IFS=';' read -ra PROJECTS <<< "$BUILT_PROJECTS"
|
||
for entry in "${PROJECTS[@]}"; do
|
||
if [ -n "$entry" ]; then
|
||
PROJECT_NAME=$(echo "$entry" | cut -d':' -f1)
|
||
ZIP_NAME=$(echo "$entry" | cut -d':' -f2)
|
||
MESSAGE="${MESSAGE}• <code>${PROJECT_NAME}</code>: <code>${ZIP_NAME}</code>%0A"
|
||
fi
|
||
done
|
||
fi
|
||
else
|
||
MESSAGE="<b>🚀 部署通知</b>%0A%0A"
|
||
MESSAGE="${MESSAGE}<b>❌ 部署状态: 失败</b>%0A%0A"
|
||
MESSAGE="${MESSAGE}<b>📊 基本信息:</b>%0A"
|
||
MESSAGE="${MESSAGE}• <b>分支:</b> ${{ github.ref_name }}%0A"
|
||
MESSAGE="${MESSAGE}• <b>提交:</b> <code>${NEW_HEAD:0:8}</code>%0A"
|
||
MESSAGE="${MESSAGE}• <b>耗时:</b> ${DURATION_MIN}分${DURATION_SEC}秒%0A"
|
||
MESSAGE="${MESSAGE}• <b>日期:</b> $(date '+%Y-%m-%d %H:%M:%S')%0A%0A"
|
||
MESSAGE="${MESSAGE}<b>⚠️ 请检查构建日志获取详细错误信息</b>"
|
||
fi
|
||
|
||
# 发送到 Telegram(最多重试3次)
|
||
for i in 1 2 3; do
|
||
RESPONSE=$(wget -qO- --post-data="chat_id=${{ secrets.TELEGRAM_CHAT_ID }}&text=${MESSAGE}&parse_mode=HTML" \
|
||
"https://api.telegram.org/bot${{ secrets.TELEGRAM_BOT_TOKEN }}/sendMessage" 2>&1)
|
||
|
||
if echo "$RESPONSE" | grep -q '"ok":true'; then
|
||
echo "Telegram notification sent successfully"
|
||
break
|
||
else
|
||
echo "Failed to send Telegram notification (attempt $i/3)"
|
||
if [ $i -lt 3 ]; then
|
||
sleep 3
|
||
fi
|
||
fi
|
||
done
|
||
else
|
||
echo "Skipping Telegram notification (secrets not configured)"
|
||
fi
|
||
|
||
# 如果部署失败,退出码为1
|
||
if [ "$DEPLOY_STATUS" = "failed" ]; then
|
||
exit 1
|
||
fi
|