Files
let-deals-radar/.github/workflows/update.yml
T
gungun88 c62657d4b6 fix(ci): 修复 forum_posted.json 不存在时 git add 报错
上一个提交把 data/forum_posted.json 直接加进 git add,
但该文件只在真正发过帖时才生成。默认关闭发帖时文件不存在,
git add 报 "pathspec did not match",导致提交步骤失败(exit 128)。

改为先判断文件是否存在再添加,两种情况都安全。

已在本地用隔离脚本验证:
- 文件不存在:add_all 成功,正常提交其他产物
- 文件存在:正确暂存 forum_posted.json
2026-10-16 20:09:55 +08:00

161 lines
6.1 KiB
YAML

name: Update deals
# 定时抓取 → 生成站点 → 提交回仓库 →(可选)推送到自有服务器
#
# 为什么用 GitHub Actions 抓取而不是自有服务器:
# Actions 每次运行都是**不同的云 IP**,可避开 Cloudflare 对固定 IP 的拦截;
# 而站点仍可发布到自己的域名与服务器。
on:
schedule:
# 每 6 小时一次(UTC)。GitHub 的 cron 在高负载时可能延后几分钟,属正常。
- cron: '17 */6 * * *'
workflow_dispatch:
inputs:
with_replies:
description: '抓取回帖(库存更准,耗时更长)'
type: boolean
default: true
recent_days:
description: '只保留最近 N 天(0=全部)'
type: string
default: '90'
permissions:
contents: write
# 避免上一次未跑完时重复触发
concurrency:
group: update-deals
cancel-in-progress: false
jobs:
update:
runs-on: ubuntu-latest
timeout-minutes: 30
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup Python
uses: actions/setup-python@v5
with:
python-version: '3.11'
- name: Install test dependency
run: python -m pip install --upgrade pip pytest
- name: Run tests
run: python -m pytest tests -q
- name: Fetch, extract and build site
env:
# 站点与域名配置(在仓库 Settings → Variables 中设置)
LDR_SITE_TITLE: ${{ vars.LDR_SITE_TITLE }}
LDR_SITE_URL: ${{ vars.LDR_SITE_URL }}
LDR_SITE_DESC: ${{ vars.LDR_SITE_DESC }}
LDR_SITE_FOOTER: ${{ vars.LDR_SITE_FOOTER }}
# 抓取参数:手动触发时用输入值,定时触发时用默认值
WITH_REPLIES: ${{ github.event.inputs.with_replies || '1' }}
RECENT_DAYS: ${{ github.event.inputs.recent_days || '90' }}
PYTHON: python
run: bash deploy/run_pipeline.sh
- name: Verify output is non-empty
# 安全网:抓取失败或全部被过滤时,拒绝提交,保留上次线上数据
run: |
COUNT=$(python -c "import json;print(json.load(open('data/deals.json'))['count'])")
echo "记录数: $COUNT"
if [ "$COUNT" -lt 1 ]; then
echo "::error::记录数为 0,拒绝提交(保留上次数据)"
exit 1
fi
- name: Upload site artifact
uses: actions/upload-artifact@v4
with:
name: site-${{ github.run_number }}
path: site/
retention-days: 7
if-no-files-found: error
- name: Post to forum
# 把优惠帖搬运到 LowSeek 论坛。
#
# 默认关闭:LDR_FORUM_ENABLED 未设置时该步骤只打印「已关闭」并退出,
# 不会发布任何内容。想开启时在仓库 Variables 里设:
# LDR_FORUM_ENABLED = true
# LDR_FORUM_DRY_RUN = false (先设 true 可只看演练日志)
# 并在 Secrets 里配置 LDR_FORUM_API_KEY。
env:
LDR_FORUM_ENABLED: ${{ vars.LDR_FORUM_ENABLED || 'false' }}
LDR_FORUM_DRY_RUN: ${{ vars.LDR_FORUM_DRY_RUN || 'true' }}
LDR_FORUM_API_KEY: ${{ secrets.LDR_FORUM_API_KEY }}
LDR_FORUM_URL: ${{ vars.LDR_FORUM_URL || 'https://lowseek.ai' }}
LDR_FORUM_TAG_ID: ${{ vars.LDR_FORUM_TAG_ID || '21' }}
LDR_FORUM_MAX_PER_RUN: ${{ vars.LDR_FORUM_MAX_PER_RUN || '3' }}
LDR_FORUM_MAX_AGE_DAYS: ${{ vars.LDR_FORUM_MAX_AGE_DAYS || '3' }}
LDR_FORUM_MIN_PERCENT: ${{ vars.LDR_FORUM_MIN_PERCENT || '30' }}
# 读上一步生成的 deals.json,不重复抓取
run: python -m letdeals --forum-only
- name: Commit refreshed data
run: |
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
# forum_posted.json 是幂等依据,必须提交;但它只在真正发过帖时
# 才存在。文件不存在时若直接 git add 会报
# "pathspec did not match",因此先判断再添加。
add_all() {
git add data/deals.json data/deals.md site/
if [ -f data/forum_posted.json ]; then
git add data/forum_posted.json
fi
}
add_all
if git diff --staged --quiet; then
echo "无变化,跳过提交"
exit 0
fi
git commit -m "chore: refresh deals [skip ci]"
# 远端可能已被另一次运行推进(手动重跑、cron 延迟等),
# 直接 push 会因非快进而被拒。做法:把 HEAD 移到远端最新提交,
# 保留我们刚生成的数据(这些是产物,永远以最新一次为准),
# 在其之上重新提交,从而始终是快进推送。
git fetch origin main
git reset --soft origin/main
add_all
if git diff --staged --quiet; then
echo "与远端一致,无需提交"
else
git commit -m "chore: refresh deals [skip ci]"
fi
git push
# 可选:推送到自有服务器(配置 LDR_DEPLOY_HOST 后自动启用)
- name: Deploy to own server
if: ${{ vars.LDR_DEPLOY_HOST != '' }}
env:
SSH_KEY: ${{ secrets.LDR_DEPLOY_SSH_KEY }}
HOST: ${{ vars.LDR_DEPLOY_HOST }}
USER: ${{ vars.LDR_DEPLOY_USER }}
TARGET: ${{ vars.LDR_DEPLOY_PATH }}
PORT: ${{ vars.LDR_DEPLOY_PORT || '22' }}
run: |
if [ -z "$SSH_KEY" ]; then
echo "::warning::未配置 LDR_DEPLOY_SSH_KEY,跳过部署"
exit 0
fi
mkdir -p ~/.ssh
printf '%s\n' "$SSH_KEY" > ~/.ssh/deploy_key
chmod 600 ~/.ssh/deploy_key
# 首次连接自动接受主机指纹;更高安全性可改为预置 known_hosts
ssh-keyscan -p "$PORT" -H "$HOST" >> ~/.ssh/known_hosts 2>/dev/null || true
rsync -avz --delete -e "ssh -i ~/.ssh/deploy_key -p $PORT" \
site/ "$USER@$HOST:$TARGET/"
echo "已推送到 $USER@$HOST:$TARGET"