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 [ -f "zip.js" ] && [ -d "dist" ]; then ZIP_NAME=$(grep -o 'zip/[^"]*\.zip' zip.js | head -1 | sed 's|zip/||') 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="🚀 部署通知%0A%0A" MESSAGE="${MESSAGE}✅ 部署状态: 成功%0A%0A" MESSAGE="${MESSAGE}📊 基本信息:%0A" MESSAGE="${MESSAGE}• 分支: ${{ github.ref_name }}%0A" MESSAGE="${MESSAGE}• 提交: ${NEW_HEAD:0:8}%0A" MESSAGE="${MESSAGE}• 耗时: ${DURATION_MIN}分${DURATION_SEC}秒%0A" MESSAGE="${MESSAGE}• 日期: $(date '+%Y-%m-%d %H:%M:%S')%0A%0A" if [ -n "$BUILT_PROJECTS" ]; then MESSAGE="${MESSAGE}📦 部署项目:%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}• ${PROJECT_NAME}: ${ZIP_NAME}%0A" fi done fi else MESSAGE="🚀 部署通知%0A%0A" MESSAGE="${MESSAGE}❌ 部署状态: 失败%0A%0A" MESSAGE="${MESSAGE}📊 基本信息:%0A" MESSAGE="${MESSAGE}• 分支: ${{ github.ref_name }}%0A" MESSAGE="${MESSAGE}• 提交: ${NEW_HEAD:0:8}%0A" MESSAGE="${MESSAGE}• 耗时: ${DURATION_MIN}分${DURATION_SEC}秒%0A" MESSAGE="${MESSAGE}• 日期: $(date '+%Y-%m-%d %H:%M:%S')%0A%0A" MESSAGE="${MESSAGE}⚠️ 请检查构建日志获取详细错误信息" 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