From 4ce263831d9a5f54e0e029a4f4cadfd125f58f6e Mon Sep 17 00:00:00 2001 From: codes-factory-of-bg Date: Tue, 21 Jul 2026 12:10:00 +0800 Subject: [PATCH 1/3] =?UTF-8?q?ci(build-dist):=20=E5=8A=A0=20tarball=20?= =?UTF-8?q?=E5=86=92=E7=83=9F=E8=87=AA=E6=A3=80=20+=20install=20--skip-bro?= =?UTF-8?q?wser?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - build-dist.yml 在出 tarball 后、attach release 前加冒烟 step:解压 linux tarball → 跑 install.sh --no-prompt --skip-bind --skip-browser(指本地 tarball,不碰 runner ~/.openclaw)→ bin/openclaw --version。冒烟失败则 workflow fail,不会把坏 tarball attach 到 release - install.sh / install.ps1 加 --skip-browser / -SkipBrowser:跳过 camoufox-cli 浏览器二进制安装(省 ~557MB Firefox 下载),冒烟只验解压+依赖装+引擎起 --- .github/workflows/build-dist.yml | 27 +++++++++++++++++++++++++++ scripts/README.md | 1 + scripts/install.ps1 | 5 +++++ scripts/install.sh | 11 +++++++++++ 4 files changed, 44 insertions(+) diff --git a/.github/workflows/build-dist.yml b/.github/workflows/build-dist.yml index 841f7e55..0835b0d8 100644 --- a/.github/workflows/build-dist.yml +++ b/.github/workflows/build-dist.yml @@ -190,6 +190,33 @@ jobs: echo "out_dir=$RUNNER_TEMP/out" >> "$GITHUB_OUTPUT" ls -lh "$RUNNER_TEMP/out/" + - name: Smoke test linux tarball (extract + install --skip-browser + openclaw --version) + run: | + set -euo pipefail + REF_NAME="${GITHUB_REF##*/}" + if [[ "$REF_NAME" != v* ]]; then + echo "非 tag 触发(ref=$GITHUB_REF),跳过冒烟自检" + exit 0 + fi + TB="$RUNNER_TEMP/out/xiaobei-$REF_NAME-linux-x64.tar.zst" + [[ -f "$TB" ]] || { echo "❌ tarball 不存在:$TB"; exit 1; } + SMOKE="$RUNNER_TEMP/smoke" + rm -rf "$SMOKE" + mkdir -p "$SMOKE/extract" "$SMOKE/program" "$SMOKE/runtime" + # 解压一份拿到 scripts/install.sh(install.sh 会再按 XIAOBEI_TARBALL 解压到 program) + tar --zstd -xf "$TB" -C "$SMOKE/extract" + [[ -f "$SMOKE/extract/scripts/install.sh" ]] || { echo "❌ tarball 缺 scripts/install.sh"; exit 1; } + export XIAOBEI_HOME="$SMOKE/program" + export OPENCLAW_HOME="$SMOKE/runtime" + export XIAOBEI_TARBALL="$TB" + export XIAOBEI_TAG="$REF_NAME" + export XIAOBEI_SOURCE=github + export AWK_API_KEY="smoke-test-key" + bash "$SMOKE/extract/scripts/install.sh" \ + --no-prompt --skip-bind --skip-browser --root "$XIAOBEI_HOME" + "$XIAOBEI_HOME/bin/openclaw" --version + echo "✅ 冒烟自检通过:tarball 可解压 + 依赖可装 + 引擎可起" + - name: Upload artifacts uses: actions/upload-artifact@v4 with: diff --git a/scripts/README.md b/scripts/README.md index 325cc41c..77e99e84 100644 --- a/scripts/README.md +++ b/scripts/README.md @@ -37,6 +37,7 @@ irm https://atomgit.com/wiseflow/xiaobei/raw/branch/master/scripts/install.ps1 | | `--mirror ` / `-Mirror ` | 自定义镜像站根(覆盖默认 atomgit) | | `--force` / `-Force` | 强覆盖已有运行数据(`~/.openclaw`);默认已装机器重跑只更新 program,不碰运行数据 | | `--skip-bind` / `-SkipBind` | 跳过末尾微信扫码绑定(CI / 自动化) | +| `--skip-browser` / `-SkipBrowser` | 跳过 camoufox-cli 浏览器二进制安装(冒烟 / CI,省 ~557MB Firefox 下载) | | `--no-prompt` / `-NoPrompt` | 关闭交互提示(CI / 自动化,隐含 `--skip-bind`) | | `--root ` / `-Root ` | 程序目录覆盖(默认 `~/xiaobei`) | diff --git a/scripts/install.ps1 b/scripts/install.ps1 index 48f51cb3..d8c60a89 100644 --- a/scripts/install.ps1 +++ b/scripts/install.ps1 @@ -29,6 +29,7 @@ param( [switch]$GitHub, # 切回 GitHub release(不走默认 atomgit) [switch]$Force, # 强覆盖已有运行数据(~\.openclaw) [switch]$SkipBind, # 跳过末尾微信扫码绑定 + [switch]$SkipBrowser, # 跳过 camoufox-cli 浏览器二进制(冒烟/CI) [switch]$NoPrompt ) @@ -204,6 +205,10 @@ function Run-SetupCrew { # ─── 8. camoufox-cli ─────────────────────────────────────────── function Install-CamoufoxCli { + if ($SkipBrowser) { + Write-Host " [i] 跳过 camoufox-cli 浏览器二进制(-SkipBrowser);后续手动:camoufox-cli install" -ForegroundColor Yellow + return + } Write-Stage "Installing camoufox-cli browser" $fork = Join-Path $Root "camoufox-cli" if (-not (Test-Path $fork)) { Write-Warn "camoufox-cli fork 不在 tarball 内:$fork;跳过"; return } diff --git a/scripts/install.sh b/scripts/install.sh index fac43e1c..3d39a890 100755 --- a/scripts/install.sh +++ b/scripts/install.sh @@ -1007,6 +1007,10 @@ checkout_openclaw_at_pin() { # camoufox-cli(Firefox 反指纹浏览器) # ═══════════════════════════════════════════════════════════════════ install_camoufox_cli() { + if [[ "$SKIP_BROWSER" == "true" ]]; then + ui_info "跳过 camoufox-cli 浏览器二进制(--skip-browser);后续手动:camoufox-cli install" + return 0 + fi local node="$WISEFLOW_ROOT/$PORTABLE_NODE" local npm_bin; npm_bin="$(dirname "$node")/npm" local fork_dir="$WISEFLOW_ROOT/camoufox-cli" @@ -1111,6 +1115,7 @@ NO_PROMPT=0 USE_LOCAL=false FORCE_RUNTIME=false SKIP_WEIXIN_BIND=false +SKIP_BROWSER=false TAGLINE="$DEFAULT_TAGLINE" parse_args() { @@ -1155,6 +1160,11 @@ parse_args() { SKIP_WEIXIN_BIND=true shift ;; + --skip-browser) + # 跳过 camoufox-cli 装浏览器二进制(冒烟/CI,省 ~557MB Firefox 下载) + SKIP_BROWSER=true + shift + ;; --root) if [[ $# -lt 2 || "${2:-}" == --* ]]; then ui_error "Missing value for $1" @@ -1177,6 +1187,7 @@ Options: --mirror Custom mirror root (overrides default atomgit) --force Overwrite existing runtime data (~/.openclaw); default preserves it on re-install --skip-bind Skip the WeChat QR binding at the end (CI/automation) + --skip-browser Skip camoufox-cli browser binary install (smoke/CI, saves ~557MB Firefox) --verbose Print debug output --no-prompt Disable prompts (CI/automation) --help, -h Show this help From 4ce7266dbf564b13b432b21f18038294cc72fc6a Mon Sep 17 00:00:00 2001 From: codes-factory-of-bg Date: Tue, 21 Jul 2026 12:24:15 +0800 Subject: [PATCH 2/3] =?UTF-8?q?ci:=20=E4=BF=AE=20build-dist=20=E8=A7=A6?= =?UTF-8?q?=E5=8F=91=E9=93=BE=20+=20=E5=8E=BB=20continue-on-error=20+=20ac?= =?UTF-8?q?tions=20=E5=8D=87=20Node=2024?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - release.yml 推 tag 后主动 gh workflow run build-dist.yml -f tag=:GITHUB_TOKEN 推 tag 不触发下游 on:push(递归保护),workflow_dispatch 是例外可触发;加 actions: write 权限,清过期注释 - build-dist.yml 加 workflow_dispatch inputs.tag;ASSET_TAG 优先 inputs.tag > git tag > version 文件,输出 asset_tag 供冒烟/attach 复用;attach 去 continue-on-error + 去 per-file || true(上传失败不再被吞,release 不会静默缺包) - ci.yml / release.yml / build-dist.yml:actions/checkout v4→v5、setup-node v4→v5、pnpm/action-setup v4→v6,全部 node24 runtime,消 Node 20 deprecation 警告 --- .github/workflows/build-dist.yml | 38 ++++++++++++++++++++------------ .github/workflows/ci.yml | 6 ++--- .github/workflows/release.yml | 17 ++++++++++---- 3 files changed, 40 insertions(+), 21 deletions(-) diff --git a/.github/workflows/build-dist.yml b/.github/workflows/build-dist.yml index 0835b0d8..ea5e4edf 100644 --- a/.github/workflows/build-dist.yml +++ b/.github/workflows/build-dist.yml @@ -9,6 +9,11 @@ on: push: tags: ['v*'] workflow_dispatch: + inputs: + tag: + description: 'Release tag to build + attach (e.g. v5.6.0);由 release.yml 推 tag 后触发' + required: true + type: string permissions: contents: write @@ -22,7 +27,7 @@ jobs: runs-on: ubuntu-24.04 steps: - name: Checkout xiaobei - uses: actions/checkout@v4 + uses: actions/checkout@v5 - name: Read pinned openclaw version id: pin @@ -32,10 +37,10 @@ jobs: echo "version=$OPENCLAW_VERSION" >> "$GITHUB_OUTPUT" - name: Setup Node + pnpm (build env) - uses: actions/setup-node@v4 + uses: actions/setup-node@v5 with: node-version: '24.15.0' - - uses: pnpm/action-setup@v4 + - uses: pnpm/action-setup@v6 - name: Clone openclaw at pinned commit run: | @@ -121,13 +126,18 @@ jobs: echo "stage_dir=$STAGE" >> "$GITHUB_OUTPUT" - name: Build 4 platform tarballs (engine + portable Node) + id: buildtars run: | set -euo pipefail STAGE="${{ steps.stage.outputs.stage_dir }}" XIAOBEI_VER="$(tr -d '[:space:]' < "$GITHUB_WORKSPACE/version")" - # asset 名优先用 git tag(release source of truth),非 tag 触发回退 version 文件 + # asset tag 优先级:workflow_dispatch inputs.tag > git tag(push 触发)> version 文件 + INPUT_TAG="${{ inputs.tag }}" REF_NAME="${GITHUB_REF##*/}" - if [[ "$REF_NAME" == v* ]]; then ASSET_TAG="$REF_NAME"; else ASSET_TAG="$XIAOBEI_VER"; fi + if [[ -n "$INPUT_TAG" ]]; then ASSET_TAG="$INPUT_TAG" + elif [[ "$REF_NAME" == v* ]]; then ASSET_TAG="$REF_NAME" + else ASSET_TAG="$XIAOBEI_VER"; fi + echo "ASSET_TAG=$ASSET_TAG" mkdir -p "$RUNNER_TEMP/out" # 平台 → (node_url, subdir) @@ -188,17 +198,18 @@ jobs: # 给后续步骤用 echo "out_dir=$RUNNER_TEMP/out" >> "$GITHUB_OUTPUT" + echo "asset_tag=$ASSET_TAG" >> "$GITHUB_OUTPUT" ls -lh "$RUNNER_TEMP/out/" - name: Smoke test linux tarball (extract + install --skip-browser + openclaw --version) run: | set -euo pipefail - REF_NAME="${GITHUB_REF##*/}" - if [[ "$REF_NAME" != v* ]]; then - echo "非 tag 触发(ref=$GITHUB_REF),跳过冒烟自检" + ASSET_TAG="${{ steps.buildtars.outputs.asset_tag }}" + if [[ "$ASSET_TAG" != v* ]]; then + echo "无 release tag(asset_tag=$ASSET_TAG),跳过冒烟自检" exit 0 fi - TB="$RUNNER_TEMP/out/xiaobei-$REF_NAME-linux-x64.tar.zst" + TB="$RUNNER_TEMP/out/xiaobei-$ASSET_TAG-linux-x64.tar.zst" [[ -f "$TB" ]] || { echo "❌ tarball 不存在:$TB"; exit 1; } SMOKE="$RUNNER_TEMP/smoke" rm -rf "$SMOKE" @@ -209,7 +220,7 @@ jobs: export XIAOBEI_HOME="$SMOKE/program" export OPENCLAW_HOME="$SMOKE/runtime" export XIAOBEI_TARBALL="$TB" - export XIAOBEI_TAG="$REF_NAME" + export XIAOBEI_TAG="$ASSET_TAG" export XIAOBEI_SOURCE=github export AWK_API_KEY="smoke-test-key" bash "$SMOKE/extract/scripts/install.sh" \ @@ -227,16 +238,15 @@ jobs: retention-days: 14 - name: Attach to release (on real tag, skip disttest) - if: startsWith(github.ref, 'refs/tags/v') && !contains(github.ref, 'disttest') - continue-on-error: true + if: ${{ startsWith(steps.buildtars.outputs.asset_tag, 'v') && !contains(steps.buildtars.outputs.asset_tag, 'disttest') }} env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: | - TAG="${GITHUB_REF##*/}" + TAG="${{ steps.buildtars.outputs.asset_tag }}" if ! gh release view "$TAG" >/dev/null 2>&1; then gh release create "$TAG" --title "$TAG" --generate-notes fi for f in "$RUNNER_TEMP"/out/*.tar.zst "$RUNNER_TEMP"/out/*.tar.gz; do [ -e "$f" ] || continue - gh release upload "$TAG" "$f" --clobber || true + gh release upload "$TAG" "$f" --clobber done diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 707da782..a3208f1d 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -20,15 +20,15 @@ jobs: steps: - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@v5 - name: Setup Node.js - uses: actions/setup-node@v4 + uses: actions/setup-node@v5 with: node-version: '24' - name: Install pnpm - uses: pnpm/action-setup@v4 + uses: pnpm/action-setup@v6 - name: Read pinned openclaw version id: pin diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index abfe30e3..f0ed53fb 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -18,6 +18,7 @@ on: permissions: contents: write + actions: write # 防止多个 PR 同时 merge 时并发触发重复 release concurrency: @@ -26,15 +27,15 @@ concurrency: jobs: release: - # wiseflow 走 git clone 路线(见 scripts/install.sh),无 release artifact 通道。 - # 本 job 仅做版本 bump + tag push,让用户 update.sh 可拉特定 tag 而非总跟 master。 - # 后续若重启 tarball 通道,在此 job 内追加 build / upload asset 步骤即可。 + # PR merge → bump version + push v* tag → 触发 build-dist.yml 出 4 平台 tarball + attach release。 + # tag push 用 GITHUB_TOKEN 不会触发下游 on:push workflow(递归保护),故这里主动 + # gh workflow run build-dist.yml(workflow_dispatch 是递归保护例外,GITHUB_TOKEN 可触发)。 if: github.event.pull_request.merged == true || github.event_name == 'workflow_dispatch' runs-on: ubuntu-latest steps: - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@v5 with: fetch-depth: 0 token: ${{ secrets.RELEASE_TOKEN || secrets.GITHUB_TOKEN }} @@ -98,3 +99,11 @@ jobs: git commit -m "chore: bump version to ${{ steps.version.outputs.new }} [skip ci]" git tag "${{ steps.version.outputs.new }}" git push origin master --tags + + - name: Trigger build-dist tarball workflow + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + TAG="${{ steps.version.outputs.new }}" + echo "Triggering build-dist.yml with tag=$TAG" + gh workflow run build-dist.yml -f tag="$TAG" From d73b6abe76f6fb294301c4fd73eefb59a1a6002b Mon Sep 17 00:00:00 2001 From: codes-factory-of-bg Date: Tue, 21 Jul 2026 12:42:18 +0800 Subject: [PATCH 3/3] =?UTF-8?q?ci:=20setup-node@v6=20=E4=BF=AE=20pnpm=20?= =?UTF-8?q?=E8=87=AA=E5=8A=A8=E7=BC=93=E5=AD=98=E8=AF=AF=E6=8A=A5=20+=20ac?= =?UTF-8?q?tion-setup=20=E6=98=BE=E5=BC=8F=20version?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 升级 actions/setup-node@v5→v6:v5 的 package-manager-cache 检测到 package.json 里 packageManager: pnpm@ 就自动开 pnpm 缓存,但它在 pnpm/action-setup 之前跑、pnpm 还没装,抛 'Unable to locate executable file: pnpm'(setup-node#1351)。v6 把自动缓存限为 npm-only,解。 pnpm/action-setup@v6 显式传 version: 10.30.2,规避 v6 早期不读 packageManager 版本的坑(action-setup#227)。 --- .github/workflows/build-dist.yml | 6 +++++- .github/workflows/ci.yml | 8 +++++++- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build-dist.yml b/.github/workflows/build-dist.yml index ea5e4edf..3a21458b 100644 --- a/.github/workflows/build-dist.yml +++ b/.github/workflows/build-dist.yml @@ -37,10 +37,14 @@ jobs: echo "version=$OPENCLAW_VERSION" >> "$GITHUB_OUTPUT" - name: Setup Node + pnpm (build env) - uses: actions/setup-node@v5 + # v6:package-manager-cache 限 npm-only,避免 pnpm 装好前自动开缓存报 + # "Unable to locate executable file: pnpm"(setup-node#1351) + uses: actions/setup-node@v6 with: node-version: '24.15.0' - uses: pnpm/action-setup@v6 + with: + version: 10.30.2 - name: Clone openclaw at pinned commit run: | diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a3208f1d..2d4e7a51 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -23,12 +23,18 @@ jobs: uses: actions/checkout@v5 - name: Setup Node.js - uses: actions/setup-node@v5 + # v6:把 package-manager-cache 限制为 npm-only,避免检测到 packageManager: pnpm@ + # 时在 pnpm 装好前自动开 pnpm 缓存而抛 "Unable to locate executable file: pnpm" + #(setup-node#1351)。v5 会自动开 pnpm 缓存,必须配 pnpm/action-setup 才不报错。 + uses: actions/setup-node@v6 with: node-version: '24' - name: Install pnpm + # 显式 version 规避 action-setup#227(v6 早期不读 packageManager 版本) uses: pnpm/action-setup@v6 + with: + version: 10.30.2 - name: Read pinned openclaw version id: pin