From 157ee8b32c32b274d82516cfdbafa99ebbda82e2 Mon Sep 17 00:00:00 2001 From: SureBot Date: Sun, 26 Apr 2026 15:12:21 +0000 Subject: [PATCH] chore: bootstrap Ruby and Bundler toolchain --- .../sure-openclaw-build-bootstrap/SKILL.md | 47 ++++++++++++++- .../references/baseline-environment-audit.md | 34 +++++++++++ .../scripts/audit_sure_build_env.py | 59 ++++++++++++++++--- 3 files changed, 129 insertions(+), 11 deletions(-) diff --git a/.openclaw/skills/sure-openclaw-build-bootstrap/SKILL.md b/.openclaw/skills/sure-openclaw-build-bootstrap/SKILL.md index 92c7e421f..7178c22a6 100644 --- a/.openclaw/skills/sure-openclaw-build-bootstrap/SKILL.md +++ b/.openclaw/skills/sure-openclaw-build-bootstrap/SKILL.md @@ -47,6 +47,49 @@ Interpretation: If the audit reports `stop-and-free-disk-space`, do that before the next bootstrap step. +## Step 3, install Ruby and Bundler + +Preferred path on the reference host: + +- install `rbenv` and `ruby-build` from apt +- update the `ruby-build` plugin inside `/root/.rbenv/plugins/ruby-build` because Debian Bookworm's packaged definitions are too old for Ruby `3.4.7` +- install Ruby `3.4.7` with `rbenv` +- install Bundler `2.6.7` with `gem` + +Install missing Ruby build helpers: + +```bash +apt-get install -y --no-install-recommends \ + rbenv ruby-build libreadline-dev libgdbm-dev libgdbm-compat-dev bison +``` + +Refresh `ruby-build` definitions and install Ruby: + +```bash +mkdir -p /root/.rbenv/plugins +rm -rf /root/.rbenv/plugins/ruby-build +git clone --depth=1 https://github.com/rbenv/ruby-build.git /root/.rbenv/plugins/ruby-build + +export RBENV_ROOT=/root/.rbenv +export PATH="$RBENV_ROOT/bin:$RBENV_ROOT/shims:$PATH" +eval "$(rbenv init -)" +export RUBY_BUILD_CACHE_PATH=/root/.cache/ruby-build + +rbenv install -s 3.4.7 +rbenv global 3.4.7 +rbenv rehash +``` + +Install the lockfile-compatible Bundler: + +```bash +gem install bundler -v 2.6.7 --no-document +rbenv rehash +bundle -v +``` + +Important note: the host may still also have Debian's system Ruby on PATH. The audit helper is expected to prefer the `rbenv` Ruby and Bundler when they match repo requirements. + ## Step 2, install only missing OS packages On the first reference host, the missing OS-level pieces were: @@ -159,5 +202,5 @@ This tells you the environment cannot run Rails tests yet, but it has enough fre ## Resources -- `scripts/audit_sure_build_env.py` for a repeatable baseline audit and strategy recommendation. -- `references/baseline-environment-audit.md` for the captured step 1 findings and rationale. +- `scripts/audit_sure_build_env.py` for a repeatable baseline audit, disk-space gate, and strategy recommendation. +- `references/baseline-environment-audit.md` for the captured step-by-step findings and rationale. diff --git a/.openclaw/skills/sure-openclaw-build-bootstrap/references/baseline-environment-audit.md b/.openclaw/skills/sure-openclaw-build-bootstrap/references/baseline-environment-audit.md index 5cf112fa8..68dfbd407 100644 --- a/.openclaw/skills/sure-openclaw-build-bootstrap/references/baseline-environment-audit.md +++ b/.openclaw/skills/sure-openclaw-build-bootstrap/references/baseline-environment-audit.md @@ -117,6 +117,34 @@ Disk effect observed on the reference host: - the heaviest dependency expansion came from `libvips-dev` - the post-install state still cleared the hard disk gate, so it was safe to continue +## Step 3 result, Ruby and Bundler installed + +Installed on the reference host: + +- `rbenv` +- `ruby-build` +- `libreadline-dev` +- `libgdbm-dev` +- `libgdbm-compat-dev` +- `bison` + +Then: + +- updated `/root/.rbenv/plugins/ruby-build` to a current upstream release so Ruby `3.4.7` was available +- installed Ruby `3.4.7` via `rbenv` +- installed Bundler `2.6.7` + +Re-audit result after install: + +- Ruby: present, `3.4.7`, detected via `/root/.rbenv/shims/ruby` +- Bundler: present, `2.6.7`, detected via `/root/.rbenv/shims/bundle` +- disk-space gate: still `pass` + +Important finding: + +- Debian's system Ruby may still exist on the host and can appear earlier on PATH in bare shells +- the audit helper must therefore prefer the `rbenv` toolchain when it matches repo requirements + ## Suggested follow-up audit checks after installs Preferred: @@ -128,6 +156,12 @@ python3 .openclaw/skills/sure-openclaw-build-bootstrap/scripts/audit_sure_build_ Then add: ```bash +export RBENV_ROOT=/root/.rbenv +export PATH="$RBENV_ROOT/bin:$RBENV_ROOT/shims:$PATH" +eval "$(rbenv init -)" + +ruby -v +bundle -v bundle config list npm config get cache ``` diff --git a/.openclaw/skills/sure-openclaw-build-bootstrap/scripts/audit_sure_build_env.py b/.openclaw/skills/sure-openclaw-build-bootstrap/scripts/audit_sure_build_env.py index e0fc2bc60..d53c98be9 100644 --- a/.openclaw/skills/sure-openclaw-build-bootstrap/scripts/audit_sure_build_env.py +++ b/.openclaw/skills/sure-openclaw-build-bootstrap/scripts/audit_sure_build_env.py @@ -168,17 +168,52 @@ def du(path): def version_for(cmd, args): if not shutil.which(cmd): - return {'present': False, 'version': None} + return {'present': False, 'version': None, 'source': None} res = run([cmd] + args) out = res['output'].splitlines()[0] if res['output'] else '' - return {'present': True, 'version': out} + return {'present': True, 'version': out, 'source': shutil.which(cmd)} + + +def version_for_path(path, args): + if not Path(path).exists(): + return {'present': False, 'version': None, 'source': None} + res = run([path] + args) + out = res['output'].splitlines()[0] if res['output'] else '' + return {'present': res['ok'], 'version': out if res['ok'] else None, 'source': path} + + +def detect_ruby_toolchain(ruby_req, bundler_req): + system_ruby = version_for('ruby', ['-v']) + system_bundle = version_for('bundle', ['-v']) + rbenv_ruby = version_for_path('/root/.rbenv/shims/ruby', ['-v']) + rbenv_bundle = version_for_path('/root/.rbenv/shims/bundle', ['-v']) + + chosen_ruby = system_ruby + chosen_bundle = system_bundle + + if rbenv_ruby['present'] and ruby_req and ruby_req in (rbenv_ruby['version'] or ''): + chosen_ruby = rbenv_ruby + elif not system_ruby['present'] and rbenv_ruby['present']: + chosen_ruby = rbenv_ruby + + if rbenv_bundle['present'] and bundler_req and bundler_req in (rbenv_bundle['version'] or ''): + chosen_bundle = rbenv_bundle + elif not system_bundle['present'] and rbenv_bundle['present']: + chosen_bundle = rbenv_bundle + + return chosen_ruby, chosen_bundle, { + 'system_ruby': system_ruby, + 'system_bundle': system_bundle, + 'rbenv_ruby': rbenv_ruby, + 'rbenv_bundle': rbenv_bundle, + } def recommend(virt, ruby, bundler, node, psql, redis, ruby_req, bundler_req, node_hint, disk_health): missing = [] - if not ruby['present']: + if not ruby['present'] or (ruby_req and ruby_req not in (ruby['version'] or '')): missing.append('Ruby') - if not bundler['present']: + if not bundler['present'] or (bundler_req and bundler_req not in (bundler['version'] or '')): missing.append('Bundler') if not psql['present']: missing.append('PostgreSQL client') @@ -241,7 +276,8 @@ def markdown_report(data): item = data['tools'][key] name = key.replace('_', '-') if item['present']: - lines.append(f"- {name}: `{item['version']}`") + suffix = f" via `{item['source']}`" if item.get('source') else '' + lines.append(f"- {name}: `{item['version']}`{suffix}") else: lines.append(f"- {name}: **missing**") lines.append('') @@ -281,6 +317,10 @@ def main(): repo = Path(args[0]).resolve() if args else Path.cwd() output_json = '--json' in sys.argv[1:] + ruby_required = parse_ruby_version(repo) + bundler_required = parse_bundler_version(repo) + ruby_tool, bundler_tool, ruby_detection = detect_ruby_toolchain(ruby_required, bundler_required) + data = { 'host': { 'platform': platform.platform(), @@ -289,8 +329,8 @@ def main(): }, 'virtualization': detect_virtualization(), 'tools': { - 'ruby': version_for('ruby', ['-v']), - 'bundler': version_for('bundle', ['-v']), + 'ruby': ruby_tool, + 'bundler': bundler_tool, 'node': version_for('node', ['-v']), 'npm': version_for('npm', ['-v']), 'psql': version_for('psql', ['--version']), @@ -298,9 +338,10 @@ def main(): 'git': version_for('git', ['--version']), 'curl': version_for('curl', ['--version']), }, + 'tool_detection': ruby_detection, 'repo': { - 'ruby_required': parse_ruby_version(repo), - 'bundler_required': parse_bundler_version(repo), + 'ruby_required': ruby_required, + 'bundler_required': bundler_required, 'node_hint': parse_node_hint(repo), 'size': du(repo), },