Skip to content

[codex] Centralize libyaml setup in Ruby action#3758

Merged
justin808 merged 4 commits into
mainfrom
codex/issue-3521-centralize-libyaml
Jun 7, 2026
Merged

[codex] Centralize libyaml setup in Ruby action#3758
justin808 merged 4 commits into
mainfrom
codex/issue-3521-centralize-libyaml

Conversation

@justin808

@justin808 justin808 commented Jun 7, 2026

Copy link
Copy Markdown
Member

Closes #3521.

Summary

  • Extend the local setup-ruby composite action so it can optionally run ruby/setup-ruby with Bundler cache settings.
  • Have setup-bundle delegate Ruby setup and gem caching through the shared setup-ruby action instead of calling ruby/setup-ruby directly.
  • Replace benchmark workflow's manual libyaml-dev install steps with the shared setup-ruby action.
  • Add an install-libyaml passthrough so workflows that already ran setup-ruby can call setup-bundle without a duplicate libyaml-dev install.
  • Document that install-libyaml only takes effect on Linux runners, matching the guarded install step.
  • Update the VM script-caching analysis artifact note to avoid pointing readers at an ephemeral local tmp path.

Validation

  • actionlint - passed.
  • ruby -e 'require "yaml"; files = Dir[".github/actions/*/action.yml", ".github/workflows/*.yml"].sort; files.each { |path| YAML.load_file(path) }; puts "parsed #{files.size} yaml files"' - parsed 30 YAML files.
  • pnpm dlx prettier@3.6.2 --check .github/actions/setup-ruby/action.yml .github/actions/setup-bundle/action.yml .github/workflows/benchmark.yml .github/workflows/dummy-app-bundler-tests.yml .github/workflows/examples.yml .github/workflows/gem-tests.yml .github/workflows/lint-js-and-ruby.yml .github/workflows/playwright.yml .github/workflows/precompile-check.yml .github/workflows/pro-integration-tests.yml .github/workflows/pro-test-package-and-gem.yml .github/workflows/shakaperf-release-gates.yml analysis/vm-script-caching-investigation-2026-06-07.md - passed.
  • git diff --check - passed.
  • script/ci-changes-detector origin/main - CI infrastructure; recommended full suite, no benchmarks.
  • rg -n "sudo apt-get .*libyaml|Install libyaml-dev|ensure libyaml-dev|ruby/setup-ruby@v1|install-libyaml" .github/workflows .github/actions - direct libyaml-dev install remains centralized in setup-ruby; workflow setup-bundle calls that already ran setup-ruby now pass install-libyaml: 'false'.

Adversarial PR Review Gate

Findings:

  • BLOCKING: none remaining after current-head review fixes.
  • DISCUSS: none requiring maintainer input.
  • FOLLOWUP: optional future optimization: try installing libyaml-dev before apt-get update on warm runners. This is advisory, pre-existing behavior, and outside the centralization scope of this PR.
  • NON_BLOCKING_DECISION: keep ruby/setup-ruby@v1 usage inside the shared setup-ruby action; the centralization target is removal of workflow/local-action bypasses and manual libyaml-dev installs, not vendoring the upstream Ruby setup action. Keep bundler-cache: false explicit in the non-cache setup path for readability, even though it matches the upstream default. Keep setup-bundle focused on bundle setup while documenting the Linux-only install-libyaml behavior in setup-ruby; workflow call sites already pass install-libyaml: 'false' when setup-ruby has already run. Keep the setup-ruby split comment concise: the cache path is the only path where Bundler env vars can matter because the non-cache path does not run bundle install.
  • NOISE: no code-runtime validation was run because this is CI composite-action wiring; GitHub Actions checks are the authoritative integration validation.

Readiness note: non-draft and ready to merge once current-head CI is green.


Note

Low Risk
CI composite-action wiring only; behavior should match prior Ruby/Bundler and libyaml steps, with integration validated by GitHub Actions runs.

Overview
libyaml and Ruby/Bundler setup are consolidated in the local setup-ruby composite action, and setup-bundle now delegates to it instead of calling ruby/setup-ruby directly.

setup-ruby gains optional Bundler cache install (working-directory, bundler-cache, frozen, cache-version) with separate steps for cache vs non-cache paths, and keeps libyaml-dev install behind install-libyaml (Linux only). setup-bundle adds an install-libyaml passthrough; workflows that already run setup-ruby pass install-libyaml: 'false' on subsequent setup-bundle steps to avoid duplicate apt installs. Benchmark workflow drops inline libyaml-dev steps and uses ./.github/actions/setup-ruby.

The VM script-caching analysis note is updated so artifact references stay in the committed doc instead of an ephemeral tmp path.

Reviewed by Cursor Bugbot for commit dfbbeac. Bugbot is set up for automated code reviews on this repo. Configure here.

Summary by CodeRabbit

  • Chores
    • Refactored Ruby and Bundler configuration in CI/CD pipelines with updated composite GitHub Actions for improved maintainability.
    • Added configurable control for optional libyaml installation dependencies across test and build workflows to improve flexibility in various environments.

@coderabbitai

coderabbitai Bot commented Jun 7, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

Walkthrough

Centralize Ruby/Bundler setup into a repo-local composite action: extend .github/actions/setup-ruby with bundler-cache inputs and conditional steps; add install-libyaml and repoint setup-bundle to call it; update workflows to use the local action and pass install-libyaml: 'false'; reformat an analysis doc.

Changes

Ruby/Bundler setup centralization

