chore: 砍COS改造(deploy.yml改artifact传递+gitea-backup可移植部署包+改造步骤文档)

This commit is contained in:
zqlit committed 2026-10-04 09:52:50 +08:00
1 parent a74b3c7127
commit 2388694e8a
8 files changed
+729 -147

No files matched your search

+154 -147
View File
@@ -122,11 +122,9 @@ jobs:
contents: write
outputs:
build_hash: ${{ steps.hash.outputs.build_hash }}
last_hash: ${{ steps.last-hash.outputs.last_hash }}
duration: ${{ steps.end-build.outputs.duration }}
file_count: ${{ steps.stats.outputs.file_count }}
total_size: ${{ steps.stats.outputs.total_size }}
need_upload: ${{ steps.check-upload.outputs.need_upload }}
# Upload to UpYun 的真实三态:success / failure / skipped(未执行)。
# 该步骤标了 continue-on-error,conclusion 恒为 success,不能用来判断成败。
# 这里刻意不用 steps.<id>.outcome,而是让步骤自己在退出时写 GITHUB_OUTPUT,
@@ -221,80 +219,23 @@ jobs:
echo "file_count=${FILE_COUNT}" >> $GITHUB_OUTPUT
echo "total_size=${TOTAL_SIZE}" >> $GITHUB_OUTPUT
- name: Setup Python
uses: actions/setup-python@v4
- name: Upload build artifact (public/)
# 2026-10-04 起产物不再上传腾讯云 COS,改用 Gitea artifact 传递:
# - deploy-edgeone 用 actions/download-artifact 直接拿(同 runner,零跨境)
# - 国内中转机用 Gitea API 下载 artifact zip(替代原先的「从 COS 下载」)
# hash 写在 public/.build_hash 里随 artifact 一起走,中转机解压后读它判断是否同步。
uses: actions/upload-artifact@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: Get last build hash from COS
id: last-hash
continue-on-error: true
run: |
echo "🔍 从腾讯云 COS 获取上次部署的 hash..."
coscmd download /__build_hash /tmp/last_hash 2>/dev/null || echo ""
LAST_HASH=$(cat /tmp/last_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: Check if upload is needed
id: check-upload
run: |
LAST_HASH="${{ steps.last-hash.outputs.last_hash }}"
CURRENT_HASH="${{ steps.hash.outputs.build_hash }}"
echo "上次部署 hash: $LAST_HASH"
echo "当前构建 hash: $CURRENT_HASH"
if [ -z "$LAST_HASH" ] || [ "$CURRENT_HASH" != "$LAST_HASH" ]; then
echo "🔄 构建产物有变化,需要上传"
echo "need_upload=true" >> $GITHUB_OUTPUT
else
echo "✅ 构建产物无变化,跳过上传"
echo "need_upload=false" >> $GITHUB_OUTPUT
fi
- name: Upload to Tencent COS
if: steps.check-upload.outputs.need_upload == 'true'
continue-on-error: true
run: |
echo "📤 打包并上传到腾讯云 COS..."
if command -v zstd; then
tar -cf - public/ | zstd -1 -T0 -o public.tar.zst
coscmd upload public.tar.zst /public.tar.zst
else
tar -czf public.tar.gz public/
coscmd upload public.tar.gz /public.tar.gz
fi
coscmd upload public/.build_hash /__build_hash
- name: Upload hash to COS (even if skipped)
if: steps.check-upload.outputs.need_upload == 'false'
run: |
echo "📤 更新 hash 文件到腾讯云 COS..."
coscmd upload public/.build_hash /__build_hash
name: hugo-public
path: public/
retention-days: 7
- name: Report deploy status (built)
# 上报「构建完成、产物已进 COS」到 api.200181.xyz 的部署状态接口,
# 上报「构建完成、产物已进 artifact」到 api.200181.xyz 的部署状态接口,
# 中转机同步完成后会上报 phase=synced —— 打开
# https://api.200181.xyz/api/deploy-status 即可看到国内线路是否同步完。
# 需要 Gitea 仓库 Secrets 里配置 RSS_API_TOKEN = rss-robot-cf 的站点口令;
# 未配置时静默跳过上报(不影响部署)。
if: steps.check-upload.outputs.need_upload == 'true'
continue-on-error: true
env:
REPORT_TOKEN: ${{ secrets.RSS_API_TOKEN }}
@@ -320,7 +261,7 @@ jobs:
# │ 又拍云 purge → 多吉云刷新,实测 5 分钟内完成且它自己会刷 CDN)。 │
# │ 将来若把 runner 挪到国内,把下面的 if: false 删掉即可恢复。 │
# └─────────────────────────────────────────────────────────────────┘
if: false && steps.check-upload.outputs.need_upload == 'true'
if: false
timeout-minutes: 30
env:
UPYUN_SERVICE: ${{ secrets.UPYUN_BUCKET }}
@@ -458,7 +399,6 @@ jobs:
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:
@@ -469,63 +409,25 @@ jobs:
- name: Check if deployment is needed
id: check
run: |
CURRENT_HASH="${{ needs.build.outputs.build_hash }}"
LAST_HASH="${{ needs.build.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
# 2026-10-04 起去掉「比对 last_hash 跳过未变化部署」的优化:
# last_hash 原本存 COS,砍 COS 后无处持久化(Gitea 缓存服务跨网段不可达)。
# 且 push 才触发构建,本就意味着有内容变化,直接部署即可。
echo "🔄 构建完成,部署到 EdgeOne"
echo "deployed=true" >> $GITHUB_OUTPUT
- name: Setup Python
if: steps.check.outputs.deployed == 'true'
uses: actions/setup-python@v4
with:
python-version: '3.x'
- name: Install coscmd
if: steps.check.outputs.deployed == 'true'
run: pip install -U coscmd
- name: Configure coscmd
if: steps.check.outputs.deployed == 'true'
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: Download files from COS
if: steps.check.outputs.deployed == 'true'
- name: Download build artifact
id: download-files
run: |
echo "📥 从腾讯云 COS 下载构建产物..."
DOWNLOAD_START=$(date +%s)
if command -v zstd; then
coscmd download /public.tar.zst /tmp/public.tar.zst
tar -I zstd -xf /tmp/public.tar.zst
else
coscmd download /public.tar.gz /tmp/public.tar.gz
tar -xzf /tmp/public.tar.gz
fi
DOWNLOAD_END=$(date +%s)
DOWNLOAD_DURATION=$((DOWNLOAD_END - DOWNLOAD_START))
echo "download_duration=${DOWNLOAD_DURATION}" >> $GITHUB_OUTPUT
# 从 Gitea artifact 下载 public/(build job 上传的,同 runner 零跨境、零费用)
uses: actions/download-artifact@v4
with:
name: hugo-public
path: public/
- 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: |
@@ -541,7 +443,6 @@ jobs:
npx edgeone pages deploy ./public -n hugo-blog -t "$EDGEONE_API_TOKEN" --area overseas
- name: End upload timing
if: steps.check.outputs.deployed == 'true'
id: end-edgeone-upload
run: |
end_time=$(date +%s)
@@ -557,17 +458,11 @@ jobs:
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-files.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
echo "## ⏱️ Deploy EdgeOne 耗时: ${duration}秒" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "### 📊 部署统计" >> $GITHUB_STEP_SUMMARY
echo "- **上传部署**: ${duration}秒" >> $GITHUB_STEP_SUMMARY
echo "- **文件总数**: ${{ needs.build.outputs.file_count }}" >> $GITHUB_STEP_SUMMARY
# ============================================================
# 注意:这里原先有一个名为 deploy-upyun 的 job —— 它是纯空壳:
@@ -721,9 +616,8 @@ jobs:
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")
EDGEONE_DETAIL=$(printf "\n 📤 上传: %ss" "$EDGEONE_UPLOAD")
fi
# 三态映射:直传结果如实呈现,不再有"文件已在 Build 阶段同步"这种没验证过的说辞
@@ -804,9 +698,8 @@ jobs:
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")
EDGEONE_DETAIL=$(printf "\n 📤 上传: %ss" "$EDGEONE_UPLOAD")
fi
# 三态映射:直传结果如实呈现,不再有"文件已在 Build 阶段同步"这种没验证过的说辞
@@ -910,7 +803,6 @@ jobs:
🏗️ 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.build.outputs.upyun_status == 'success' && '✅ 成功' || (needs.build.outputs.upyun_status == 'skipped' && '⏭️ 跳过(无变化)' || '❌ 失败(国内中转机兜底)') }}
@@ -940,10 +832,8 @@ jobs:
UPYUN_DUR="${{ needs.build.outputs.upyun_duration }}"
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
@@ -962,13 +852,13 @@ jobs:
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_CELL} | - | ${UPYUN_DUR_CELL} |" >> $GITHUB_STEP_SUMMARY
echo "| Finalize | ${finalize_duration}s | - | - |" >> $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_UPLOAD}s |" >> $GITHUB_STEP_SUMMARY
echo "| UpYun 直传 | ${UPYUN_DUR_CELL} | ${UPYUN_DUR_CELL} |" >> $GITHUB_STEP_SUMMARY
echo "| Finalize | ${finalize_duration}s | - |" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "### 🚀 部署状态" >> $GITHUB_STEP_SUMMARY
@@ -1098,4 +988,121 @@ jobs:
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}}')"
-d "$(jq -n --arg text "$MESSAGE_TEXT" '{"msg_type":"text","content":{"text":$text}}')"
# ============================================================
# Job 7: 网络链路探测(仅手动触发,不改任何线上数据)
# ============================================================
# 目的:评估「境外 runner → 国内源站/CDN」各条链路的真实耗时与稳定性,
# 为「境外 EdgeOne + 境内多吉云」架构决策提供数据,而不是拍脑袋。
#
# 触发方式:workflow_dispatch(手动),绝不随 push/schedule 自动跑。
# 安全:只做连通性/耗时探测,不下载、不上传任何真实产物,不刷新 CDN。
#
# 探测项:
# A. 又拍云 API(v0.api.upyun.com) —— 境外直传又拍云的入口,已知会 EOF
# B. 又拍云对象存储上传探针(upx login) —— 登录握手能否成功(不传文件)
# C. 腾讯云 COS(cos.ap-*.myqcloud.com) —— 现状中转,作为稳定对照
# D. 多吉云 API(api.dogecloud.com) —— CDN 刷新 API 跨境响应耗时
# E. 多吉云 CDN 边缘节点 —— 国内加速域名的连通耗时
# ============================================================
probe-network:
runs-on: ubuntu-latest
timeout-minutes: 10
permissions:
contents: read
if: github.event_name == 'workflow_dispatch'
steps:
- name: 探测结果汇总头
run: |
echo "## 🌐 境外 Runner → 国内链路探测" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "| 探测项 | 结果 | 耗时 |" >> $GITHUB_STEP_SUMMARY
echo "|--------|------|------|" >> $GITHUB_STEP_SUMMARY
- name: A. 又拍云 API 连通性
run: |
echo "📡 探测又拍云 v0 API..."
T0=$(date +%s%3N)
CODE=$(curl -s -o /dev/null -w "%{http_code}" --connect-timeout 10 --max-time 20 "https://v0.api.upyun.com/" 2>&1 || echo "FAIL")
T1=$(date +%s%3N)
DUR=$(( (T1 - T0) / 1000 ))
echo " HTTP $CODE,耗时 ${DUR}s"
echo "| 又拍云 v0 API | $([ "$CODE" = "200" ] || [ "$CODE" = "401" ] || [ "$CODE" = "403" ] && echo '✅ 可达' || echo '⚠️ $CODE') | ${DUR}s |" >> $GITHUB_STEP_SUMMARY
- name: B. 又拍云 upx 登录握手(不传文件)
env:
UPYUN_SERVICE: ${{ secrets.UPYUN_BUCKET }}
UPYUN_OPERATOR: ${{ secrets.UPYUN_OPERATOR }}
UPYUN_PASSWORD: ${{ secrets.UPYUN_PASSWORD }}
run: |
echo "📡 探测又拍云 upx 登录握手..."
if [ -z "$UPYUN_SERVICE" ] || [ -z "$UPYUN_OPERATOR" ] || [ -z "$UPYUN_PASSWORD" ]; then
echo " ⚠️ UpYun secrets 未配置,跳过"
echo "| upx 登录握手 | ⏭️ 无密钥 | — |" >> $GITHUB_STEP_SUMMARY
exit 0
fi
UPX_VERSION="0.4.9"
curl -fsSL --connect-timeout 10 --max-time 60 -o /tmp/upx.tar.gz \
"https://github.com/upyun/upx/releases/download/v${UPX_VERSION}/upx_${UPX_VERSION}_linux_amd64.tar.gz" \
&& tar -xzf /tmp/upx.tar.gz -C /tmp && mv /tmp/upx /tmp/upyun-upx && chmod +x /tmp/upyun-upx
T0=$(date +%s%3N)
if timeout 30 /tmp/upyun-upx login "$UPYUN_SERVICE" "$UPYUN_OPERATOR" "$UPYUN_PASSWORD" 2>&1; then
R="✅ 握手成功"
else
R="❌ 握手失败"
fi
T1=$(date +%s%3N)
DUR=$(( (T1 - T0) / 1000 ))
echo " $R,耗时 ${DUR}s"
echo "| upx 登录握手 | $R | ${DUR}s |" >> $GITHUB_STEP_SUMMARY
- name: C. 腾讯云 COS 连通性(现状对照)
env:
COS_BUCKET: ${{ secrets.COS_BUCKET }}
COS_REGION: ${{ secrets.COS_REGION }}
run: |
echo "📡 探测腾讯云 COS..."
if [ -z "$COS_BUCKET" ]; then
echo " ⚠️ COS secrets 未配置,跳过"
echo "| 腾讯云 COS | ⏭️ 无密钥 | — |" >> $GITHUB_STEP_SUMMARY
exit 0
fi
HOST="${COS_BUCKET}.cos.${COS_REGION}.myqcloud.com"
T0=$(date +%s%3N)
CODE=$(curl -s -o /dev/null -w "%{http_code}" --connect-timeout 10 --max-time 20 "https://${HOST}/" 2>&1 || echo "FAIL")
T1=$(date +%s%3N)
DUR=$(( (T1 - T0) / 1000 ))
echo " ${HOST} → HTTP $CODE,耗时 ${DUR}s"
echo "| 腾讯云 COS | $([ "$CODE" != "FAIL" ] && [ "$CODE" != "000" ] && echo '✅ 可达' || echo '⚠️ $CODE') | ${DUR}s |" >> $GITHUB_STEP_SUMMARY
- name: D. 多吉云 API 跨境响应
env:
DOGECLOUD_ACCESS_KEY: ${{ secrets.DOGECLOUD_ACCESS_KEY }}
DOGECLOUD_SECRET_KEY: ${{ secrets.DOGECLOUD_SECRET_KEY }}
run: |
echo "📡 探测多吉云 API(不带签名,只测连通+延迟)..."
T0=$(date +%s%3N)
CODE=$(curl -s -o /dev/null -w "%{http_code}" --connect-timeout 10 --max-time 20 "https://api.dogecloud.com/cdn/refresh/add.json" 2>&1 || echo "FAIL")
T1=$(date +%s%3N)
DUR=$(( (T1 - T0) / 1000 ))
echo " HTTP $CODE,耗时 ${DUR}s"
echo "| 多吉云 API | $([ "$CODE" != "FAIL" ] && [ "$CODE" != "000" ] && echo '✅ 可达' || echo '⚠️ $CODE') | ${DUR}s |" >> $GITHUB_STEP_SUMMARY
- name: E. 多吉云 CDN 边缘节点连通性
run: |
echo "📡 探测多吉云 CDN 边缘节点..."
# 用当前博客域名(国内加速走多吉云)测连通 + 耗时
T0=$(date +%s%3N)
CODE=$(curl -s -o /dev/null -w "%{http_code}" --connect-timeout 10 --max-time 20 "https://usj.cc/" 2>&1 || echo "FAIL")
T1=$(date +%s%3N)
DUR=$(( (T1 - T0) / 1000 ))
echo " usj.cc → HTTP $CODE,耗时 ${DUR}s"
echo "| 博客站点(多吉云加速) | $([ "$CODE" = "200" ] && echo '✅ 可达' || echo '⚠️ $CODE') | ${DUR}s |" >> $GITHUB_STEP_SUMMARY
- name: 探测结果汇总尾
run: |
echo "" >> $GITHUB_STEP_SUMMARY
echo "> 结论判读:若「upx 登录握手」与「又拍云 v0 API」耗时远高于「COS / 多吉云 API」," >> $GITHUB_STEP_SUMMARY
echo "> 说明境外直传又拍云仍不稳定,国内线路应继续走中转机兜底,不宜改成境外直传。" >> $GITHUB_STEP_SUMMARY