ci: 新增自动跟踪 OpenClaw 上游 workflow

每天 cron 检测 npm openclaw 新版,自动 bump 壳版本+改 OPENCLAW_VERSION+打 tag
触发 release.yml 发版。借鉴 agentkernel/openclaw-desktop 的 pin 思路,
补上其缺失的定时自动发版。半自动模式(推 tag 后手动 Run release)。

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
hfshfg
2026-06-17 22:45:59 +08:00
parent 8bffa5d9d7
commit dcc034fa85

161
.github/workflows/track-upstream.yml vendored Normal file
View File

@@ -0,0 +1,161 @@
name: Track OpenClaw upstream
# 自动跟踪 OpenClaw 上游更新(借鉴 agentkernel/openclaw-desktop 的 pin 思路,
# 但补上了它没做的最后一步:定时检测 + 自动 bump + 自动打 tag → 自动发版)。
#
# 工作原理:
# 1. 每天 cron 跑 `npm view openclaw version` 拿上游 npm 最新版
# 2. 和仓库里的 OPENCLAW_VERSIONpin比对
# 3. 上游更新了 → 改 OPENCLAW_VERSION根 + portable/、bump 壳版本 patch、
# commit、push 新 tag v<壳版本>
# 4. push tag 触发 release.yml → 自动构建 Win/Mac 便携版+桌面版并发布 Release
#
# 设计原则:
# - 幂等:上游没新版就什么都不做,安静退出
# - 可手动workflow_dispatch 支持手动触发、强制指定上游版本、dry-run 只看不改
# - 单一可信源OPENCLAW_VERSION 是上游 pinu-claw-app/package.json 是壳版本
on:
schedule:
# 每天 UTC 01:00北京时间 09:00检查一次
- cron: '0 1 * * *'
workflow_dispatch:
inputs:
force_version:
description: '强制使用的上游 OpenClaw 版本(留空=用 npm latest'
required: false
default: ''
dry_run:
description: '只检测不改动true/false'
required: false
default: 'false'
permissions:
contents: write
jobs:
track:
name: Check upstream & auto-bump
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
# 需要完整历史才能正确打 tag / 读已有 tag
fetch-depth: 0
# 半自动模式(默认):用 GITHUB_TOKEN push tag。GitHub 防递归机制下
# 自动推的 tag 不会触发 release.yml所以需到 Actions 手动点一次 Run release。
# 想升级成全自动:去仓库 Settings → Secrets 加一个 RELEASE_PAT个人访问令牌
# repo 权限),本行会自动优先用它 pushtag 即可自动触发发版。
token: ${{ secrets.RELEASE_PAT || secrets.GITHUB_TOKEN }}
- uses: actions/setup-node@v4
with:
node-version: '22'
- name: Resolve upstream OpenClaw version
id: upstream
run: |
force="${{ github.event.inputs.force_version }}"
if [ -n "$force" ]; then
latest="${force#v}"
echo "强制指定上游版本: $latest"
else
latest="$(npm view openclaw version --registry=https://registry.npmmirror.com 2>/dev/null | tr -d '[:space:]')"
# npmmirror 偶尔缓存陈旧,官方源兜底取较大值
official="$(npm view openclaw version 2>/dev/null | tr -d '[:space:]')"
if [ -n "$official" ] && [ "$official" != "$latest" ]; then
# 取版本号较大的那个npmmirror 缓存滞后时用官方源)
latest="$(printf '%s\n%s\n' "$latest" "$official" | sort -V | tail -1)"
fi
echo "npm latest openclaw: $latest"
fi
if [ -z "$latest" ]; then
echo "::error::无法获取上游 openclaw 版本npm view 失败)"
exit 1
fi
echo "latest=$latest" >> "$GITHUB_OUTPUT"
- name: Read current pin
id: current
run: |
pinned="$(tr -d '[:space:]' < OPENCLAW_VERSION)"
shell_ver="$(node -p "require('./u-claw-app/package.json').version")"
echo "pinned=$pinned" >> "$GITHUB_OUTPUT"
echo "shell_ver=$shell_ver" >> "$GITHUB_OUTPUT"
echo "当前 pin: $pinned | 壳版本: $shell_ver"
- name: Decide whether to bump
id: decide
run: |
latest="${{ steps.upstream.outputs.latest }}"
pinned="${{ steps.current.outputs.pinned }}"
if [ "$latest" = "$pinned" ]; then
echo "✅ 已是最新pin=$pinned无需发版。"
echo "changed=false" >> "$GITHUB_OUTPUT"
exit 0
fi
# 只在 latest 严格 > pinned 时发版(避免上游撤版导致回退)
newer="$(printf '%s\n%s\n' "$pinned" "$latest" | sort -V | tail -1)"
if [ "$newer" != "$latest" ]; then
echo "⚠️ npm latest ($latest) 不比当前 pin ($pinned) 新,跳过。"
echo "changed=false" >> "$GITHUB_OUTPUT"
exit 0
fi
echo "🆕 发现上游新版: $pinned → $latest"
echo "changed=true" >> "$GITHUB_OUTPUT"
- name: Compute next shell version (patch bump)
if: steps.decide.outputs.changed == 'true'
id: nextver
run: |
cur="${{ steps.current.outputs.shell_ver }}"
IFS='.' read -r MA MI PA <<< "$cur"
PA=$((PA + 1))
next="${MA}.${MI}.${PA}"
echo "壳版本 bump: $cur → $next"
echo "next=$next" >> "$GITHUB_OUTPUT"
- name: Apply changes (pin + version files)
if: steps.decide.outputs.changed == 'true' && github.event.inputs.dry_run != 'true'
run: |
latest="${{ steps.upstream.outputs.latest }}"
next="${{ steps.nextver.outputs.next }}"
# 1) 更新上游 pin根 + portable/ 两份保持一致)
printf '%s\n' "$latest" > OPENCLAW_VERSION
printf '%s\n' "$latest" > portable/OPENCLAW_VERSION
# 2) bump 壳版本package.json。release.yml 仍会从 tag 同步,
# 这里写一份让 main 分支也保持一致。
node -e "const f='u-claw-app/package.json';const p=require('./'+f);p.version='$next';require('fs').writeFileSync(f, JSON.stringify(p,null,2)+'\n')"
echo "已写入: OPENCLAW_VERSION=$latest, 壳版本=$next"
- name: Commit, tag & push
if: steps.decide.outputs.changed == 'true' && github.event.inputs.dry_run != 'true'
run: |
latest="${{ steps.upstream.outputs.latest }}"
next="${{ steps.nextver.outputs.next }}"
git config user.name "u-claw-bot"
git config user.email "bot@u-claw.org"
git add OPENCLAW_VERSION portable/OPENCLAW_VERSION u-claw-app/package.json
git commit -m "chore(upstream): 跟随 OpenClaw $latest发布 v$next
自动跟踪上游OpenClaw npm latest 升到 $latest
自动 bump 壳版本到 $next 并打 tag 触发发版。"
git push origin HEAD:main
# 打 tag 触发 release.yml
git tag "v$next"
git push origin "v$next"
echo "✅ 已推送 v$nextrelease.yml 将自动构建并发布。"
- name: Dry-run summary
if: steps.decide.outputs.changed == 'true' && github.event.inputs.dry_run == 'true'
run: |
echo "🔍 DRY RUN — 不改动。"
echo "若执行将OPENCLAW_VERSION ${{ steps.current.outputs.pinned }} → ${{ steps.upstream.outputs.latest }},发布 v${{ steps.nextver.outputs.next }}"