name: Deploy to Production on: push: branches: - main schedule: - cron: '0 1 * * *' # UTC 01:00 = 北京时间 09:00 workflow_dispatch: concurrency: group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true env: TZ: Asia/Shanghai jobs: # ============================================================ # Job 0: Pre-Flight Checks (前置检查) # ============================================================ pre-check: runs-on: ubuntu-latest timeout-minutes: 2 outputs: can_deploy: ${{ steps.repo-check.outputs.can_deploy }} duration: ${{ steps.end-pre-check.outputs.duration }} steps: - name: Start timing id: start-pre-check run: echo "start_time=$(date +%s)" >> $GITHUB_OUTPUT - name: Checkout code uses: actions/checkout@v4 with: fetch-depth: 1 - name: Validate repository id: repo-check run: | if [ "${{ github.repository }}" != "zqlit/blog" ]; then echo "❌ 只能在主仓库执行部署" echo "can_deploy=false" >> $GITHUB_OUTPUT exit 1 fi echo "✅ 仓库验证通过" echo "can_deploy=true" >> $GITHUB_OUTPUT - name: Validate commit (only for push events) if: github.event_name == 'push' id: commit-check run: | COMMIT_AUTHOR="${{ github.event.head_commit.author.name }}" COMMIT_MESSAGE="${{ github.event.head_commit.message }}" echo "📝 提交作者: $COMMIT_AUTHOR" echo "📄 提交信息: $COMMIT_MESSAGE" if echo "$COMMIT_MESSAGE" | grep -qE "^(feat|fix|chore|docs|style|refactor|test): "; then echo "✅ 提交信息符合规范" else echo "⚠️ 提交信息格式建议: feat/fix/chore/docs/style/refactor/test: description" fi - name: Check for new commits (only for cron) if: github.event_name == 'schedule' id: cron-check run: | LAST_COMMIT_TIME=$(git log -1 --format=%ct) CURRENT_TIME=$(date +%s) DIFF_HOURS=$(( (CURRENT_TIME - LAST_COMMIT_TIME) / 3600 )) echo "⏰ 最后一次提交时间: $(date -d @$LAST_COMMIT_TIME)" echo "⏰ 当前时间: $(date)" echo "⏰ 距离上次提交: $DIFF_HOURS 小时" if [ "$DIFF_HOURS" -lt 1 ]; then echo "✅ 最近有提交,继续构建" echo "can_deploy=true" >> $GITHUB_OUTPUT else echo "⏭️ 超过 1 小时没有新提交,跳过定时构建" echo "can_deploy=false" >> $GITHUB_OUTPUT exit 0 fi - name: Summary run: | echo "## 🔍 前置检查完成" >> $GITHUB_STEP_SUMMARY echo "" >> $GITHUB_STEP_SUMMARY echo "- **仓库**: ${{ github.repository }}" >> $GITHUB_STEP_SUMMARY echo "- **分支**: ${{ github.ref_name }}" >> $GITHUB_STEP_SUMMARY echo "- **触发方式**: ${{ github.event_name }}" >> $GITHUB_STEP_SUMMARY echo "- **Commit SHA**: ${{ github.sha }}" >> $GITHUB_STEP_SUMMARY - name: End timing id: end-pre-check run: | end_time=$(date +%s) start_time=${{ steps.start-pre-check.outputs.start_time }} duration=$((end_time - start_time)) echo "duration=${duration}" >> $GITHUB_OUTPUT echo "## ⏱️ Pre-check 耗时: ${duration}秒" >> $GITHUB_STEP_SUMMARY # ============================================================ # Job 1: Build (构建) # ============================================================ build: runs-on: ubuntu-latest timeout-minutes: 15 permissions: contents: write outputs: build_hash: ${{ steps.hash.outputs.build_hash }} duration: ${{ steps.end-build.outputs.duration }} file_count: ${{ steps.stats.outputs.file_count }} total_size: ${{ steps.stats.outputs.total_size }} skipped: ${{ steps.upload.outputs.skipped }} needs: pre-check if: needs.pre-check.outputs.can_deploy == 'true' steps: - name: Start timing id: start-build run: echo "start_time=$(date +%s)" >> $GITHUB_OUTPUT - name: Checkout code uses: actions/checkout@v4 with: fetch-depth: 0 - name: Setup Hugo uses: peaceiris/actions-hugo@v2 with: hugo-version: '0.128.2' extended: true - name: Setup Node uses: actions/setup-node@v4 with: node-version: '22' cache: 'npm' - name: Install Node.js dependencies run: npm ci - name: Cache Hugo resources uses: actions/cache@v4 id: hugo-cache with: path: | resources/_gen /home/runner/.cache/hugo_cache key: ${{ runner.os }}-hugo-${{ hashFiles('go.sum', 'package-lock.json', 'hugo.toml', 'config/_default/*.toml') }} restore-keys: | ${{ runner.os }}-hugo- - name: Run Pre-Build Scripts shell: pwsh run: ./scripts/add_draft_to_hidden.ps1 - name: Optimize Images continue-on-error: true timeout-minutes: 5 run: node scripts/optimize_images.js - name: Commit Optimized Images continue-on-error: true run: | git config --global user.name "GitHub Actions" git config --global user.email "actions@github.com" git add content/posts static if ! git diff --staged --quiet; then git commit -m "chore: auto-optimize images [skip ci]" else echo "No changes to commit" fi - name: Build Hugo site timeout-minutes: 10 run: rm -rf public && hugo --minify - name: Generate build hash id: hash run: | BUILD_HASH=$(find public -type f -print0 | sort -z | xargs -0 sha256sum | sha256sum | awk '{print $1}') echo "build_hash=${BUILD_HASH}" >> $GITHUB_OUTPUT echo "$BUILD_HASH" > public/.build_hash - name: Build statistics id: stats run: | FILE_COUNT=$(find public -type f | wc -l) TOTAL_SIZE=$(du -sh public | awk '{print $1}') echo "file_count=${FILE_COUNT}" >> $GITHUB_OUTPUT echo "total_size=${TOTAL_SIZE}" >> $GITHUB_OUTPUT - name: Setup Python uses: actions/setup-python@v4 with: python-version: '3.x' - name: Install coscmd run: pip install -U coscmd - name: Configure coscmd env: COS_SECRET_ID: ${{ secrets.COS_SECRET_ID }} COS_SECRET_KEY: ${{ secrets.COS_SECRET_KEY }} COS_BUCKET: ${{ secrets.COS_BUCKET }} COS_REGION: ${{ secrets.COS_REGION }} run: coscmd config -a $COS_SECRET_ID -s $COS_SECRET_KEY -b $COS_BUCKET -r $COS_REGION -m 30 - name: Upload to Tencent COS continue-on-error: true run: | echo "📤 打包并上传到腾讯云 COS..." tar -czf public.tar.gz public/ coscmd upload public.tar.gz /public.tar.gz coscmd upload public/.build_hash /__build_hash - name: Upload to UpYun and check hash env: UPYUN_SERVICE: ${{ secrets.UPYUN_BUCKET }} UPYUN_OPERATOR: ${{ secrets.UPYUN_OPERATOR }} UPYUN_PASSWORD: ${{ secrets.UPYUN_PASSWORD }} id: upload run: | echo "📤 上传构建产物到 UpYun..." UPX_VERSION="0.4.9" UPX_URL="https://collection.b0.upaiyun.com/softwares/upx/upx_${UPX_VERSION}_linux_amd64.tar.gz" UPX_BIN="/tmp/upyun-upx" if [ ! -x "$UPX_BIN" ]; then curl -sL "$UPX_URL" -o /tmp/upx.tar.gz tar -xzf /tmp/upx.tar.gz -C /tmp mv /tmp/upx "$UPX_BIN" chmod +x "$UPX_BIN" fi for i in 1 2 3; do echo "🔐 UpYun 登录 (尝试 $i/3)..." if "$UPX_BIN" login "$UPYUN_SERVICE" "$UPYUN_OPERATOR" "$UPYUN_PASSWORD" 2>&1; then echo "✅ 登录成功" break else echo "⚠️ 登录失败,等待 5 秒后重试..." sleep 5 fi done # 获取上次部署的哈希 LAST_HASH=$("$UPX_BIN" get /__build_hash 2>/dev/null || echo "") CURRENT_HASH=$(cat public/.build_hash) echo "上次部署 hash: $LAST_HASH" echo "当前构建 hash: $CURRENT_HASH" if [ "$CURRENT_HASH" = "$LAST_HASH" ]; then echo "✅ 构建产物无变化,跳过上传" echo "skipped=true" >> $GITHUB_OUTPUT else echo "🔄 发现变化,开始上传..." "$UPX_BIN" sync public/ / -w 10 --delete --strong "$UPX_BIN" put public/.build_hash /__build_hash echo "✅ 上传完成" echo "skipped=false" >> $GITHUB_OUTPUT fi - name: Push Image Optimizations continue-on-error: true run: | git fetch origin main git stash push -m "temp stash for rebase" || true git rebase origin/main || true git stash pop || true if git log --oneline -1 | grep -q "\[skip ci\]"; then git push origin HEAD:main else echo "No auto-commits to push" fi - name: End timing id: end-build run: | end_time=$(date +%s) start_time=${{ steps.start-build.outputs.start_time }} duration=$((end_time - start_time)) echo "duration=${duration}" >> $GITHUB_OUTPUT echo "## ⏱️ Build 耗时: ${duration}秒" >> $GITHUB_STEP_SUMMARY echo "" >> $GITHUB_STEP_SUMMARY echo "### 📊 构建统计" >> $GITHUB_STEP_SUMMARY echo "- **文件总数**: ${{ steps.stats.outputs.file_count }}" >> $GITHUB_STEP_SUMMARY echo "- **总大小**: ${{ steps.stats.outputs.total_size }}" >> $GITHUB_STEP_SUMMARY echo "- **构建哈希**: ${{ steps.hash.outputs.build_hash }}" >> $GITHUB_STEP_SUMMARY echo "- **Hugo 缓存**: ${{ steps.hugo-cache.outputs.cache-hit == 'true' && '✅ 命中' || '🔄 未命中' }}" >> $GITHUB_STEP_SUMMARY # ============================================================ # Job 3: Deploy to EdgeOne Pages (并行) # ============================================================ deploy-edgeone: runs-on: ubuntu-latest timeout-minutes: 20 permissions: contents: read needs: build outputs: deployed: ${{ steps.check.outputs.deployed }} duration: ${{ steps.end-edgeone.outputs.duration }} download_duration: ${{ steps.download-files.outputs.download_duration }} upload_duration: ${{ steps.end-edgeone-upload.outputs.duration }} steps: - name: Start timing id: start-edgeone run: echo "start_time=$(date +%s)" >> $GITHUB_OUTPUT - name: Get last build hash from UpYun id: last-hash env: UPYUN_SERVICE: ${{ secrets.UPYUN_BUCKET }} UPYUN_OPERATOR: ${{ secrets.UPYUN_OPERATOR }} UPYUN_PASSWORD: ${{ secrets.UPYUN_PASSWORD }} run: | echo "🔍 从 UpYun 获取上次部署的 hash..." UPX_VERSION="0.4.9" UPX_URL="https://collection.b0.upaiyun.com/softwares/upx/upx_${UPX_VERSION}_linux_amd64.tar.gz" UPX_BIN="/tmp/upyun-upx" if [ ! -x "$UPX_BIN" ]; then curl -sL "$UPX_URL" -o /tmp/upx.tar.gz tar -xzf /tmp/upx.tar.gz -C /tmp mv /tmp/upx "$UPX_BIN" chmod +x "$UPX_BIN" fi for i in 1 2 3; do echo "🔐 UpYun 登录 (尝试 $i/3)..." if "$UPX_BIN" login "$UPYUN_SERVICE" "$UPYUN_OPERATOR" "$UPYUN_PASSWORD" 2>&1; then echo "✅ 登录成功" break else echo "⚠️ 登录失败,等待 5 秒后重试..." sleep 5 fi done LAST_HASH=$("$UPX_BIN" get /__build_hash 2>/dev/null || echo "") if [ -z "$LAST_HASH" ]; then echo "⚠️ 没有找到上次部署的 hash(首次部署)" else echo "上次部署 hash: $LAST_HASH" fi echo "last_hash=${LAST_HASH}" >> $GITHUB_OUTPUT - name: Checkout code (for scripts) uses: actions/checkout@v4 with: fetch-depth: 1 - name: Setup Python uses: actions/setup-python@v4 with: python-version: '3.x' - name: Install coscmd run: pip install -U coscmd - name: Configure coscmd env: COS_SECRET_ID: ${{ secrets.COS_SECRET_ID }} COS_SECRET_KEY: ${{ secrets.COS_SECRET_KEY }} COS_BUCKET: ${{ secrets.COS_BUCKET }} COS_REGION: ${{ secrets.COS_REGION }} run: coscmd config -a $COS_SECRET_ID -s $COS_SECRET_KEY -b $COS_BUCKET -r $COS_REGION - name: Get current hash from COS id: download run: | echo "📥 从腾讯云 COS 获取 build_hash..." coscmd get /__build_hash /tmp/current_hash 2>/dev/null || echo "" CURRENT_HASH=$(cat /tmp/current_hash 2>/dev/null || echo "") echo "current_hash=${CURRENT_HASH}" >> $GITHUB_OUTPUT - name: Check if deployment is needed id: check run: | CURRENT_HASH="${{ steps.download.outputs.current_hash }}" LAST_HASH="${{ steps.last-hash.outputs.last_hash }}" echo "当前 build_hash: $CURRENT_HASH" echo "上次部署 hash: $LAST_HASH" if [ -z "$LAST_HASH" ] || [ "$CURRENT_HASH" != "$LAST_HASH" ]; then echo "🔄 构建产物有变化,需要部署到 EdgeOne" echo "deployed=true" >> $GITHUB_OUTPUT else echo "✅ 构建产物无变化,跳过 EdgeOne 部署" echo "deployed=false" >> $GITHUB_OUTPUT fi - name: Download files from COS if: steps.check.outputs.deployed == 'true' id: download-files run: | echo "📥 从腾讯云 COS 下载构建产物..." DOWNLOAD_START=$(date +%s) coscmd get /public.tar.gz /tmp/public.tar.gz tar -xzf /tmp/public.tar.gz DOWNLOAD_END=$(date +%s) DOWNLOAD_DURATION=$((DOWNLOAD_END - DOWNLOAD_START)) echo "download_duration=${DOWNLOAD_DURATION}" >> $GITHUB_OUTPUT - name: Start upload timing if: steps.check.outputs.deployed == 'true' id: start-edgeone-upload run: echo "start_time=$(date +%s)" >> $GITHUB_OUTPUT - name: Deploy to EdgeOne Pages if: steps.check.outputs.deployed == 'true' env: EDGEONE_API_TOKEN: ${{ secrets.EDGEONE_API_TOKEN }} run: | chmod +x scripts/deploy_edgeone.sh ./scripts/deploy_edgeone.sh hugo-blog ./public overseas - name: End upload timing if: steps.check.outputs.deployed == 'true' id: end-edgeone-upload run: | end_time=$(date +%s) start_time=${{ steps.start-edgeone-upload.outputs.start_time }} duration=$((end_time - start_time)) echo "duration=${duration}" >> $GITHUB_OUTPUT - name: End timing id: end-edgeone run: | end_time=$(date +%s) start_time=${{ steps.start-edgeone.outputs.start_time }} duration=$((end_time - start_time)) echo "duration=${duration}" >> $GITHUB_OUTPUT if [ "${{ steps.check.outputs.deployed }}" = "true" ]; then echo "## ⏱️ Deploy EdgeOne 耗时: ${duration}秒" >> $GITHUB_STEP_SUMMARY echo "" >> $GITHUB_STEP_SUMMARY echo "### 📊 部署统计" >> $GITHUB_STEP_SUMMARY echo "- **下载: ${{ steps.download.outputs.download_duration }}s**" >> $GITHUB_STEP_SUMMARY echo "- **上传部署**: ${duration}秒" >> $GITHUB_STEP_SUMMARY echo "- **文件总数**: ${{ needs.build.outputs.file_count }}" >> $GITHUB_STEP_SUMMARY else echo "## EdgeOne 部署已跳过(构建产物无变化)" >> $GITHUB_STEP_SUMMARY echo "总耗时: ${duration}秒" >> $GITHUB_STEP_SUMMARY fi # ============================================================ # Job 4: Deploy to UpYun (并行) # ============================================================ deploy-upyun: runs-on: ubuntu-latest timeout-minutes: 5 permissions: contents: read needs: build outputs: deployed: ${{ steps.check.outputs.deployed }} duration: ${{ steps.end-upyun.outputs.duration }} steps: - name: Start timing id: start-upyun run: echo "start_time=$(date +%s)" >> $GITHUB_OUTPUT - name: Get last build hash from UpYun id: last-hash env: UPYUN_SERVICE: ${{ secrets.UPYUN_BUCKET }} UPYUN_OPERATOR: ${{ secrets.UPYUN_OPERATOR }} UPYUN_PASSWORD: ${{ secrets.UPYUN_PASSWORD }} run: | echo "🔍 从 UpYun 获取上次部署的 hash..." UPX_VERSION="0.4.9" UPX_URL="https://collection.b0.upaiyun.com/softwares/upx/upx_${UPX_VERSION}_linux_amd64.tar.gz" UPX_BIN="/tmp/upyun-upx" if [ ! -x "$UPX_BIN" ]; then curl -sL "$UPX_URL" -o /tmp/upx.tar.gz tar -xzf /tmp/upx.tar.gz -C /tmp mv /tmp/upx "$UPX_BIN" chmod +x "$UPX_BIN" fi for i in 1 2 3; do echo "🔐 UpYun 登录 (尝试 $i/3)..." if "$UPX_BIN" login "$UPYUN_SERVICE" "$UPYUN_OPERATOR" "$UPYUN_PASSWORD" 2>&1; then echo "✅ 登录成功" break else echo "⚠️ 登录失败,等待 5 秒后重试..." sleep 5 fi done LAST_HASH=$("$UPX_BIN" get /__build_hash 2>/dev/null || echo "") if [ -z "$LAST_HASH" ]; then echo "⚠️ 没有找到上次部署的 hash(首次部署)" else echo "上次部署 hash: $LAST_HASH" fi echo "last_hash=${LAST_HASH}" >> $GITHUB_OUTPUT - name: Get current hash from COS id: download env: COS_SECRET_ID: ${{ secrets.COS_SECRET_ID }} COS_SECRET_KEY: ${{ secrets.COS_SECRET_KEY }} COS_BUCKET: ${{ secrets.COS_BUCKET }} COS_REGION: ${{ secrets.COS_REGION }} run: | echo "📥 从腾讯云 COS 获取 build_hash..." pip install -U coscmd coscmd config -a $COS_SECRET_ID -s $COS_SECRET_KEY -b $COS_BUCKET -r $COS_REGION coscmd get /__build_hash /tmp/current_hash 2>/dev/null || echo "" CURRENT_HASH=$(cat /tmp/current_hash 2>/dev/null || echo "") echo "current_hash=${CURRENT_HASH}" >> $GITHUB_OUTPUT - name: Check if deployment is needed id: check run: | CURRENT_HASH="${{ steps.download.outputs.current_hash }}" LAST_HASH="${{ steps.last-hash.outputs.last_hash }}" echo "当前 build_hash: $CURRENT_HASH" echo "上次部署 hash: $LAST_HASH" if [ -z "$LAST_HASH" ] || [ "$CURRENT_HASH" != "$LAST_HASH" ]; then echo "🔄 构建产物有变化,UpYun 已同步最新内容" echo "deployed=true" >> $GITHUB_OUTPUT else echo "✅ 构建产物无变化,UpYun 无需更新" echo "deployed=false" >> $GITHUB_OUTPUT fi - name: End timing id: end-upyun run: | end_time=$(date +%s) total_start_time=${{ steps.start-upyun.outputs.start_time }} total_duration=$((end_time - total_start_time)) echo "duration=${total_duration}" >> $GITHUB_OUTPUT if [ "${{ steps.check.outputs.deployed }}" = "true" ]; then echo "## ⏱️ Deploy UpYun 耗时: ${total_duration}秒" >> $GITHUB_STEP_SUMMARY echo "" >> $GITHUB_STEP_SUMMARY echo "### 📊 部署统计" >> $GITHUB_STEP_SUMMARY echo "- **下载: ${{ steps.download.outputs.download_duration }}s**" >> $GITHUB_STEP_SUMMARY echo "- **文件总数**: ${{ needs.build.outputs.file_count }}" >> $GITHUB_STEP_SUMMARY echo "- **总大小**: ${{ needs.build.outputs.total_size }}" >> $GITHUB_STEP_SUMMARY else echo "## UpYun 部署已跳过(构建产物无变化)" >> $GITHUB_STEP_SUMMARY echo "总耗时: ${total_duration}秒" >> $GITHUB_STEP_SUMMARY fi # ============================================================ # Job 5: CDN Refresh & Notifications (after all deployments) # ============================================================ finalize: runs-on: ubuntu-latest timeout-minutes: 5 permissions: contents: write needs: [pre-check, build, deploy-edgeone, deploy-upyun] if: always() && needs.build.result == 'success' && needs.deploy-edgeone.result == 'success' && needs.deploy-upyun.result == 'success' steps: - name: Start timing id: start-finalize run: echo "start_time=$(date +%s)" >> $GITHUB_OUTPUT - name: Checkout code uses: actions/checkout@v4 with: fetch-depth: 1 - name: Setup Node uses: actions/setup-node@v4 with: node-version: '22' cache: 'npm' - name: Install Node.js dependencies run: npm ci - name: Determine deployment status id: deploy-status run: | EDGEONE_DEPLOYED="${{ needs.deploy-edgeone.outputs.deployed }}" UPYUN_DEPLOYED="${{ needs.deploy-upyun.outputs.deployed }}" echo "EdgeOne deployed: $EDGEONE_DEPLOYED" echo "UpYun deployed: $UPYUN_DEPLOYED" if [ "$EDGEONE_DEPLOYED" = "true" ] || [ "$UPYUN_DEPLOYED" = "true" ]; then echo "any_deployed=true" >> $GITHUB_OUTPUT else echo "any_deployed=false" >> $GITHUB_OUTPUT fi - name: Refresh DogeCloud CDN if: steps.deploy-status.outputs.any_deployed == 'true' env: DOGECLOUD_ACCESS_KEY: ${{ secrets.DOGECLOUD_ACCESS_KEY }} DOGECLOUD_SECRET_KEY: ${{ secrets.DOGECLOUD_SECRET_KEY }} CDN_URL_LIST: ${{ secrets.CDN_URL_LIST }} run: node scripts/refresh_cdn.js - name: Send Telegram notification with detailed timing env: TELEGRAM_BOT_TOKEN: ${{ secrets.TELEGRAM_BOT_TOKEN }} TELEGRAM_CHAT_ID: ${{ secrets.TELEGRAM_CHAT_ID }} run: | if [ -z "$TELEGRAM_BOT_TOKEN" ] || [ -z "$TELEGRAM_CHAT_ID" ]; then echo "⚠️ Telegram secrets 未配置,跳过通知" exit 0 fi PRECHECK_DUR="${{ needs.pre-check.outputs.duration }}" BUILD_DUR="${{ needs.build.outputs.duration }}" EDGEONE_DUR="${{ needs.deploy-edgeone.outputs.duration }}" EDGEONE_DEPLOYED="${{ needs.deploy-edgeone.outputs.deployed }}" UPYUN_DUR="${{ needs.deploy-upyun.outputs.duration }}" UPYUN_DEPLOYED="${{ needs.deploy-upyun.outputs.deployed }}" FILE_COUNT="${{ needs.build.outputs.file_count }}" TOTAL_SIZE="${{ needs.build.outputs.total_size }}" EDGEONE_DETAIL="" if [ "$EDGEONE_DEPLOYED" = "true" ]; then EDGEONE_DOWNLOAD="${{ needs.deploy-edgeone.outputs.download_duration }}" EDGEONE_UPLOAD="${{ needs.deploy-edgeone.outputs.upload_duration }}" EDGEONE_DETAIL=$(printf "\n 📥 下载: %ss\n 📤 上传: %ss" "$EDGEONE_DOWNLOAD" "$EDGEONE_UPLOAD") fi UPYUN_DETAIL="" if [ "$UPYUN_DEPLOYED" = "true" ]; then UPYUN_DOWNLOAD="${{ needs.deploy-upyun.outputs.download_duration }}" UPYUN_UPLOAD="${{ needs.deploy-upyun.outputs.upload_duration }}" UPYUN_DETAIL=$(printf "\n 📥 下载: %ss\n 📤 上传: %ss" "$UPYUN_DOWNLOAD" "$UPYUN_UPLOAD") fi if [ "${{ steps.deploy-status.outputs.any_deployed }}" = "true" ]; then STATUS_ICON="🎉" STATUS_TEXT="部署成功" else STATUS_ICON="⏭️" STATUS_TEXT="无变化,跳过部署" fi EDGEONE_STATUS=$([ "$EDGEONE_DEPLOYED" = "true" ] && echo "✅ 已部署" || echo "⏭️ 跳过") UPYUN_STATUS=$([ "$UPYUN_DEPLOYED" = "true" ] && echo "✅ 已部署" || echo "⏭️ 跳过") CURRENT_TIME=$(date +'%Y-%m-%d %H:%M:%S') MESSAGE="$STATUS_ICON *$STATUS_TEXT*" MESSAGE="$MESSAGE"$'\n\n' MESSAGE="$MESSAGE""📦 *项目*: \`${{ github.repository }}\`"$'\n' MESSAGE="$MESSAGE""🌿 *分支*: \`${{ github.ref_name }}\`"$'\n' MESSAGE="$MESSAGE""🔗 *Commit*: \`${{ github.sha }}\`"$'\n' MESSAGE="$MESSAGE""⏰ *时间*: $CURRENT_TIME"$'\n' MESSAGE="$MESSAGE""🚀 *触发方式*: ${{ github.event_name }}"$'\n\n' MESSAGE="$MESSAGE""━━━━━━━━━━━━━━━━━━━━━━"$'\n' MESSAGE="$MESSAGE""📊 *构建统计*"$'\n' MESSAGE="$MESSAGE""━━━━━━━━━━━━━━━━━━━━━━"$'\n' MESSAGE="$MESSAGE""📁 文件总数: $FILE_COUNT"$'\n' MESSAGE="$MESSAGE""💾 总大小: $TOTAL_SIZE"$'\n\n' MESSAGE="$MESSAGE""━━━━━━━━━━━━━━━━━━━━━━"$'\n' MESSAGE="$MESSAGE""⏱️ *耗时统计*"$'\n' MESSAGE="$MESSAGE""━━━━━━━━━━━━━━━━━━━━━━"$'\n' MESSAGE="$MESSAGE""🔍 Pre-check: ${PRECHECK_DUR}s"$'\n' MESSAGE="$MESSAGE""🏗️ Build: ${BUILD_DUR}s"$'\n' MESSAGE="$MESSAGE""🌐 EdgeOne: ${EDGEONE_DUR}s$EDGEONE_DETAIL"$'\n' MESSAGE="$MESSAGE""☁️ UpYun: ${UPYUN_DUR}s$UPYUN_DETAIL"$'\n\n' MESSAGE="$MESSAGE""━━━━━━━━━━━━━━━━━━━━━━"$'\n' MESSAGE="$MESSAGE""📌 *部署状态*"$'\n' MESSAGE="$MESSAGE""━━━━━━━━━━━━━━━━━━━━━━"$'\n' MESSAGE="$MESSAGE""🌐 EdgeOne Pages: $EDGEONE_STATUS"$'\n' MESSAGE="$MESSAGE""☁️ UpYun: $UPYUN_STATUS"$'\n\n' MESSAGE="$MESSAGE""🔗 [查看详情](https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }})" curl -s -X POST "https://api.telegram.org/bot${TELEGRAM_BOT_TOKEN}/sendMessage" \ -d chat_id="${TELEGRAM_CHAT_ID}" \ -d text="$MESSAGE" \ -d parse_mode="Markdown" \ -d disable_web_page_preview=true - name: Send Feishu notification with detailed timing env: FEISHU_WEBHOOK_URL: ${{ secrets.FEISHU_WEBHOOK_URL }} run: | if [ -z "$FEISHU_WEBHOOK_URL" ]; then echo "⚠️ 飞书 Webhook URL 未配置,跳过通知" exit 0 fi PRECHECK_DUR="${{ needs.pre-check.outputs.duration }}" BUILD_DUR="${{ needs.build.outputs.duration }}" EDGEONE_DUR="${{ needs.deploy-edgeone.outputs.duration }}" EDGEONE_DEPLOYED="${{ needs.deploy-edgeone.outputs.deployed }}" UPYUN_DUR="${{ needs.deploy-upyun.outputs.duration }}" UPYUN_DEPLOYED="${{ needs.deploy-upyun.outputs.deployed }}" FILE_COUNT="${{ needs.build.outputs.file_count }}" TOTAL_SIZE="${{ needs.build.outputs.total_size }}" EDGEONE_DETAIL="" if [ "$EDGEONE_DEPLOYED" = "true" ]; then EDGEONE_DOWNLOAD="${{ needs.deploy-edgeone.outputs.download_duration }}" EDGEONE_UPLOAD="${{ needs.deploy-edgeone.outputs.upload_duration }}" EDGEONE_DETAIL=$(printf "\n 📥 下载: %ss\n 📤 上传: %ss" "$EDGEONE_DOWNLOAD" "$EDGEONE_UPLOAD") fi UPYUN_DETAIL="" if [ "$UPYUN_DEPLOYED" = "true" ]; then UPYUN_DOWNLOAD="${{ needs.deploy-upyun.outputs.download_duration }}" UPYUN_UPLOAD="${{ needs.deploy-upyun.outputs.upload_duration }}" UPYUN_DETAIL=$(printf "\n 📥 下载: %ss\n 📤 上传: %ss" "$UPYUN_DOWNLOAD" "$UPYUN_UPLOAD") fi if [ "${{ steps.deploy-status.outputs.any_deployed }}" = "true" ]; then STATUS_ICON="🎉" STATUS_TEXT="部署成功" else STATUS_ICON="⏭️" STATUS_TEXT="无变化,跳过部署" fi EDGEONE_STATUS=$([ "$EDGEONE_DEPLOYED" = "true" ] && echo "✅ 已部署" || echo "⏭️ 跳过") UPYUN_STATUS=$([ "$UPYUN_DEPLOYED" = "true" ] && echo "✅ 已部署" || echo "⏭️ 跳过") CURRENT_TIME=$(date +'%Y-%m-%d %H:%M:%S') MESSAGE_TEXT="$STATUS_ICON $STATUS_TEXT" MESSAGE_TEXT="$MESSAGE_TEXT"$'\n\n' MESSAGE_TEXT="$MESSAGE_TEXT""📦 项目: ${{ github.repository }}"$'\n' MESSAGE_TEXT="$MESSAGE_TEXT""🌿 分支: ${{ github.ref_name }}"$'\n' MESSAGE_TEXT="$MESSAGE_TEXT""🔗 Commit: ${{ github.sha }}"$'\n' MESSAGE_TEXT="$MESSAGE_TEXT""⏰ 时间: $CURRENT_TIME"$'\n' MESSAGE_TEXT="$MESSAGE_TEXT""🚀 触发方式: ${{ github.event_name }}"$'\n\n' MESSAGE_TEXT="$MESSAGE_TEXT""━━━━━━━━━━━━━━━━━━━━━━"$'\n' MESSAGE_TEXT="$MESSAGE_TEXT""📊 构建统计"$'\n' MESSAGE_TEXT="$MESSAGE_TEXT""━━━━━━━━━━━━━━━━━━━━━━"$'\n' MESSAGE_TEXT="$MESSAGE_TEXT""📁 文件总数: $FILE_COUNT"$'\n' MESSAGE_TEXT="$MESSAGE_TEXT""💾 总大小: $TOTAL_SIZE"$'\n\n' MESSAGE_TEXT="$MESSAGE_TEXT""━━━━━━━━━━━━━━━━━━━━━━"$'\n' MESSAGE_TEXT="$MESSAGE_TEXT""⏱️ 耗时统计"$'\n' MESSAGE_TEXT="$MESSAGE_TEXT""━━━━━━━━━━━━━━━━━━━━━━"$'\n' MESSAGE_TEXT="$MESSAGE_TEXT""🔍 Pre-check: ${PRECHECK_DUR}s"$'\n' MESSAGE_TEXT="$MESSAGE_TEXT""🏗️ Build: ${BUILD_DUR}s"$'\n' MESSAGE_TEXT="$MESSAGE_TEXT""🌐 EdgeOne: ${EDGEONE_DUR}s$EDGEONE_DETAIL"$'\n' MESSAGE_TEXT="$MESSAGE_TEXT""☁️ UpYun: ${UPYUN_DUR}s$UPYUN_DETAIL"$'\n\n' MESSAGE_TEXT="$MESSAGE_TEXT""━━━━━━━━━━━━━━━━━━━━━━"$'\n' MESSAGE_TEXT="$MESSAGE_TEXT""📌 部署状态"$'\n' MESSAGE_TEXT="$MESSAGE_TEXT""━━━━━━━━━━━━━━━━━━━━━━"$'\n' MESSAGE_TEXT="$MESSAGE_TEXT""🌐 EdgeOne Pages: $EDGEONE_STATUS"$'\n' MESSAGE_TEXT="$MESSAGE_TEXT""☁️ UpYun: $UPYUN_STATUS"$'\n\n' MESSAGE_TEXT="$MESSAGE_TEXT""🔗 查看详情: https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}" echo "📤 发送飞书通知..." echo "Message length: ${#MESSAGE_TEXT}" RESPONSE=$(curl -s -w "\nHTTP_STATUS:%{http_code}" -X POST "$FEISHU_WEBHOOK_URL" \ -H "Content-Type: application/json" \ -d "$(jq -n --arg text "$MESSAGE_TEXT" '{"msg_type":"text","content":{"text":$text}}')") echo "飞书响应: $RESPONSE" - name: Get current date (CN) if: steps.deploy-status.outputs.any_deployed == 'true' id: date run: echo "date=$(date +'%Y-%m-%d %H:%M:%S')" >> $GITHUB_OUTPUT - name: Send email notification with detailed timing if: steps.deploy-status.outputs.any_deployed == 'true' uses: dawidd6/action-send-mail@v3 with: server_address: smtp.qq.com server_port: 465 secure: true username: ${{ secrets.MAIL_USERNAME }} password: ${{ secrets.MAIL_PASSWORD }} subject: "🎉 部署成功 - ${{ github.repository }} - ${{ steps.date.outputs.date }}" to: ${{ secrets.MAIL_USERNAME }} from: GitHub Actions <${{ github.event_name }}> body: | 🎉 部署成功 🎉 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 📦 项目信息 ────────────────────────────────── 项目: ${{ github.repository }} 分支: ${{ github.ref_name }} Commit: ${{ github.sha }} ⏰ 时间: ${{ steps.date.outputs.date }} 🚀 触发方式: ${{ github.event_name }} 📊 构建统计 ────────────────────────────────── 📁 文件总数: ${{ needs.build.outputs.file_count }} 💾 总大小: ${{ needs.build.outputs.total_size }} ⏱️ 耗时统计 ────────────────────────────────── 🔍 Pre-check: ${{ needs.pre-check.outputs.duration }}s 🏗️ Build: ${{ needs.build.outputs.duration }}s 🌐 EdgeOne Pages: ${{ needs.deploy-edgeone.outputs.duration }}s 📥 下载 COS: ${{ needs.deploy-edgeone.outputs.download_duration }}s 📤 上传部署: ${{ needs.deploy-edgeone.outputs.upload_duration }}s ☁️ UpYun: ${{ needs.deploy-upyun.outputs.duration }}s 📌 部署状态 ────────────────────────────────── 🌐 EdgeOne Pages: ${{ needs.deploy-edgeone.outputs.deployed == 'true' && '✅ 已部署' || '⏭️ 跳过(无变化)' }} ☁️ UpYun: ${{ needs.deploy-upyun.outputs.deployed == 'true' && '✅ 已部署' || '⏭️ 跳过(无变化)' }} 🔗 查看详情 ────────────────────────────────── https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }} ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ - name: Generate timing summary id: timing-summary run: | end_time=$(date +%s) start_time=${{ steps.start-finalize.outputs.start_time }} finalize_duration=$((end_time - start_time)) PRECHECK_DUR="${{ needs.pre-check.outputs.duration }}" BUILD_DUR="${{ needs.build.outputs.duration }}" EDGEONE_DUR="${{ needs.deploy-edgeone.outputs.duration }}" EDGEONE_DEPLOYED="${{ needs.deploy-edgeone.outputs.deployed }}" UPYUN_DUR="${{ needs.deploy-upyun.outputs.duration }}" UPYUN_DEPLOYED="${{ needs.deploy-upyun.outputs.deployed }}" if [ "$EDGEONE_DEPLOYED" = "true" ]; then EDGEONE_DOWNLOAD="${{ needs.deploy-edgeone.outputs.download_duration }}" EDGEONE_UPLOAD="${{ needs.deploy-edgeone.outputs.upload_duration }}" else EDGEONE_DOWNLOAD="0" EDGEONE_UPLOAD="0" fi if [ "$UPYUN_DEPLOYED" = "true" ]; then UPYUN_DOWNLOAD="${{ needs.deploy-upyun.outputs.download_duration }}" UPYUN_UPLOAD="${{ needs.deploy-upyun.outputs.upload_duration }}" else UPYUN_DOWNLOAD="0" UPYUN_UPLOAD="0" fi echo "## 📊 部署报告" >> $GITHUB_STEP_SUMMARY echo "" >> $GITHUB_STEP_SUMMARY echo "### 基本信息" >> $GITHUB_STEP_SUMMARY echo "- **项目**: ${{ github.repository }}" >> $GITHUB_STEP_SUMMARY echo "- **分支**: ${{ github.ref_name }}" >> $GITHUB_STEP_SUMMARY echo "- **Commit**: ${{ github.sha }}" >> $GITHUB_STEP_SUMMARY echo "- **触发方式**: ${{ github.event_name }}" >> $GITHUB_STEP_SUMMARY echo "- **文件总数**: ${{ needs.build.outputs.file_count }}" >> $GITHUB_STEP_SUMMARY echo "- **总大小**: ${{ needs.build.outputs.total_size }}" >> $GITHUB_STEP_SUMMARY echo "" >> $GITHUB_STEP_SUMMARY echo "### ⏱️ 耗时统计" >> $GITHUB_STEP_SUMMARY echo "" >> $GITHUB_STEP_SUMMARY echo "| 阶段 | 总耗时 | 下载 | 上传 |" >> $GITHUB_STEP_SUMMARY echo "|------|--------|------|------|" >> $GITHUB_STEP_SUMMARY echo "| Pre-check | ${PRECHECK_DUR}s | - | - |" >> $GITHUB_STEP_SUMMARY echo "| Build | ${BUILD_DUR}s | - | - |" >> $GITHUB_STEP_SUMMARY echo "| EdgeOne | ${EDGEONE_DUR}s | ${EDGEONE_DOWNLOAD}s | ${EDGEONE_UPLOAD}s |" >> $GITHUB_STEP_SUMMARY echo "| UpYun | ${UPYUN_DUR}s | ${UPYUN_DOWNLOAD}s | ${UPYUN_UPLOAD}s |" >> $GITHUB_STEP_SUMMARY echo "| Finalize | ${finalize_duration}s | - | - |" >> $GITHUB_STEP_SUMMARY echo "" >> $GITHUB_STEP_SUMMARY echo "### 🚀 部署状态" >> $GITHUB_STEP_SUMMARY echo "" >> $GITHUB_STEP_SUMMARY echo "| 目标 | 状态 |" >> $GITHUB_STEP_SUMMARY echo "|------|------|" >> $GITHUB_STEP_SUMMARY echo "| EdgeOne Pages | ${{ needs.deploy-edgeone.outputs.deployed == 'true' && '✅ 已部署' || '⏭️ 跳过(无变化)' }} |" >> $GITHUB_STEP_SUMMARY echo "| UpYun | ${{ needs.deploy-upyun.outputs.deployed == 'true' && '✅ 已部署' || '⏭️ 跳过(无变化)' }} |" >> $GITHUB_STEP_SUMMARY echo "| CDN 刷新 | ${{ steps.deploy-status.outputs.any_deployed == 'true' && '✅ 已刷新' || '⏭️ 跳过' }} |" >> $GITHUB_STEP_SUMMARY # ============================================================ # Job 6: Failure Notification (失败通知) # ============================================================ notify-failure: runs-on: ubuntu-latest timeout-minutes: 3 permissions: contents: read needs: [pre-check, build, deploy-edgeone, deploy-upyun, finalize] if: always() && (needs.pre-check.result == 'failure' || needs.build.result == 'failure' || needs.deploy-edgeone.result == 'failure' || needs.deploy-upyun.result == 'failure' || needs.finalize.result == 'failure') steps: - name: Send Telegram failure notification env: TELEGRAM_BOT_TOKEN: ${{ secrets.TELEGRAM_BOT_TOKEN }} TELEGRAM_CHAT_ID: ${{ secrets.TELEGRAM_CHAT_ID }} run: | if [ -z "$TELEGRAM_BOT_TOKEN" ] || [ -z "$TELEGRAM_CHAT_ID" ]; then echo "⚠️ Telegram secrets 未配置,跳过失败通知" exit 0 fi FAILURES="" if [ "${{ needs.pre-check.result }}" = "failure" ]; then FAILURES=$(printf "%s\n 🔴 Pre-check" "$FAILURES"); fi if [ "${{ needs.build.result }}" = "failure" ]; then FAILURES=$(printf "%s\n 🔴 Build" "$FAILURES"); fi if [ "${{ needs.deploy-edgeone.result }}" = "failure" ]; then FAILURES=$(printf "%s\n 🔴 Deploy EdgeOne" "$FAILURES"); fi if [ "${{ needs.deploy-upyun.result }}" = "failure" ]; then FAILURES=$(printf "%s\n 🔴 Deploy UpYun" "$FAILURES"); fi if [ "${{ needs.finalize.result }}" = "failure" ]; then FAILURES=$(printf "%s\n 🔴 Finalize" "$FAILURES"); fi PRECHECK_STATUS=$([ "${{ needs.pre-check.result }}" = "success" ] && echo "✅ 成功" || ([ "${{ needs.pre-check.result }}" = "failure" ] && echo "❌ 失败" || echo "⏭️ 跳过")) BUILD_STATUS=$([ "${{ needs.build.result }}" = "success" ] && echo "✅ 成功" || ([ "${{ needs.build.result }}" = "failure" ] && echo "❌ 失败" || echo "⏭️ 跳过")) EDGEONE_STATUS=$([ "${{ needs.deploy-edgeone.result }}" = "success" ] && echo "✅ 成功" || ([ "${{ needs.deploy-edgeone.result }}" = "failure" ] && echo "❌ 失败" || echo "⏭️ 跳过")) UPYUN_STATUS=$([ "${{ needs.deploy-upyun.result }}" = "success" ] && echo "✅ 成功" || ([ "${{ needs.deploy-upyun.result }}" = "failure" ] && echo "❌ 失败" || echo "⏭️ 跳过")) FINALIZE_STATUS=$([ "${{ needs.finalize.result }}" = "success" ] && echo "✅ 成功" || ([ "${{ needs.finalize.result }}" = "failure" ] && echo "❌ 失败" || echo "⏭️ 跳过")) CURRENT_TIME=$(date +'%Y-%m-%d %H:%M:%S') MESSAGE="💥 *部署失败*" MESSAGE="$MESSAGE"$'\n\n' MESSAGE="$MESSAGE""📦 *项目*: \`${{ github.repository }}\`"$'\n' MESSAGE="$MESSAGE""🌿 *分支*: \`${{ github.ref_name }}\`"$'\n' MESSAGE="$MESSAGE""🔗 *Commit*: \`${{ github.sha }}\`"$'\n' MESSAGE="$MESSAGE""⏰ *时间*: $CURRENT_TIME"$'\n' MESSAGE="$MESSAGE""🚀 *触发方式*: ${{ github.event_name }}"$'\n\n' MESSAGE="$MESSAGE""━━━━━━━━━━━━━━━━━━━━━━"$'\n' MESSAGE="$MESSAGE""⚠️ *失败阶段*"$'\n' MESSAGE="$MESSAGE""━━━━━━━━━━━━━━━━━━━━━━$FAILURES"$'\n\n' MESSAGE="$MESSAGE""━━━━━━━━━━━━━━━━━━━━━━"$'\n' MESSAGE="$MESSAGE""📊 *各阶段状态*"$'\n' MESSAGE="$MESSAGE""━━━━━━━━━━━━━━━━━━━━━━"$'\n' MESSAGE="$MESSAGE""🔍 Pre-check: $PRECHECK_STATUS"$'\n' MESSAGE="$MESSAGE""🏗️ Build: $BUILD_STATUS"$'\n' MESSAGE="$MESSAGE""🌐 Deploy EdgeOne: $EDGEONE_STATUS"$'\n' MESSAGE="$MESSAGE""☁️ Deploy UpYun: $UPYUN_STATUS"$'\n' MESSAGE="$MESSAGE""📤 Finalize: $FINALIZE_STATUS"$'\n\n' MESSAGE="$MESSAGE""🔗 [查看详情](https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }})" curl -s -X POST "https://api.telegram.org/bot${TELEGRAM_BOT_TOKEN}/sendMessage" \ -d chat_id="${TELEGRAM_CHAT_ID}" \ -d text="$MESSAGE" \ -d parse_mode="Markdown" \ -d disable_web_page_preview=true - name: Send Feishu failure notification env: FEISHU_WEBHOOK_URL: ${{ secrets.FEISHU_WEBHOOK_URL }} run: | if [ -z "$FEISHU_WEBHOOK_URL" ]; then echo "⚠️ 飞书 Webhook URL 未配置,跳过失败通知" exit 0 fi FAILURES="" if [ "${{ needs.pre-check.result }}" = "failure" ]; then FAILURES=$(printf "%s\n 🔴 Pre-check" "$FAILURES"); fi if [ "${{ needs.build.result }}" = "failure" ]; then FAILURES=$(printf "%s\n 🔴 Build" "$FAILURES"); fi if [ "${{ needs.deploy-edgeone.result }}" = "failure" ]; then FAILURES=$(printf "%s\n 🔴 Deploy EdgeOne" "$FAILURES"); fi if [ "${{ needs.deploy-upyun.result }}" = "failure" ]; then FAILURES=$(printf "%s\n 🔴 Deploy UpYun" "$FAILURES"); fi if [ "${{ needs.finalize.result }}" = "failure" ]; then FAILURES=$(printf "%s\n 🔴 Finalize" "$FAILURES"); fi PRECHECK_STATUS=$([ "${{ needs.pre-check.result }}" = "success" ] && echo "✅ 成功" || ([ "${{ needs.pre-check.result }}" = "failure" ] && echo "❌ 失败" || echo "⏭️ 跳过")) BUILD_STATUS=$([ "${{ needs.build.result }}" = "success" ] && echo "✅ 成功" || ([ "${{ needs.build.result }}" = "failure" ] && echo "❌ 失败" || echo "⏭️ 跳过")) EDGEONE_STATUS=$([ "${{ needs.deploy-edgeone.result }}" = "success" ] && echo "✅ 成功" || ([ "${{ needs.deploy-edgeone.result }}" = "failure" ] && echo "❌ 失败" || echo "⏭️ 跳过")) UPYUN_STATUS=$([ "${{ needs.deploy-upyun.result }}" = "success" ] && echo "✅ 成功" || ([ "${{ needs.deploy-upyun.result }}" = "failure" ] && echo "❌ 失败" || echo "⏭️ 跳过")) FINALIZE_STATUS=$([ "${{ needs.finalize.result }}" = "success" ] && echo "✅ 成功" || ([ "${{ needs.finalize.result }}" = "failure" ] && echo "❌ 失败" || echo "⏭️ 跳过")) CURRENT_TIME=$(date +'%Y-%m-%d %H:%M:%S') MESSAGE_TEXT="💥 部署失败" MESSAGE_TEXT="$MESSAGE_TEXT"$'\n\n' MESSAGE_TEXT="$MESSAGE_TEXT""📦 项目: ${{ github.repository }}"$'\n' MESSAGE_TEXT="$MESSAGE_TEXT""🌿 分支: ${{ github.ref_name }}"$'\n' MESSAGE_TEXT="$MESSAGE_TEXT""🔗 Commit: ${{ github.sha }}"$'\n' MESSAGE_TEXT="$MESSAGE_TEXT""⏰ 时间: $CURRENT_TIME"$'\n' MESSAGE_TEXT="$MESSAGE_TEXT""🚀 触发方式: ${{ github.event_name }}"$'\n\n' MESSAGE_TEXT="$MESSAGE_TEXT""━━━━━━━━━━━━━━━━━━━━━━"$'\n' MESSAGE_TEXT="$MESSAGE_TEXT""⚠️ 失败阶段"$'\n' MESSAGE_TEXT="$MESSAGE_TEXT""━━━━━━━━━━━━━━━━━━━━━━$FAILURES"$'\n\n' MESSAGE_TEXT="$MESSAGE_TEXT""━━━━━━━━━━━━━━━━━━━━━━"$'\n' MESSAGE_TEXT="$MESSAGE_TEXT""📊 各阶段状态"$'\n' MESSAGE_TEXT="$MESSAGE_TEXT""━━━━━━━━━━━━━━━━━━━━━━"$'\n' MESSAGE_TEXT="$MESSAGE_TEXT""🔍 Pre-check: $PRECHECK_STATUS"$'\n' MESSAGE_TEXT="$MESSAGE_TEXT""🏗️ Build: $BUILD_STATUS"$'\n' MESSAGE_TEXT="$MESSAGE_TEXT""🌐 Deploy EdgeOne: $EDGEONE_STATUS"$'\n' MESSAGE_TEXT="$MESSAGE_TEXT""☁️ Deploy UpYun: $UPYUN_STATUS"$'\n' MESSAGE_TEXT="$MESSAGE_TEXT""📤 Finalize: $FINALIZE_STATUS"$'\n\n' MESSAGE_TEXT="$MESSAGE_TEXT""🔗 查看详情: https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}" curl -s -X POST "$FEISHU_WEBHOOK_URL" \ -H "Content-Type: application/json" \ -d "$(jq -n --arg text "$MESSAGE_TEXT" '{"msg_type":"text","content":{"text":$text}}')"