chore: bootstrap Ruby and Bundler toolchain

This commit is contained in:
SureBot
2026-04-26 15:12:21 +00:00
parent d03fa01aec
commit 157ee8b32c
3 changed files with 129 additions and 11 deletions

View File

@@ -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.

View File

@@ -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
```

View File

@@ -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),
},