From f3228aa4dda566a559cb6f9f027a94cafe2bd540 Mon Sep 17 00:00:00 2001 From: Gergo Magyar Date: Fri, 29 May 2026 09:50:16 +0000 Subject: [PATCH] feat(devcontainer): add Bun 1.3.14, pinned via build arg MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Installed by the official bun.sh/install script with the release tag passed as the first positional arg, so the version is pinned even though the install path itself is an unverified remote script (the one such exception in the image — Cursor and the base image stay sha256/digest- pinned). BUN_INSTALL is set in ENV so the binary lands at a known path and the installer's rc-file edits don't matter. unzip is added to apt since the Bun installer extracts a .zip. Co-Authored-By: Claude Opus 4.7 (1M context) --- .devcontainer/Dockerfile | 33 +++++++++++++++++++++++++++++---- .devcontainer/README.md | 2 +- .devcontainer/devcontainer.json | 7 +++++++ 3 files changed, 37 insertions(+), 5 deletions(-) diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile index fec432e30..620a5483c 100644 --- a/.devcontainer/Dockerfile +++ b/.devcontainer/Dockerfile @@ -36,6 +36,13 @@ ARG CODEX_VERSION ARG CURSOR_VERSION ARG CURSOR_SHA256_X64 ARG CURSOR_SHA256_ARM64 +# Bun is installed via the official remote script (bun.sh/install), pinned by +# version. UNLIKE Cursor and the npm packages, this install path runs an +# UNVERIFIED remote script — there is no tarball-hash check. Chosen explicitly +# at request time over the pin-by-sha256 alternative for install-script +# simplicity. To harden later, switch to a pinned tarball + per-arch sha256 in +# the Cursor style (release artifacts at github.com/oven-sh/bun/releases). +ARG BUN_VERSION ARG TZ=UTC ARG USERNAME=node @@ -46,6 +53,8 @@ ARG USERNAME=node ENV CLAUDE_CODE_VERSION=${CLAUDE_CODE_VERSION} \ CODEX_VERSION=${CODEX_VERSION} \ CURSOR_VERSION=${CURSOR_VERSION} \ + BUN_VERSION=${BUN_VERSION} \ + BUN_INSTALL=/home/${USERNAME}/.bun \ TZ=${TZ} \ DEVCONTAINER=true \ NODE_OPTIONS=--max-old-space-size=4096 \ @@ -58,7 +67,7 @@ ENV CLAUDE_CODE_VERSION=${CLAUDE_CODE_VERSION} \ # gitnexus/Dockerfile.test images. RUN apt-get update \ && apt-get install -y --no-install-recommends \ - python3 make g++ git curl ca-certificates bash \ + python3 make g++ git curl ca-certificates bash unzip \ && rm -rf /var/lib/apt/lists/* # Create and chown the named-volume mount points (~/.npm, ~/.local, @@ -123,6 +132,22 @@ RUN set -eux; \ ln -sf "$dir/cursor-agent" "/home/${USERNAME}/.local/bin/cursor-agent"; \ rm -f /tmp/cursor.tgz -# Put ~/.local/bin on PATH for interactive shells and lifecycle scripts. That is -# where Cursor's installer drops the `agent` and `cursor-agent` symlinks. -ENV PATH=/home/${USERNAME}/.local/bin:${PATH} +# Install Bun via the official remote installer, pinned by version. The first +# positional arg to `bash` is the release tag (`bun-vX.Y.Z`), so a specific +# version is fetched even though the install script itself is downloaded fresh +# on every build. NOTE: this is the ONE remote script we run unverified in +# this image — Cursor and the base image are pinned by sha256/digest. Hardening +# path: switch to a pinned tarball + per-arch sha256 in the Cursor style +# (artifacts at github.com/oven-sh/bun/releases). `BUN_INSTALL` is set in ENV +# above so the binary lands at a known path regardless of any rc-file edits +# the installer makes (which we ignore — we own the shell rc files). +RUN set -eux; \ + curl -fsSL --retry 3 --max-time 120 https://bun.sh/install \ + | bash -s "bun-v${BUN_VERSION}"; \ + test -x "${BUN_INSTALL}/bin/bun" + +# Put ~/.local/bin and Bun's bin dir on PATH for interactive shells and +# lifecycle scripts. ~/.local/bin is where Cursor's installer drops the `agent` +# and `cursor-agent` symlinks; ${BUN_INSTALL}/bin is where the Bun installer +# drops `bun` / `bunx`. +ENV PATH=/home/${USERNAME}/.local/bin:${BUN_INSTALL}/bin:${PATH} diff --git a/.devcontainer/README.md b/.devcontainer/README.md index 506e736da..eef88bc9c 100644 --- a/.devcontainer/README.md +++ b/.devcontainer/README.md @@ -1,6 +1,6 @@ # GitNexus Devcontainer -A cross-platform Dev Container that pre-installs Claude Code, OpenAI Codex CLI, and Cursor CLI alongside the GitNexus native build chain. Supported hosts: **macOS, Linux, Windows 11 (native), and Windows 11 via WSL2.** Windows-native needs a **one-time `HOME` env var setup** — handled automatically by the `initializeCommand` on first run (see [Windows 11 setup](#windows-11-setup)). +A cross-platform Dev Container that pre-installs Claude Code, OpenAI Codex CLI, Cursor CLI, and Bun alongside the GitNexus native build chain. Supported hosts: **macOS, Linux, Windows 11 (native), and Windows 11 via WSL2.** Windows-native needs a **one-time `HOME` env var setup** — handled automatically by the `initializeCommand` on first run (see [Windows 11 setup](#windows-11-setup)). > ### ⚠️ Read this before using it on a work machine > diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index 04372eb62..75069d97c 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -24,6 +24,13 @@ "CURSOR_VERSION": "2026.05.28-a70ca7c", "CURSOR_SHA256_X64": "7f8b6a09393e0b84b288cc6952b292fc98d15775f644cc01b0b9aa4f04b268df", "CURSOR_SHA256_ARM64": "05a0ab361e038729aba25fe7f407531b3e8432912e499d0bffdf1dda0e7833e9", + // Bun: pinned by version. Installed by the official bun.sh/install + // script, which accepts the release tag as its first positional arg + // (`bash -s bun-vX.Y.Z`). UNLIKE Cursor, the install path runs an + // unverified remote script — chosen at request time for simplicity. + // To bump: pick a tag from github.com/oven-sh/bun/releases and update + // this value. + "BUN_VERSION": "1.3.14", "TZ": "${localEnv:TZ:UTC}" } },