Skip to content

refa(devcontainer): rework to use mise for fast switching#2948

Open
solnic wants to merge 22 commits into
masterfrom
refa/rework-devcontainer
Open

refa(devcontainer): rework to use mise for fast switching#2948
solnic wants to merge 22 commits into
masterfrom
refa/rework-devcontainer

Conversation

@solnic
Copy link
Copy Markdown
Collaborator

@solnic solnic commented May 8, 2026

This rework comes with 3 nice improvements:

1. Mise for fast switching between modern ruby versions (including jruby)

The image by default ships with the latest ruby (4.0.3 at the moment), and then switching to older rubies is super easy:

➜  sentry git:(refa/rework-devcontainer) ruby -v            
ruby 4.0.3 (2026-04-21 revision 85ddef263a) +PRISM [aarch64-linux]
➜  sentry git:(refa/rework-devcontainer) mise shell ruby@3.4
ruby@3.4.9      extract ruby-3.4.9.arm64_linux.tar.gz                                                                                                    ✔
➜  sentry git:(refa/rework-devcontainer) ruby -v 
ruby 3.4.9 (2026-03-11 revision 76cca827ab) +PRISM [aarch64-linux]
➜  sentry git:(refa/rework-devcontainer) mise shell ruby@jruby
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100 38.8M  100 38.8M    0     0  86.2M      0 --:--:-- --:--:-- --:--:-- 86.4M
ruby@jruby-10.1.0.0 ==> Installed jruby-10.1.0.0 to /home/sentry/.local/share/mise/installs/ruby/jruby-10.1.0.0                                          ✔
➜  sentry git:(refa/rework-devcontainer) ruby -v
jruby 10.1.0.0 (4.0.0) 2026-04-20 32f988b78c OpenJDK 64-Bit Server VM 21.0.11+10-LTS on 21.0.11+10-LTS +indy +jit [aarch64-linux]

All that in less than 20s.

For legacy Rubies, we still use dedicated dev container builds, no way around this.

2. Improved e2e spec setup in CI

Supports running against 4.x and 3.x rubies and uses pre-built images from the build_images workflow. We also no longer depend on foreman for running e2e test apps, and instead we just use mise scripts.

3. Versioned dev container images with workflow manual trigger enabled

Our build images workflow publishes versioned images based on .devcontainer/VERSION so it's easier to maintain this setup now. Especially when a topic branch is used to make some tweaks, like this very PR/branch.

@solnic solnic changed the title Refa/rework devcontainer refa(devcontainer): rework to use mise for fast switching May 11, 2026
@solnic solnic force-pushed the refa/rework-devcontainer branch from e22e805 to 41504fa Compare May 11, 2026 09:04
@solnic solnic force-pushed the refa/rework-devcontainer branch from 048daa5 to d6cd2e6 Compare May 11, 2026 09:55
@solnic solnic force-pushed the refa/rework-devcontainer branch from 9d2348d to b6e5dbd Compare May 11, 2026 11:09
@solnic solnic marked this pull request as ready for review May 11, 2026 13:21
cursor[bot]

This comment was marked as resolved.

@dingsdax dingsdax self-requested a review May 11, 2026 13:48
Copy link
Copy Markdown
Contributor

@dingsdax dingsdax left a comment

Choose a reason for hiding this comment

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

lgtm

Comment thread .devcontainer/run
Comment on lines +43 to +47
if "$MISE_BIN" list ruby 2>/dev/null | grep -qF "${RUBY_VERSION}"; then
echo "✅ ruby@${RUBY_VERSION} already installed, skipping download."
else
echo "📦 Installing ruby@${RUBY_VERSION} (precompiled)..."
"$MISE_BIN" install "ruby@${RUBY_VERSION}"
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Bug: The check for an existing Ruby installation using mise list ruby | grep -qF "latest" always fails in local dev, causing mise install to run on every container start.
Severity: MEDIUM

Suggested Fix

Resolve the "latest" alias to a concrete version number before checking if it's installed. For example, run mise resolve ruby@latest to get the version string, store it in a variable, and then use that variable for both the grep check and the mise install command.

Prompt for AI Agent
Review the code at the location below. A potential bug has been identified by an AI
agent. Verify if this is a real issue. If it is, propose a fix; if not, explain why it's
not valid.

Location: .devcontainer/run#L43-L47

Potential issue: In local development environments where `RUBY_VERSION` is unset, it
defaults to `"latest"`. The script checks for an existing installation using `mise list
ruby | grep -qF "latest"`. This check always fails because `mise list` outputs the
resolved concrete version number (e.g., `4.0.3`), not the alias `"latest"`.
Consequently, `mise install ruby@latest` is executed on every container start, requiring
a network connection. Because the script uses `set -euo pipefail`, any network
interruption will cause the container to fail to start, even if the correct Ruby version
is already installed.

Did we get this right? 👍 / 👎 to inform future reviews.

Copy link
Copy Markdown

@cursor cursor Bot left a comment

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 9c27785. Configure here.

Comment thread .devcontainer/Dockerfile
# Install headless Chromium via Playwright (includes all system dependencies).
# Symlink the binary into ~/.local/bin which is already on PATH.
RUN /home/sentry/.local/share/mise/shims/npx playwright install chromium --with-deps
RUN bash -c 'ln -sf /home/sentry/.cache/ms-playwright/chromium-*/chrome-linux/chrome /home/sentry/.local/bin/chromium'
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Chromium symlink broken on x86_64 Linux builds

High Severity

The symlink hardcodes chrome-linux/chrome, but Playwright ≥1.57 on Linux x64 installs Chromium under chrome-linux64/chrome. Since CI uses ubuntu-latest (x86_64) and npx playwright install chromium fetches the latest version, the glob resolves to a non-existent subdirectory, creating a broken symlink. File.exist? in spec_helper.rb then returns false, so options.binary is never set, and Selenium cannot locate the Chrome binary — breaking e2e tests on x64 runners. The path chrome-linux/chrome only works on ARM64, which appears to be where the author tested (PR description shows aarch64-linux).

Additional Locations (1)
Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 9c27785. Configure here.

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.

2 participants