Layer / File(s) Summary
setup-ruby action: inputs and conditional Bundler caching
.github/actions/setup-ruby/action.yml
Extend description and inputs (working-directory, bundler-cache, frozen, cache-version) and split implementation into non-cached and cached paths that wire Bundler env and cache-version.
setup-bundle: add install-libyaml and delegate to local setup-ruby action
.github/actions/setup-bundle/action.yml
Remove libyaml-dev guidance from description, add install-libyaml input (default 'true'), and reroute the "Setup Ruby and install cached gems" step to ./.github/actions/setup-ruby, passing bundler-version, frozen, and install-libyaml as inputs instead of setting BUNDLE_* env vars.
Workflows: use local setup-ruby and disable libyaml where requested
.github/workflows/*
Replace ruby/setup-ruby@v1 with ./.github/actions/setup-ruby in gated benchmark paths, remove duplicate sudo apt-get install -y libyaml-dev steps, and add install-libyaml: 'false' to many setup-bundle invocations across CI workflows.
Investigation doc: artifacts and fenced output
analysis/vm-script-caching-investigation-2026-06-07.md
Add an explicit committed-analysis note in “Artifacts” clarifying retained vs. discarded items and wrap raw compilation cost output in a labeled text fenced code block.

Sequence Diagram(s)

sequenceDiagram
  participant WorkflowJob
  participant setup_bundle as ./.github/actions/setup-bundle
  participant setup_ruby as ./.github/actions/setup-ruby
  participant upstream as ruby/setup-ruby@v1
  WorkflowJob->>setup_bundle: call setup-bundle (with install-libyaml)
  setup_bundle->>setup_ruby: delegate Ruby/Bundler setup (bundler-version, frozen, install-libyaml, bundler-cache)
  setup_ruby->>upstream: invoke ruby/setup-ruby@v1 (cached or non-cached path)
  upstream-->>setup_ruby: install Ruby / manage Bundler cache
  setup_ruby-->>setup_bundle: return status
  setup_bundle-->>WorkflowJob: continue job steps
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Suggested labels

enhancement, review-needed, full-ci, P2, codex

Suggested reviewers

  • AbanoubGhadban
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the main change: centralizing libyaml setup in the Ruby action through refactoring and configuration changes across multiple workflow files.
Linked Issues check ✅ Passed All objectives from issue #3521 are met: setup-ruby is extended with configurable inputs (working-directory, bundler-cache, frozen, cache-version); setup-bundle delegates to setup-ruby; manual libyaml-dev installations are replaced; install-libyaml passthrough prevents duplicate installs; and workflows are updated accordingly.
Out of Scope Changes check ✅ Passed The analysis document update clarifies artifact retention; while not directly related to libyaml centralization, it addresses documentation clarity for the same code review effort and appears incidental rather than introducing unrelated functionality.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch codex/issue-3521-centralize-libyaml

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@claude

claude Bot commented Jun 7, 2026

Copy link
Copy Markdown
Contributor

Code Review

Summary: Clean CI refactor that centralizes libyaml-dev installation and Ruby/Bundler setup into a single composite action. The approach is sound and the implementation is correct.

What is Good

  • True centralization. No direct ruby/setup-ruby@v1 calls or libyaml apt installs remain outside the shared action — every bypass is gone (the stated goal of Centralize libyaml/setup-ruby #3521).
  • Robust libyaml install. The old benchmark.yml ran sudo apt-get install -y libyaml-dev without apt-get update first; the shared action always runs apt-get update before the install — a quiet reliability improvement on cold runners.
  • String-boolean comparisons are correct. Using inputs.bundler-cache != true / == true is the right GitHub Actions idiom when the default is the string false. No type-coercion surprise.
  • OS guard preserved. runner.os == Linux on the libyaml step means macOS/Windows runners are unaffected even though install-libyaml defaults to true.

Minor Observations

  1. Two-step split in setup-ruby deserves a comment — The two nearly-identical ruby/setup-ruby steps gated by bundler-cache != true and == true are intentional (GitHub Actions has no conditional env block on a step), but a one-line comment explaining the split would help future readers avoid collapsing them.

  2. bundler-version description nudge — The updated description says Callers that enable bundler-cache usually want Gemfile.lock but callers almost always go through setup-bundle, which already defaults to Gemfile.lock. The nudge is low-value at the setup-ruby level and could be cut.

  3. apt-get update latency — The detect-changes job now runs apt-get update inside the shared action where the old code skipped it. Correctness improvement, but adds ~5-10 s to affected runs. Not a blocker; worth tracking if benchmark CI time is a concern.

Verdict

No blocking issues. Centralization is correct, the libyaml conditional is properly guarded by OS and input flag, and setup-bundle delegation preserves original BUNDLE_FROZEN/RETRY/JOBS semantics.

Recommend: approve once CI is green.

Comment thread .github/actions/setup-ruby/action.yml
Comment thread .github/actions/setup-ruby/action.yml
@justin808 justin808 force-pushed the codex/issue-3521-centralize-libyaml branch from e29b913 to 6e91005 Compare June 7, 2026 06:32
@claude

claude Bot commented Jun 7, 2026

Copy link
Copy Markdown
Contributor

Code Review: Centralize libyaml setup in Ruby action

Summary: Clean centralization that moves libyaml installation and the conditional bundler-cache path into the shared setup-ruby composite action. The benchmark workflow correctly sheds its duplicate apt steps, and setup-bundle now delegates fully rather than calling ruby/setup-ruby@v1 directly. Validation steps in the PR description are thorough.


Correctness

Benchmark workflow — both changes are correct:

  • detect-changes job: the Setup Ruby conditional already gates both the old libyaml step and the old ruby step under the same if:, so folding both into a single setup-ruby call preserves the same condition.
  • benchmark job: the old libyaml step was unconditional; install-libyaml defaults to 'true', so the new setup-ruby call is equivalent.

String comparisonsinputs.bundler-cache == 'true' and != 'true' are correct. GitHub Actions always coerces with: values to strings, so callers passing the unquoted boolean true (as setup-bundle does on line 43) are safely coerced to the string 'true'.

BUNDLE_FROZEN env var — Bundler parses its env vars with false-ish handling for the strings "false" and "0", so passing frozen: 'false' correctly disables frozen mode.


Existing workflows will pay a redundant libyaml install

Several workflows call both setup-ruby and setup-bundle in the same job (e.g. dummy-app-bundler-tests.yml, lint-js-and-ruby.yml, gem-tests.yml, playwright.yml). The old pattern made sense because setup-bundle required libyaml to be pre-installed by the caller. Now that setup-bundle delegates to setup-ruby (which installs libyaml), those workflows will run apt-get update && apt-get install libyaml-dev twice — harmless due to apt idempotency, but adds wall-clock time.

These workflows can be simplified in a follow-up: drop the standalone setup-ruby step and let setup-bundle handle the full setup. That would be the ideal end state of issue #3521 for those workflows. Worth noting as a follow-up task.


Minor API design note

setup-bundle does not expose the install-libyaml passthrough from setup-ruby. A caller using setup-bundle cannot opt out of the libyaml apt step (e.g. on a pre-provisioned runner or a future macOS runner). Currently all callers are Linux and benefit from it, so this is fine for now — just worth keeping in mind if setup-bundle ever targets non-Linux runners.


Nit

In the non-cache path (first ruby/setup-ruby@v1 call in setup-ruby/action.yml, line 53), bundler-cache: false is explicit but redundant — ruby/setup-ruby defaults to no cache. No action needed.


Overall: Approved. The centralization is correct, the benchmark workflow changes are clean, and the bundler-cache branching keeps BUNDLE_FROZEN/BUNDLE_RETRY/BUNDLE_JOBS scoped only to the cache path. The redundant libyaml install in multi-action workflows is a pre-existing pattern this PR partially addresses — a follow-up cleanup removing the standalone setup-ruby calls in those workflows would complete the centralization.

Comment thread .github/actions/setup-ruby/action.yml
Comment thread .github/actions/setup-bundle/action.yml
@justin808 justin808 force-pushed the codex/issue-3521-centralize-libyaml branch from 6e91005 to d771225 Compare June 7, 2026 18:44
@justin808 justin808 marked this pull request as ready for review June 7, 2026 18:46
@greptile-apps

greptile-apps Bot commented Jun 7, 2026

Copy link
Copy Markdown

Greptile Summary

This PR centralizes the libyaml-dev installation and optional Bundler cache setup into the shared setup-ruby composite action, eliminating duplicated inline steps across workflows.

  • setup-ruby gains bundler-cache, frozen, cache-version, and working-directory inputs, splitting into two conditional ruby/setup-ruby@v1 steps to work around GitHub Actions' lack of conditional env blocks on a single step.
  • setup-bundle drops its direct ruby/setup-ruby@v1 call and delegates fully to setup-ruby (with bundler-cache: true), also correctly renaming the bundler input to bundler-version.
  • benchmark.yml removes the manual Install libyaml-dev steps and replaces direct ruby/setup-ruby@v1 usage with ./.github/actions/setup-ruby.

Confidence Score: 4/5

Safe to merge; changes are CI composite-action wiring only with no runtime code impact.

The refactoring correctly centralizes libyaml setup and Bundler cache wiring. The benchmark job ends up running apt-get install libyaml-dev twice per run (once via the standalone setup-ruby call, once via setup-bundle to setup-ruby), which the PR itself flags as a known follow-up. No functional breakage was found.

benchmark.yml — the benchmark job calls setup-ruby standalone then setup-bundle (which calls setup-ruby again), resulting in a double libyaml-dev install per run.

Important Files Changed

Filename Overview
.github/actions/setup-ruby/action.yml Extended with bundler-cache, frozen, cache-version, and working-directory inputs; splits into two conditional ruby/setup-ruby steps to work around GitHub Actions' lack of conditional env blocks.
.github/actions/setup-bundle/action.yml Cleanly delegates to setup-ruby instead of calling ruby/setup-ruby directly; input rename from bundler to bundler-version is correctly reflected.
.github/workflows/benchmark.yml Replaces inline libyaml-dev installs and direct ruby/setup-ruby calls with the shared setup-ruby action; the benchmark job now installs libyaml-dev twice (once via the standalone setup-ruby step, once via setup-bundle → setup-ruby).

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[benchmark.yml / workflow] -->|plain Ruby setup| B[setup-ruby action]
    A -->|gems needed| C[setup-bundle action]

    B --> D{Linux and install-libyaml?}
    D -->|yes| E[apt-get install libyaml-dev]
    D -->|no| F{bundler-cache == true?}
    E --> F
    F -->|no| G[ruby/setup-ruby v1 no cache]
    F -->|yes| H[ruby/setup-ruby v1 with cache and BUNDLE env]

    C --> I[Verify Gemfile.lock committed]
    I --> J[setup-ruby action bundler-cache true]
    J --> K{Linux and install-libyaml?}
    K -->|yes| L[apt-get install libyaml-dev again]
    K -->|no| M[ruby/setup-ruby v1 with cache]
    L --> M

    style L fill:#ffc,stroke:#aa0
Loading

Reviews (1): Last reviewed commit: "ci: centralize libyaml setup in ruby act..." | Re-trigger Greptile

Comment thread .github/workflows/benchmark.yml
Comment thread .github/actions/setup-ruby/action.yml
@claude

claude Bot commented Jun 7, 2026

Copy link
Copy Markdown
Contributor

Code Review

Overview

Clean, well-structured centralization. The two-step split to work around GitHub Actions' lack of conditional env blocks is the right approach and the comment explaining it is valuable. YAML validity and actionlint passing are the right gates for this type of change.


Issues

Double libyaml-dev install (impactful, not just a followup)

Four production workflows call both .github/actions/setup-ruby and .github/actions/setup-bundle in the same job:

  • gem-tests.yml (lines 124 + 139)
  • lint-js-and-ruby.yml (lines 122 + 155/183)
  • playwright.yml (lines 56 + 87)
  • examples.yml (lines 127 + 167)

After this PR, setup-bundle always calls setup-ruby, which always runs apt-get update && apt-get install libyaml-dev on Linux. Jobs that already called setup-ruby for the pre-gem Ruby step now run that apt-get sequence twice. Each double-install adds ~15–25 seconds on a cold runner per job, and those are high-frequency workflows.

The PR description marks this as a FOLLOWUP, but given the scope (4 workflows, all on the hot path), it's worth addressing in the same PR — or at minimum, opening a tracking issue so it doesn't get forgotten.

The simplest fix: expose install-libyaml as a pass-through input on setup-bundle so callers that already ran setup-ruby can pass install-libyaml: 'false'. Alternatively, the two-step workflows can be converted to use only setup-bundle (since it now owns Ruby setup) and reorder any intermediate steps.

bundler-cache string comparison gap

The two conditional steps use != 'true' / == 'true'. If a caller ever passes an unexpected truthy-but-not-'true' value (e.g., bundler-cache: 'yes', '1', empty string), neither step fires and Ruby won't be set up at all — a silent failure surfacing only at the first ruby invocation. Unlikely in practice since callers are internal, but worth noting for a shared action.


Minor

  • Missing explicit bundler-cache: false: The old setup-ruby step had bundler-cache: false explicitly. The new non-cache step relies on the upstream default. The PR description's NON_BLOCKING_DECISION says to keep it explicit, but the code dropped it. Functionally equivalent, but inconsistent with the stated intent.
  • BUNDLE_RETRY/BUNDLE_JOBS hardcoded: Pre-existing behavior, not a regression.

Summary

The design goal is right and the implementation is correct. The main ask before merging is a plan for the double-apt-get in the four co-calling workflows — either address in this PR or open a concrete tracking issue.

Comment thread .github/actions/setup-bundle/action.yml
Comment thread .github/actions/setup-ruby/action.yml
Comment thread .github/actions/setup-ruby/action.yml
@justin808 justin808 force-pushed the codex/issue-3521-centralize-libyaml branch 2 times, most recently from bea8f02 to 4741434 Compare June 7, 2026 18:58
coderabbitai[bot]
coderabbitai Bot previously requested changes Jun 7, 2026

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@analysis/vm-script-caching-investigation-2026-06-07.md`:
- Around line 162-165: The artifact pointer "Original experiment:
`vm-script-cache/tmp/experiments/20260607T083551Z-vm-script-cache/`" is an
ephemeral local tmp path; update the pointer to a durable location by replacing
that tmp path with a stable repo artifact or permalink (e.g., a committed repo
path, an artifacts/ directory, or a permalink to the experiment bundle) or
include a commit SHA/CI artifact URL and attach the raw data so future readers
can verify the experiment; ensure the updated reference is placed where
"Original experiment" is declared.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 6f345143-e7e0-4498-81b4-4ea718d77d75

📥 Commits

Reviewing files that changed from the base of the PR and between bea8f02 and 4741434.

📒 Files selected for processing (4)
  • .github/actions/setup-bundle/action.yml
  • .github/actions/setup-ruby/action.yml
  • .github/workflows/benchmark.yml
  • analysis/vm-script-caching-investigation-2026-06-07.md
🚧 Files skipped from review as they are similar to previous changes (3)
  • .github/actions/setup-ruby/action.yml
  • .github/actions/setup-bundle/action.yml
  • .github/workflows/benchmark.yml

Comment thread analysis/vm-script-caching-investigation-2026-06-07.md Outdated
@claude

claude Bot commented Jun 7, 2026

Copy link
Copy Markdown
Contributor

Code Review -- Overview: This PR centralizes libyaml-dev installation into the shared setup-ruby composite action. setup-bundle now delegates to setup-ruby instead of calling ruby/setup-ruby@v1 directly, and benchmark.yml drops its manual apt-get steps. The analysis doc changes are pure Prettier formatting. Overall a solid cleanup; a few items worth addressing before merge. Issues: (1) Double libyaml install per run -- In the benchmark job, both the standalone setup-ruby step (line 245) and the downstream setup-bundle step (line 330, which internally calls setup-ruby) will run apt-get update && apt-get install libyaml-dev since install-libyaml defaults to true. The same pattern repeats in every workflow with standalone setup-ruby followed by setup-bundle in the same job (examples.yml, lint-js-and-ruby.yml, gem-tests.yml, several pro- workflows). It is idempotent but costs 5-15s per job. Recommended fix: expose install-libyaml as a passthrough input on setup-bundle (default true) and forward it to the internal setup-ruby call so callers that already ran setup-ruby can pass install-libyaml: false to setup-bundle to skip the duplicate. (2) Code contradicts PR description on bundler-cache: false -- The NON_BLOCKING_DECISION note in the PR body says keep bundler-cache: false explicit in the non-cache setup path for readability, but the non-cache Setup Ruby step in setup-ruby/action.yml does not pass it. Relying on the upstream default is fine functionally; either add the parameter or update the description to match. (3) BUNDLE_RETRY and BUNDLE_JOBS hardcoded in shared action (minor) -- These were hardcoded in setup-bundle before and are now hardcoded in setup-ruby. No regression, but promoting them to the shared layer makes them non-overridable without a flag. Consider exposing as optional inputs. Not a blocker. What is good: install-libyaml defaults to true so the action is safe-by-default. The two-step cache/non-cache split with the explaining comment is the right pattern for GitHub Actions lack of conditional env blocks. The setup-bundle description update correctly reflects that libyaml is now handled internally. The bundler to bundler-version rename on setup-ruby public interface is consistent.

Comment thread .github/actions/setup-bundle/action.yml
Comment thread .github/actions/setup-ruby/action.yml
Comment thread .github/actions/setup-ruby/action.yml
@justin808 justin808 force-pushed the codex/issue-3521-centralize-libyaml branch from 4741434 to 1404407 Compare June 7, 2026 19:02
@justin808 justin808 dismissed coderabbitai[bot]’s stale review June 7, 2026 19:13

Dismissed stale CodeRabbit requested-changes review from an older commit. The actionable markdown artifact-path comment was fixed in current head 1404407, and the CodeRabbit status check is now green. Merge gating is CI plus addressed substantive review comments.

Comment thread .github/actions/setup-ruby/action.yml
Comment thread .github/actions/setup-bundle/action.yml
@claude

claude Bot commented Jun 7, 2026

Copy link
Copy Markdown
Contributor

Code Review Summary

What is good: Correct workaround for GH Actions conditional env limitation; clean bundler-version rename; backward-compatible; thorough validation in PR description.

Issues found:

  1. Double libyaml installs (see inline comment on setup-bundle) - Jobs calling both setup-ruby and setup-bundle now run apt-get update + install libyaml-dev 2-3x per job. Measurable CI overhead; needs a follow-up issue/PR to remove redundant standalone setup-ruby calls from those jobs.

  2. Missing bundler-cache: false in non-cache step (see inline comment on setup-ruby) - PR description says to keep it explicit for readability but it was not added.

  3. Analysis doc in repo root - analysis/vm-script-caching-investigation-2026-06-07.md is a one-off artifact; consider docs/ or wiki instead.

Verdict: Changes are correct and safe - no blocking issues. Item 1 is the most impactful and should be tracked promptly.

@claude

claude Bot commented Jun 7, 2026

Copy link
Copy Markdown
Contributor

Code Review: Centralize libyaml setup in Ruby action. Overall: Clean, low-risk CI infra refactor - see inline comments for details.

@justin808

Copy link
Copy Markdown
Member Author

Latest review-thread triage for 95cc16cfe1cf82fbdce378dbf8be3a843184060f:

  • The bundler-cache: false readability decision is implemented in .github/actions/setup-ruby/action.yml at the non-cache ruby/setup-ruby@v1 step. Verified with git show 95cc16cfe1cf82fbdce378dbf8be3a843184060f:.github/actions/setup-ruby/action.yml.
  • The duplicate libyaml-dev concern is addressed by the new setup-bundle install-libyaml passthrough plus explicit install-libyaml: 'false' on every same-job setup-ruby -> setup-bundle call. Verified with the YAML parser assertion recorded in the PR body: all same-job setup-bundle calls opt out of libyaml install.\n\nNo remaining BLOCKING/DISCUSS review item from those threads.

@claude

claude Bot commented Jun 7, 2026

Copy link
Copy Markdown
Contributor

Code Review — Centralize libyaml setup in Ruby action

Overall assessment: Clean, low-risk CI infrastructure refactor. Centralization is well-structured, actionlint / Prettier / YAML parse validation is thorough, and the behavioral change is small and idempotent.


What the PR does

  • Adds working-directory, bundler-cache, frozen, and cache-version inputs to setup-ruby, splitting into two conditional ruby/setup-ruby steps because GitHub Actions cannot conditionally apply env: to a single step.
  • Migrates setup-bundle to delegate its ruby/setup-ruby call through setup-ruby instead of calling the upstream action directly.
  • Removes the manual Install libyaml-dev steps from benchmark.yml, replacing bare ruby/setup-ruby@v1 calls with the local setup-ruby action.
  • Fixes formatting in the analysis doc (no logic change).

Issues / discussion points

1. Double libyaml install in workflows that pair setup-ruby + setup-bundle (acknowledged as FOLLOWUP)

About 15 jobs across 8 workflows call setup-ruby (Ruby runtime only) and then setup-bundle (which now calls setup-ruby again with bundler-cache: true). Both calls default to install-libyaml: true, so apt-get update && apt-get install -y libyaml-dev runs twice per job. Functionally safe since it is idempotent, but adds ~3-5 s overhead per run. A short-term fix would be to expose install-libyaml as a passthrough input in setup-bundle so callers can skip it when setup-ruby already ran; the longer-term fix is the one noted in the PR: remove the standalone setup-ruby call from jobs where setup-bundle should own the full setup.

2. apt-get update added to benchmark paths that previously skipped it

The old benchmark steps ran sudo apt-get install -y libyaml-dev (no update). The new setup-ruby action runs sudo apt-get update && apt-get install -y --no-install-recommends libyaml-dev. The --no-install-recommends flag and the explicit update are both improvements for cold-runner correctness, but add a few extra seconds to benchmark jobs on every run. Acceptable tradeoff, just worth noting.

3. BUNDLE_FROZEN with string false in non-frozen matrix legs — works correctly

Workflows like dummy-app-bundler-tests.yml pass frozen via a ternary that can produce the string false. The env var BUNDLE_FROZEN=false is set. Bundler correctly treats this as boolean false (matches the false case in Bundler's to_bool helper), so minimum-dependency legs install without frozen mode as intended. No bug, but worth a comment in the action for future readers.

4. install-libyaml not passable from setup-bundle

setup-bundle does not forward an install-libyaml option to setup-ruby, so callers cannot opt out when libyaml is already installed. Not a problem today (item 1 shows it is just idempotent overhead), but it removes flexibility for non-Linux or pre-warmed runners. Low priority given the current runner profile.


Minor nit (not blocking)

The setup-bundle description now reads Setup Ruby, cache, and install gems for a Bundler project. Since setup-bundle now handles libyaml automatically, a note like includes libyaml-dev on Linux runners would keep it self-documenting. The old description warned callers to install it themselves; the new one gives no hint either way.


Summary

The refactor achieves its goal: one place owns libyaml + Ruby setup, direct ruby/setup-ruby@v1 usage is gone from all workflows/actions except inside the canonical action, and the benchmark workflow is simplified. The double-install consequence is the main operational concern and is correctly flagged as FOLLOWUP.

@claude

claude Bot commented Jun 7, 2026

Copy link
Copy Markdown
Contributor

Code Review: Centralize libyaml setup in Ruby action

Summary: This PR cleanly centralizes libyaml-dev installation and the Bundler-cache wiring into the shared setup-ruby composite action. The overall approach is sound and the validation evidence in the PR description is comprehensive.


Positives

  • Good centralization: Removing duplicated sudo apt-get install -y libyaml-dev steps from workflows in favor of a single authoritative install inside setup-ruby is the right design.
  • Bug fix included: The old benchmark.yml steps ran apt-get install -y libyaml-dev without a preceding apt-get update, which is unreliable on stale package indexes. The new approach via setup-ruby adds the update first — an implicit correctness improvement.
  • Inline comment in setup-ruby: The comment explaining why two separate ruby/setup-ruby steps are needed (GitHub Actions doesn't support conditional env: blocks on a single step) is exactly the kind of non-obvious rationale worth preserving.

Issues / Suggestions

install-libyaml description should mention Linux-only behaviour

The description reads:

description: Whether to install libyaml-dev before Ruby/Bundler steps.

But the implementation guards on runner.os == 'Linux'. On macOS/Windows runners this flag is silently ignored, which could confuse a caller who passes install-libyaml: 'true' on a non-Linux runner and wonders why libyaml wasn't installed. Suggest:

description: >
  Whether to install libyaml-dev before Ruby/Bundler steps.
  Only takes effect on Linux runners; silently ignored elsewhere.

Hardcoded BUNDLE_RETRY / BUNDLE_JOBS reduce future flexibility

The Bundler env vars BUNDLE_RETRY: '3' and BUNDLE_JOBS: '4' were previously set in setup-bundle and are now hardcoded inside setup-ruby's cached-gems step. Callers can no longer override them. The values are sensible defaults and nobody was overriding them before, so this is a very minor regression in flexibility. Worth keeping in mind if a future caller (e.g. a runner with many cores) wants higher parallelism — a bundle-jobs / bundle-retry input could be added then. Not a blocker.

Two-step split creates parallel maintenance surface

The split into two nearly-identical ruby/setup-ruby@v1 steps (non-cache and cache paths) means any future parameter change to ruby/setup-ruby that applies to both paths must be added in two places. The existing comment explains the why; a one-liner like # When adding new ruby/setup-ruby inputs, add them to BOTH steps below. near the split would make the maintenance requirement explicit for future contributors.


Correctness check: BUNDLE_FROZEN string values

BUNDLE_FROZEN: ${{ inputs.frozen }} passes the string 'true' or 'false'. Bundler accepts these the same as '1' / '0' for env-var config, so this is correct — unchanged from the old setup-bundle behaviour.


Analysis doc changes

The Prettier-reformatted tables in analysis/vm-script-caching-investigation-2026-06-07.md are correct but unrelated to this PR's purpose. They inflate the diff without adding value; squashing them into the original commit or landing them separately would keep the diff focused. Not a blocker.


Verdict: Approve with the install-libyaml description wording as a recommended (non-blocking) fix. The logic is correct, the validation gate in the PR description is thorough, and the centralization goal is well-executed.

Comment thread .github/actions/setup-ruby/action.yml Outdated
@claude

claude Bot commented Jun 7, 2026

Copy link
Copy Markdown
Contributor

Code Review - see full review below

@justin808 justin808 force-pushed the codex/issue-3521-centralize-libyaml branch from 95cc16c to 506ac6a Compare June 7, 2026 19:41
@claude

claude Bot commented Jun 7, 2026

Copy link
Copy Markdown
Contributor

test discard

@claude

claude Bot commented Jun 7, 2026

Copy link
Copy Markdown
Contributor

Code Review

Overview

This PR centralizes libyaml-dev installation in the shared setup-ruby composite action and extends it to optionally handle Bundler caching, so setup-bundle no longer calls ruby/setup-ruby directly. The result is a clear two-action hierarchy (setup-rubysetup-bundle) and the elimination of scattered manual libyaml-dev installs from the benchmark workflow.

What is Working Well

  • Consistent application across all 11 workflows. Every job that calls setup-ruby followed by setup-bundle in the same job now passes install-libyaml: 'false' on the second call. I traced all 30+ action invocations and found no missed cases.
  • Two-step split in setup-ruby (non-cache path vs cache path) is a correct workaround for GitHub Actions not supporting conditional env: blocks on a single step. The inline comment explains it clearly.
  • runner.os == 'Linux' guard on the libyaml install step correctly no-ops on macOS/Windows runners without requiring callers to pass install-libyaml: 'false'.
  • Validation was thoroughactionlint, YAML parse-check, Prettier, and rg audit all passed per the PR body.

Issues / Suggestions

1. Footgun potential: default install-libyaml: 'true' requires caller discipline

Both setup-ruby and setup-bundle default to install-libyaml: 'true'. A future author adding a setup-bundle call after setup-ruby in the same job will silently get two apt-get update + install sequences — not a correctness bug (idempotent), but wasted time (~10 s per run). Suggesting a short note in setup-bundle's description:

Pass install-libyaml: 'false' when setup-ruby has already run in the same job to avoid a redundant libyaml-dev install.

2. apt-get update runs unconditionally on every libyaml install

The libyaml step always runs sudo apt-get update && sudo apt-get install .... The apt-get update call adds 5–10 s and is only needed when the package index is stale. A try-first-then-update pattern avoids the overhead on warm runners:

run: >
  sudo apt-get install -y --no-install-recommends libyaml-dev 2>/dev/null ||
  (sudo apt-get update && sudo apt-get install -y --no-install-recommends libyaml-dev)

This pattern pre-existed this PR, so purely advisory for a follow-up issue.

3. Explicit bundler-cache: false in non-cache path (intentional, no action needed)

The non-cache ruby/setup-ruby step sets bundler-cache: false, which matches the upstream default. The PR's own adversarial review notes this is kept intentionally for readability — confirming agreement.

Verdict

Logic is sound, all call sites are consistently updated, and the validation steps were comprehensive. Issues 1 and 2 are non-blocking advisory suggestions. Ready to merge once CI is green.

Comment thread .github/actions/setup-bundle/action.yml
Comment thread .github/actions/setup-ruby/action.yml
@claude

claude Bot commented Jun 7, 2026

Copy link
Copy Markdown
Contributor

Code Review: Centralize libyaml setup in Ruby action

Overview

This PR cleanly centralizes libyaml-dev installation and the ruby/setup-ruby call into the shared setup-ruby composite action, eliminating duplicated manual installs across 13 workflow files. The approach is correct and consistently applied.


What Works Well

Correct call-site pattern across all workflows. Every job that calls both setup-ruby and setup-bundle consistently puts setup-ruby first (which installs libyaml by default) and then passes install-libyaml: 'false' on all subsequent setup-bundle calls. I verified this pattern in every modified workflow file. No job is missing the initial libyaml install, and no job runs a redundant install.

Elegant workaround for GitHub Actions' conditional env limitation. The two-step split in setup-ruby/action.yml (non-cache vs. cache paths) is the right solution — Actions doesn't support conditional env: blocks on a single step, so the comment explaining the split is valuable.

--no-install-recommends improvement. The centralized libyaml install in setup-ruby now uses --no-install-recommends, whereas the original benchmark workflow's manual installs did not. Minor but correct improvement.

Bundler env vars correctly scoped. BUNDLE_FROZEN, BUNDLE_RETRY, and BUNDLE_JOBS are set only in the bundler-cache == 'true' step, matching the original behavior in setup-bundle.

Bundler version defaults preserved. setup-bundle defaults bundler-version to Gemfile.lock and passes it through to setup-ruby, which has its own default of default. The layering is correct.


Minor Observations

1. String equality for bundler-cache comparisons

if: inputs.bundler-cache != 'true'   # non-cache path
if: inputs.bundler-cache == 'true'   # cache path

GitHub Actions inputs are always strings, so this is correct. However, it means only the literal string 'true' activates the cache path — passing an unquoted true (YAML boolean) or yes would silently fall through to the non-cache path. All callers today pass bundler-cache: true (hardcoded in the step YAML, not a user-exposed input), so this is not a live issue, but worth noting if the action is extended.

2. Opt-out pattern requires discipline from future contributors

The default install-libyaml: 'true' means any new setup-bundle call added after a prior setup-ruby call in the same job needs an explicit install-libyaml: 'false'. The cost of forgetting is only a small redundant apt-get install (not a correctness failure), but the pattern is a mild footgun. A future improvement could detect this automatically, though that is out of scope here.

3. apt-get update runs on every libyaml install

run: sudo apt-get update && sudo apt-get install -y --no-install-recommends libyaml-dev

This is the correct and safe approach for GitHub-hosted runners (stale apt indices are a known source of failures). Confirming it is intentional — no action needed.


Analysis Document Changes

The reformatting of analysis/vm-script-caching-investigation-2026-06-07.md is purely cosmetic (Prettier-aligned table cells, artifact path note updated). Content is unchanged and correct.


Verdict

No blocking issues. The centralization logic is sound, consistently applied, and well-validated (actionlint, YAML parse check, Prettier). Ready to merge once CI is green.

@justin808 justin808 force-pushed the codex/issue-3521-centralize-libyaml branch from 506ac6a to fbd2dd0 Compare June 7, 2026 20:23
@claude

claude Bot commented Jun 7, 2026

Copy link
Copy Markdown
Contributor

Code Review

Summary: Clean centralization of libyaml-dev installation. Moves install responsibility into setup-ruby, removes ad-hoc apt-get steps from benchmark.yml, and wires an install-libyaml passthrough through the action chain. YAML-parser validation and actionlint pass confirm the mechanics are solid.


Issues

Minor - opt-out footgun in setup-bundle

install-libyaml defaults to 'true' in setup-bundle. The contract is: any caller that already ran setup-ruby in the same job must remember to pass install-libyaml: 'false' to setup-bundle, or libyaml gets installed twice (harmless, but wastes ~20 s per job). This PR handles all 13 existing call sites correctly, but future contributors adding a new job following the setup-ruby + setup-bundle pattern will silently double-install unless they know the rule.

Suggestion: extend the install-libyaml description in setup-bundle/action.yml to say: "Pass 'false' if a prior setup-ruby step in this job already installed libyaml-dev."

Observation - double Ruby setup in the benchmark job (pre-existing)

In the benchmark job, setup-ruby at line 246 sets up the Ruby runtime for gem install foreman, then setup-bundle at line 330 calls setup-ruby again (with bundler-cache: true) to install app gems. ruby/setup-ruby is idempotent so this is harmless, but it is redundant. Pre-existing pattern, worth a future cleanup.


Positive highlights

  • apt-get update + --no-install-recommends: the old benchmark.yml ran apt-get install without update, which could silently fail on stale package lists. The centralized step is more correct on both counts.
  • Split steps in setup-ruby: two mutually-exclusive steps (cache / non-cache) to work around GitHub Actions not supporting conditional env: blocks on a single step. The comment explains the rationale clearly.
  • bundler-cache: false explicit: keeping the default explicit in the non-cache step aids readability.
  • Guard on runner.os == Linux: libyaml install correctly scoped to Linux runners.
  • Thorough call-site audit: every workflow calling setup-bundle after a prior setup-ruby in the same job was updated to pass install-libyaml: 'false'.

Verdict: Approve with the description-improvement suggestion above. The structural change is sound, validation is comprehensive, and the risk is low.

Comment thread .github/actions/setup-bundle/action.yml Outdated
@claude

claude Bot commented Jun 7, 2026

Copy link
Copy Markdown
Contributor

Code Review — PR #3758: Centralize libyaml setup in Ruby action

Overview

This PR centralizes libyaml-dev installation and Ruby setup into the shared setup-ruby composite action. Previously, workflows either had manual sudo apt-get install libyaml-dev steps or called ruby/setup-ruby directly. The refactoring removes that duplication and routes all callers through the shared action.

Scope: 13 files, all .github/ and CI infrastructure. No runtime application code is touched.


What's Working Well

Correct two-step split in setup-ruby
The split of ruby/setup-ruby into two named steps based on bundler-cache == 'true' is the right workaround for the GitHub Actions limitation that prevents conditional env: blocks on a single step. The comment explaining this is clear.

Consistent install-libyaml: 'false' placement
Verified all 13 modified workflows: every setup-bundle call with install-libyaml: 'false' is preceded by a setup-ruby step in the same job. The pattern is correct without exception:

  • lint-js-and-ruby.yml: setup-ruby at L122 → setup-bundle at L155, L184 ✓
  • dummy-app-bundler-tests.yml: setup-ruby at L38 → setup-bundle at L77; setup-ruby at L150 → setup-bundle at L198, L205 ✓
  • benchmark.yml: setup-ruby at L246 → setup-bundle at L330 ✓
  • pro-integration-tests.yml, pro-test-package-and-gem.yml, shakaperf-release-gates.yml all follow the same valid pattern ✓

Better libyaml-dev install
The old benchmark.yml had sudo apt-get install -y libyaml-dev without a preceding apt-get update. The new centralized step uses apt-get update && apt-get install -y --no-install-recommends libyaml-dev, which is better practice (avoids stale package lists and avoids pulling in recommended packages).

bundler-cache: false explicit in non-cache step
Making bundler-cache: false explicit even though it's the upstream default is the right call for readability — the two steps exist precisely to show the branching clearly.


Observations

frozen input is silently ignored when bundler-cache != 'true'
The frozen input description says "when bundler-cache is enabled", which is accurate — but a caller could set frozen: 'false' on a direct setup-ruby call without bundler-cache: true and get a silent no-op. No behavioral risk here (no direct setup-ruby callers in these workflows pass frozen), but adding "Has no effect when bundler-cache is false" to the description would prevent future confusion.

working-directory now passed on the non-cache path too
New in this PR: the non-cache ruby/setup-ruby step now receives working-directory: ${{ inputs.working-directory }}. Direct setup-ruby callers in the workflows don't pass working-directory, so they get the default ., which is fine. There is no observable behavioral difference for Ruby-only setup, but it is a new parameter to the previously bare non-cache invocation.


Minor Suggestions

  1. Document the frozen silent-ignore — adding "Has no effect when bundler-cache is false" to that input's description would save future callers a head-scratch.
  2. analysis/vm-script-caching-investigation-2026-06-07.md fix — the removal of the ephemeral tmp/ path reference and the addition of text fences on the code blocks are correct housekeeping.

Summary

The centralization is sound. The logic is correct throughout, the two-step workaround is properly handled, and the install-libyaml: 'false' propagation is accurate across all 13 changed files. The suggestions above are minor documentation improvements, not blockers.

Verdict: Looks good to merge once CI is green.

Comment thread .github/actions/setup-ruby/action.yml Outdated
Comment thread .github/actions/setup-ruby/action.yml
@claude

claude Bot commented Jun 7, 2026

Copy link
Copy Markdown
Contributor

Code Review — #3758 Centralize libyaml setup in Ruby action

Overview

Clean, well-scoped refactoring. Centralizing libyaml-dev and ruby/setup-ruby@v1 into the shared setup-ruby composite action eliminates duplication and makes future maintenance straightforward. The two-step split (non-cache vs cache) to work around GitHub Actions' lack of conditional env blocks is the right approach. Validation is thorough (actionlint, YAML parse, Prettier, rg sweep, git diff --check).


Correctness

  • install-libyaml: 'false' coverage is complete. Every workflow that calls setup-bundle after a prior setup-ruby in the same job correctly passes install-libyaml: 'false'. No double-install or missed-install cases found after a full sweep of all 13 changed workflow files.
  • String comparisons are correct. GitHub Actions always delivers inputs as strings, so inputs.install-libyaml == 'true' and inputs.bundler-cache == 'true' work correctly for both quoted ('true') and unquoted (true) YAML values at call sites.
  • BUNDLE_FROZEN string value is fine. Bundler's BOOL_KEYS list includes frozen, so the string "true"/"false" is parsed to a boolean correctly.
  • working-directory chain is correct. setup-bundlesetup-rubyruby/setup-ruby threads working-directory through correctly. The new default: '.' in setup-ruby is equivalent to omitting the input (GitHub Actions runner CWD is the repo root).
  • benchmark job libyaml flow is correct. The detect-changes job's conditional setup-ruby installs libyaml before the conditional bundle install (same guard). The benchmark job's unconditional setup-ruby installs libyaml, then the downstream setup-bundle correctly passes install-libyaml: 'false'.

Improvements vs. prior code

  • apt-get update added. Old benchmark.yml ran apt-get install -y libyaml-dev without apt-get update. The new centralized step adds apt-get update, which is more reliable on cold runners.
  • --no-install-recommends added. Reduces installed package footprint — good practice.
  • Description cleanup in setup-bundle. Removing the manual warning ("ensure libyaml-dev is already present or install it before calling this action") is correct now that the action handles it transparently.

Pre-existing concern (not introduced here, but now more impactful)

ruby/setup-ruby@v1 is referenced by floating major-version tag rather than a pinned commit SHA. This is now the single chokepoint for all Ruby setup across every workflow. Consider pinning to a SHA in a follow-up (ruby/setup-ruby@<sha> # v1.x.y) to close the supply-chain gap — especially since this PR deliberately concentrates the dependency.


Minor / optional

  • Future footgun risk: A developer adding a new job with setup-ruby + setup-bundle must remember to pass install-libyaml: 'false' on the bundle step. Forgetting causes a redundant apt-get install (idempotent, just slow). A brief note in AGENTS.md or the action description would help discoverability.
  • BUNDLE_RETRY/BUNDLE_JOBS are hardcoded in setup-ruby. Acceptable for the current scope; easy to promote to inputs later if needed.

Verdict: Ready to merge once CI is green. No blocking issues found.

Comment thread .github/actions/setup-ruby/action.yml
@justin808 justin808 merged commit 1048f99 into main Jun 7, 2026
45 checks passed
@justin808 justin808 deleted the codex/issue-3521-centralize-libyaml branch June 7, 2026 21:46
justin808 added a commit that referenced this pull request Jun 7, 2026
…orkflow-build-config-scope-nonforce

* origin/main:
  [codex] Centralize libyaml setup in Ruby action (#3758)
justin808 added a commit that referenced this pull request Jun 7, 2026
…un-skipped-ci-retry

* origin/main:
  [codex] Centralize libyaml setup in Ruby action (#3758)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Centralize libyaml/setup-ruby

1 participant