name: Track OpenClaw upstream # 自动跟踪 OpenClaw 上游更新(借鉴 agentkernel/openclaw-desktop 的 pin 思路, # 但补上了它没做的最后一步:定时检测 + 自动 bump + 自动打 tag → 自动发版)。 # # 工作原理: # 1. 每天 cron 跑 `npm view openclaw version` 拿上游 npm 最新版 # 2. 和仓库里的 OPENCLAW_VERSION(pin)比对 # 3. 上游更新了 → 改 OPENCLAW_VERSION(根 + portable/)、bump 壳版本 patch、 # commit、push 新 tag v<壳版本> # 4. push tag 触发 release.yml → 自动构建 Win/Mac 便携版+桌面版并发布 Release # # 设计原则: # - 幂等:上游没新版就什么都不做,安静退出 # - 可手动:workflow_dispatch 支持手动触发、强制指定上游版本、dry-run 只看不改 # - 单一可信源:OPENCLAW_VERSION 是上游 pin,u-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 权限),本行会自动优先用它 push,tag 即可自动触发发版。 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.npmjs.org 2>/dev/null | tr -d '[:space:]')" 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$next,release.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 }}"