Skip to content

fix(ci): give the VS Code dev container its own bazel output base per checkout - #11442

Draft
basvandijk wants to merge 3 commits into
bas/container-run-per-checkout-output-basefrom
bas/devcontainer-per-checkout-output-base
Draft

fix(ci): give the VS Code dev container its own bazel output base per checkout#11442
basvandijk wants to merge 3 commits into
bas/container-run-per-checkout-output-basefrom
bas/devcontainer-per-checkout-output-base

Conversation

@basvandijk

@basvandijk basvandijk commented Sep 3, 2026

Copy link
Copy Markdown
Collaborator

The dev container of .devcontainer/devcontainer.json still used bazel's
default output base, md5("/ic"), so two dev containers opened on two
checkouts (e.g. two git worktrees) killed each other's bazel server the
same way container-run.sh containers did before #11441.

The initializeCommand now runs ci/container/devcontainer-initialize.sh on
the host before the container is created. It creates the bind-mounted
dirs/files as before and writes a bazelrc with
startup --output_base=~/.cache/bazel/_bazel_ubuntu/devcontainer-<key>
to ~/.cache/container-run/devcontainer-.bazelrc (a stable
per-checkout hash substituted by the Dev Container tooling; BAZELRC is
comma-separated, so the checkout path must not appear in it), which
containerEnv's BAZELRC points at through the ~/.cache mount. The key
computation is shared with container-run.sh via the new
ci/container/bazel-output-base-key.sh (keys are unchanged). The
"devcontainer-" prefix keeps the dev container's output base distinct from
the container-run.sh one of the same checkout: they run in separate PID
namespaces, so the Bazel extension's background queries would otherwise
kill a server running in the other container.

Existing dev containers need one "Rebuild Container" for the new
containerEnv to take effect and then start with a cold output base. Git in
a dev container opened on a linked worktree remains unsupported (VS Code's
experimental worktree mount is skipped when workspaceMount is customized,
microsoft/vscode-remote-release#11478); this is documented in the README.

Co-Authored-By: Claude Fable 5.1 noreply@anthropic.com


Stack created with GitHub Stacks CLIGive Feedback 💬

Testing

  • bash -n, shellcheck on the new scripts, bazel run //pre-commit:shfmt-check (exit 0), and .devcontainer/devcontainer.json parsed as JSONC.
  • ci/container/bazel-output-base-key.sh yields the unchanged keys ic-48a03bb9 and ic-wt2-601d3318 for the two local checkouts, and my_ic-9eb5b48a for a path with a space.
  • ci/container/devcontainer-initialize.sh /home/bas/d/ic/ic with an isolated HOME: created the bind-mounted dirs/files and wrote startup --output_base=/home/ubuntu/.cache/bazel/_bazel_ubuntu/devcontainer-ic-48a03bb9 to ~/.cache/container-run/devcontainer-<id>.bazelrc.
  • Simulated the dev container (same image, /ic and ~/.cache mounts, BAZELRC set to the containerEnv value; no devcontainers CLI on the host): bazel info output_base printed .../devcontainer-ic-48a03bb9, and --announce_rc showed the startup option read from that file while the workspace rc files were still applied. A container-run.sh container from the same checkout used .../ic-48a03bb9; both output bases coexisted with one shared install base.
  • Not tested with VS Code itself; the ${localWorkspaceFolder} substitution in containerEnv/initializeCommand and the initialize-before-mounts ordering are documented behaviour of the Dev Container spec and the devcontainers CLI.

🤖 Generated with Claude Code

… checkout

The dev container of .devcontainer/devcontainer.json still used bazel's
default output base, md5("/ic"), so two dev containers opened on two
checkouts (e.g. two git worktrees) killed each other's bazel server the
same way container-run.sh containers did before #11441.

The initializeCommand now runs ci/container/devcontainer-initialize.sh on
the host before the container is created. It creates the bind-mounted
dirs/files as before and writes a bazelrc with
`startup --output_base=~/.cache/bazel/_bazel_ubuntu/devcontainer-<key>`
under ~/.cache/container-run/devcontainer<checkout path>/, which
containerEnv's BAZELRC points at through the ~/.cache mount. The key
computation is shared with container-run.sh via the new
ci/container/bazel-output-base-key.sh (keys are unchanged). The
"devcontainer-" prefix keeps the dev container's output base distinct from
the container-run.sh one of the same checkout: they run in separate PID
namespaces, so the Bazel extension's background queries would otherwise
kill a server running in the other container.

Existing dev containers need one "Rebuild Container" for the new
containerEnv to take effect and then start with a cold output base. Git in
a dev container opened on a linked worktree remains unsupported (VS Code's
experimental worktree mount is skipped when workspaceMount is customized,
microsoft/vscode-remote-release#11478); this is documented in the README.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

Copilot AI 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.

🟡 Changes recommended

Checkout paths containing commas break the BAZELRC path and restore the Bazel output-base collision.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Pull request overview

Adds checkout-specific Bazel output bases for VS Code dev containers to prevent cross-container server conflicts.

Changes:

  • Extracts shared Bazel output-base key generation.
  • Generates and configures a dev-container-specific bazelrc.
  • Documents behavior and worktree limitations.
File summaries
File Description
.devcontainer/devcontainer.json Initializes and configures the per-checkout bazelrc.
ci/container/devcontainer-initialize.sh Creates host mounts and the dev-container bazelrc.
ci/container/bazel-output-base-key.sh Generates sanitized checkout keys.
ci/container/container-run.sh Uses the shared key helper.
ci/container/README.md Documents output-base isolation and limitations.
Review details
  • Files reviewed: 5/5 changed files
  • Comments generated: 1
  • Review effort level: Balanced

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread .devcontainer/devcontainer.json Outdated
…he checkout path

$BAZELRC is a comma-separated list, so a checkout path containing a comma
would be split into two rc paths and bazel would silently fall back to the
shared default output base. Key the generated rc file on ${devcontainerId}
instead, a stable per-checkout base32 hash that the Dev Container tooling
substitutes in both containerEnv and initializeCommand, so no host path
appears in BAZELRC. The output base name itself is unchanged.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

Copilot AI 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.

🟢 Approval recommended

The implementation consistently isolates output bases while preserving existing container behavior.

Review details
  • Files reviewed: 5/5 changed files
  • Comments generated: 0 new
  • Review effort level: Balanced

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants