From 3c5b803fc1b4f05b2f3f4716b38cbd784ff2bb84 Mon Sep 17 00:00:00 2001 From: Matthew Mellor Date: Wed, 29 Apr 2026 09:50:35 -0500 Subject: [PATCH] fix(container): install libyaml-dev so bundle install can compile psych (#28) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Follow-up to v1.9.0 (issue #25). v1.9.0 shipped libyaml-0-2 (runtime lib only) which lets the in-container rubocop/reek/etc. start, but a Rails 7+ project running `bundle install` against its own Gemfile fails because compiling psych 5.x natively needs libyaml's headers. Resolution chain: debug -> irb -> rdoc -> psych (psych compile fails: missing yaml.h) Replace libyaml-0-2 with libyaml-dev in the runtime apt block. libyaml-dev depends on libyaml-0-2 transitively, so the runtime lib is still present; no other change needed in the Ruby builder stage or COPY layout. Also extend tests/smoke-rails.sh with a third assertion: run `bundle install` against the Rails-shaped fixture's Gemfile (which contains `gem 'debug'`) and require 'psych' inside the resulting bundle. The existing fixture already included the right Gemfile shape — only the install step is new. Cleanup: bundle install writes root-owned files into the bind-mounted fixture; the existing host-side `rm -rf` couldn't delete them. Moved the cleanup into a docker run so it executes as root inside the container. Tested: - smoke-rails.sh: all three checks pass (Gemfile parse, lint scope, bundle install + psych load) in ~36s end-to-end against a freshly built image - make _check on dev-toolchain itself: pass Co-Authored-By: Claude Opus 4.7 (1M context) --- CHANGELOG.md | 12 ++++++++++ Dockerfile | 2 +- tests/smoke-rails.sh | 53 +++++++++++++++++++++++++++++++++++++++++--- 3 files changed, 63 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3949032..5fa33f3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,18 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +### Fixed + +- `bundle install` now succeeds out-of-the-box for Rails 7+ projects that use + the standard `debug` gem (#28). v1.9.0 shipped `libyaml-0-2` (runtime lib only) + but not the development headers required to compile `psych` 5.x as a native + gem; the resolution chain `debug → irb → rdoc → psych` failed at the psych + build step. Replaced `libyaml-0-2` with `libyaml-dev` (which transitively + pulls in the runtime lib). +- `tests/smoke-rails.sh` extended with a `bundle install` step against the + Rails-shaped fixture's Gemfile — exercises the psych native-compile path + end-to-end and asserts `require 'psych'` succeeds inside the container. + ## [1.9.0] - 2026-04-27 ### Fixed diff --git a/Dockerfile b/Dockerfile index ca58700..2970b23 100644 --- a/Dockerfile +++ b/Dockerfile @@ -101,7 +101,7 @@ RUN apt-get update && apt-get install -y --no-install-recommends \ python3-pip \ python3-venv \ build-essential \ - libyaml-0-2 \ + libyaml-dev \ shellcheck \ unzip \ wget \ diff --git a/tests/smoke-rails.sh b/tests/smoke-rails.sh index e5f92e8..65c5352 100755 --- a/tests/smoke-rails.sh +++ b/tests/smoke-rails.sh @@ -1,9 +1,11 @@ #!/usr/bin/env bash -# tests/smoke-rails.sh — Rails 7+ smoke test for issue #25 +# tests/smoke-rails.sh — Rails 7+ smoke test for issues #25 and #28 # # Verifies the image is consumable by Rails 7+ projects out-of-the-box: # 1. Gemfile with `platforms: %i[mri windows]` parses (needs Bundler 2.6+). # 2. make _lint scopes to RUBY_PATHS — vendor/bundle/ is NOT scanned. +# 3. `bundle install` succeeds against a Gemfile containing `gem 'debug'` +# — exercises the psych->libyaml native compile path (issue #28). # # Usage: bash tests/smoke-rails.sh # Env: @@ -15,7 +17,17 @@ set -euo pipefail IMAGE="${DEVRAIL_IMAGE:-ghcr.io/devrail-dev/dev-toolchain}:${DEVRAIL_TAG:-local}" REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" FIXTURE="$(mktemp -d)" -trap 'rm -rf "$FIXTURE"' EXIT + +# bundle install creates root-owned files inside the bind mount. Host-side `rm` +# can't delete them; do the cleanup inside a container instead. +cleanup() { + if [ -n "${FIXTURE:-}" ] && [ -d "$FIXTURE" ]; then + docker run --rm -v "$FIXTURE:/cleanup" "$IMAGE" \ + sh -c 'rm -rf /cleanup/* /cleanup/.[!.]* 2>/dev/null || true' >/dev/null 2>&1 || true + rmdir "$FIXTURE" 2>/dev/null || rm -rf "$FIXTURE" 2>/dev/null || true + fi +} +trap cleanup EXIT # --- Build a minimal Rails-shaped fixture ---------------------------------- mkdir -p "$FIXTURE"/{app,lib,vendor/bundle/ruby/3.4.0/gems/noisy/lib} @@ -107,4 +119,39 @@ if [ "$elapsed" -gt 60 ]; then exit 1 fi -echo "==> All Rails smoke checks passed (lint completed in ${elapsed}s)" +echo "==> Rails lint scoping: PASS (completed in ${elapsed}s)" + +# --- 3) bundle install must succeed against the Rails-shaped Gemfile ------- +# Issue #28: psych 5.x native build needs libyaml-dev headers in the runtime. +# Without them, `debug -> irb -> rdoc -> psych` resolution fails when bundler +# tries to compile psych. This step does a real network install — needs +# rubygems.org reachable from the runner. +echo "==> Running bundle install (needs libyaml-dev for psych native compile)" +bundle_start=$(date +%s) +bundle_output=$(docker run --rm \ + -v "$FIXTURE:/workspace" \ + -w /workspace \ + -e BUNDLE_PATH=/workspace/vendor/bundle \ + "$IMAGE" \ + bundle install --jobs 4 --quiet 2>&1) && bundle_exit=0 || bundle_exit=$? +bundle_elapsed=$(($(date +%s) - bundle_start)) + +if [ "$bundle_exit" -ne 0 ]; then + printf '%s\n' "$bundle_output" + echo "FAIL: bundle install exited $bundle_exit — likely missing libyaml-dev or network issue" >&2 + exit 1 +fi + +if ! docker run --rm \ + -v "$FIXTURE:/workspace" \ + -w /workspace \ + -e BUNDLE_PATH=/workspace/vendor/bundle \ + "$IMAGE" \ + bundle exec ruby -e "require 'psych'; puts 'psych ' + Psych::VERSION + ' loads OK'" >/dev/null 2>&1; then + echo "FAIL: psych installed but cannot be required — libyaml runtime/header mismatch" >&2 + exit 1 +fi + +echo "==> bundle install + psych load: PASS (completed in ${bundle_elapsed}s)" + +echo "==> All Rails smoke checks passed"