Skip to content

[CI] Enable devcontainer jobs#82

Open
hcho3 wants to merge 2 commits intorapidsai:mainfrom
hcho3:enable-devcontainer
Open

[CI] Enable devcontainer jobs#82
hcho3 wants to merge 2 commits intorapidsai:mainfrom
hcho3:enable-devcontainer

Conversation

@hcho3
Copy link
Contributor

@hcho3 hcho3 commented Mar 12, 2026

Co-Authored-By: Simon Adorf <sadorf@nvidia.com>
@hcho3 hcho3 requested review from a team as code owners March 12, 2026 00:35
@hcho3 hcho3 requested a review from bdice March 12, 2026 00:35
@hcho3 hcho3 added non-breaking Introduces a non-breaking change ci improvement Improves an existing functionality labels Mar 12, 2026
@hcho3 hcho3 mentioned this pull request Mar 12, 2026
25 tasks
@coderabbitai
Copy link

coderabbitai bot commented Mar 12, 2026

📝 Walkthrough

Summary by CodeRabbit

  • Chores
    • Added comprehensive devcontainer configurations for multiple CUDA and Python package-manager combinations, with workspace mounts and development tooling.
    • Updated CI workflow to run devcontainer builds across additional architectures and CUDA targets, enabling cached/parallelized builds.
  • Documentation
    • Added a README describing devcontainer usage, prerequisites, mounts, and VS Code workflow for onboarding.

Walkthrough

Adds a devcontainer Dockerfile and multiple devcontainer configurations (pip and conda for CUDA 12.9 and 13.1), documentation for the devcontainer, and enables a devcontainer job in the PR CI workflow targeting amd64/arm64 with CUDA 13.1 and sccache settings.

Changes

Cohort / File(s) Summary
Devcontainer Dockerfile & docs
.devcontainer/Dockerfile, .devcontainer/README.md
Adds a multi-stage Dockerfile with pip/conda stages, ARGs for BASE and PYTHON_PACKAGE_MANAGER, RAPIDS/CUDA/sccache and Python environment defaults, build/runtime flags and timeouts. Adds README describing container purpose, prerequisites, bind mounts, and VSCode reopen/rebuild workflow.
CUDA 12.9 devcontainer configurations
.devcontainer/cuda12.9-conda/devcontainer.json, .devcontainer/cuda12.9-pip/devcontainer.json
Adds two devcontainer configs for CUDA 12.9: one conda-based and one pip-based. Each defines build context, Dockerfile, build args (CUDA, PYTHON_PACKAGE_MANAGER, BASE), runArgs, optional GPU host, RAPIDS/CUDA features, initialize/postAttach commands, workspace mounts for caches/configs/conda, and VSCode extensions.
CUDA 13.1 devcontainer configurations
.devcontainer/cuda13.1-conda/devcontainer.json, .devcontainer/cuda13.1-pip/devcontainer.json
Adds two devcontainer configs for CUDA 13.1: conda and pip variants. Each sets build context, Dockerfile, build args, runArgs, optional GPU host, RAPIDS/CUDA features and install order, initialize/postAttach commands, workspace mounts for persistence, and VSCode extensions.
CI workflow
.github/workflows/pr.yaml
Uncomments/enables the devcontainer job in the pr-builder pipeline, making it a dependency of pr-builder (needs: telemetry-setup). Configures the job to run on amd64 and arm64 with CUDA 13.1, sets sccache and verbose build env vars, and uses a build_command that runs builds with sccache and BUILD_TESTS=ON.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title '[CI] Enable devcontainer jobs' accurately summarizes the main change: enabling devcontainer CI jobs by uncommenting the devcontainer job in the pr.yaml workflow and adding supporting devcontainer configuration files.
Description check ✅ Passed The description 'Follow-up to rapidsai/devcontainers#672' is related to the changeset as it provides context for the devcontainer additions and workflow enablement.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

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

Copy link

@coderabbitai coderabbitai bot left a comment

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 the current code and only fix it if needed.

Inline comments:
In @.devcontainer/README.md:
- Line 33: The image tag lacks an alt attribute which breaks accessibility
checks (MD045); edit the <img> element in the README line containing
src="https://user-images.githubusercontent.com/178183/221771999-97ab29d5-e718-4e5f-b32f-2cdd51bba25c.png"
and add a concise, descriptive alt text (for example: alt="VS Code Reopen in
Container button") so the image is accessible to screen readers.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 3bcd8d88-9886-4cc0-a7b8-d7e892488b52

📥 Commits

Reviewing files that changed from the base of the PR and between 5a29d01 and 9f288f6.

📒 Files selected for processing (3)
  • .devcontainer/Dockerfile
  • .devcontainer/README.md
  • .github/workflows/pr.yaml


## Launch a Dev Container

To launch a devcontainer from VSCode, open the nvForest repo and select the "Reopen in Container" button in the bottom right:<br/><img src="https://user-images.githubusercontent.com/178183/221771999-97ab29d5-e718-4e5f-b32f-2cdd51bba25c.png"/>
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Add alt text to the image for accessibility.

The image tag is missing alternative text, which is required for accessibility compliance. Static analysis flagged this as MD045 (no-alt-text).

📝 Proposed fix
-To launch a devcontainer from VSCode, open the nvForest repo and select the "Reopen in Container" button in the bottom right:<br/><img src="https://user-images.githubusercontent.com/178183/221771999-97ab29d5-e718-4e5f-b32f-2cdd51bba25c.png"/>
+To launch a devcontainer from VSCode, open the nvForest repo and select the "Reopen in Container" button in the bottom right:<br/><img src="https://user-images.githubusercontent.com/178183/221771999-97ab29d5-e718-4e5f-b32f-2cdd51bba25c.png" alt="VSCode Reopen in Container notification"/>
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
To launch a devcontainer from VSCode, open the nvForest repo and select the "Reopen in Container" button in the bottom right:<br/><img src="https://user-images.githubusercontent.com/178183/221771999-97ab29d5-e718-4e5f-b32f-2cdd51bba25c.png"/>
To launch a devcontainer from VSCode, open the nvForest repo and select the "Reopen in Container" button in the bottom right:<br/><img src="https://user-images.githubusercontent.com/178183/221771999-97ab29d5-e718-4e5f-b32f-2cdd51bba25c.png" alt="VSCode Reopen in Container notification"/>
🧰 Tools
🪛 markdownlint-cli2 (0.21.0)

[warning] 33-33: Images should have alternate text (alt text)

(MD045, no-alt-text)

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.devcontainer/README.md at line 33, The image tag lacks an alt attribute
which breaks accessibility checks (MD045); edit the <img> element in the README
line containing
src="https://user-images.githubusercontent.com/178183/221771999-97ab29d5-e718-4e5f-b32f-2cdd51bba25c.png"
and add a concise, descriptive alt text (for example: alt="VS Code Reopen in
Container button") so the image is accessible to screen readers.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 3

🧹 Nitpick comments (1)
.devcontainer/cuda12.9-conda/devcontainer.json (1)

25-25: Avoid a host-side Bash dependency in initializeCommand.

initializeCommand runs on the host, so hard-coding /bin/bash makes this devcontainer host-OS dependent. If Windows hosts are in scope, container creation will fail before Docker even starts. A host-agnostic bootstrap mechanism would be safer here.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.devcontainer/cuda12.9-conda/devcontainer.json at line 25, The
initializeCommand currently hard-codes "/bin/bash" which makes host-side
container initialization fail on non-Unix hosts; remove the host-side bash
dependency by either moving the directory-creation step into a container-side
hook (e.g., postCreateCommand or a Dockerfile RUN) or replace the host shell
invocation with a cross-platform bootstrap script (e.g., a small Node.js script)
and call that from initializeCommand; update the initializeCommand entry that
references initializeCommand to either call the container-side command or the
cross-platform script so directory creation no longer depends on /bin/bash.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In @.devcontainer/cuda12.9-conda/devcontainer.json:
- Around line 27-28: The workspaceFolder is set to /home/coder but the repo is
mounted at /home/coder/nvforest (see workspaceMount), so update the devcontainer
JSONs to point workspaceFolder to the mounted checkout path
(/home/coder/nvforest) instead of /home/coder; locate the "workspaceFolder" key
in each devcontainer config (e.g., the file containing workspaceMount) and
change its value to match the mount target so terminals, tasks, and tooling
start inside the repository.

In @.devcontainer/cuda12.9-pip/devcontainer.json:
- Line 33: The initializeCommand uses an unquoted ${localWorkspaceFolder} inside
the mkdir argument which breaks when the path contains spaces; update the
initializeCommand entry so the shell argument encloses the entire path expansion
in quotes (i.e., quote ${localWorkspaceFolder} and/or
${localWorkspaceFolderBasename} inside the command string) so mkdir receives a
single path argument — target the "initializeCommand" JSON value in the
devcontainer config and wrap the path expansions in double quotes.
- Around line 35-36: The workspaceFolder is set to "/home/coder" but the repo is
mounted at "/home/coder/nvforest", so change the "workspaceFolder" value to
point to the mounted checkout ("/home/coder/nvforest") so the container root,
terminals, tasks and CI use the repository directory; update the
"workspaceFolder" field to match the "workspaceMount" target path (refer to
workspaceFolder and workspaceMount in the file).

---

Nitpick comments:
In @.devcontainer/cuda12.9-conda/devcontainer.json:
- Line 25: The initializeCommand currently hard-codes "/bin/bash" which makes
host-side container initialization fail on non-Unix hosts; remove the host-side
bash dependency by either moving the directory-creation step into a
container-side hook (e.g., postCreateCommand or a Dockerfile RUN) or replace the
host shell invocation with a cross-platform bootstrap script (e.g., a small
Node.js script) and call that from initializeCommand; update the
initializeCommand entry that references initializeCommand to either call the
container-side command or the cross-platform script so directory creation no
longer depends on /bin/bash.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 649a0c70-d8dc-4442-95e1-8a14e4015320

📥 Commits

Reviewing files that changed from the base of the PR and between 9f288f6 and dfd88d5.

📒 Files selected for processing (4)
  • .devcontainer/cuda12.9-conda/devcontainer.json
  • .devcontainer/cuda12.9-pip/devcontainer.json
  • .devcontainer/cuda13.1-conda/devcontainer.json
  • .devcontainer/cuda13.1-pip/devcontainer.json

Comment on lines +27 to +28
"workspaceFolder": "/home/coder",
"workspaceMount": "source=${localWorkspaceFolder},target=/home/coder/nvforest,type=bind,consistency=consistent",
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

# First, let's look at the full devcontainer.json file
cat -n .devcontainer/cuda12.9-conda/devcontainer.json

Repository: rapidsai/nvforest

Length of output: 2320


🏁 Script executed:

# Check if there are other devcontainer configurations for comparison
find .devcontainer -name "devcontainer.json" -type f

Repository: rapidsai/nvforest

Length of output: 244


🏁 Script executed:

# Let's also check the directory structure to understand the context
ls -la .devcontainer/

Repository: rapidsai/nvforest

Length of output: 550


🏁 Script executed:

# Check the other devcontainer configurations for the same issue
for file in .devcontainer/cuda12.9-pip/devcontainer.json .devcontainer/cuda13.1-conda/devcontainer.json .devcontainer/cuda13.1-pip/devcontainer.json; do
  echo "=== $file ==="
  grep -A 1 "workspaceFolder\|workspaceMount" "$file"
done

Repository: rapidsai/nvforest

Length of output: 716


Point workspaceFolder at the mounted checkout.

The repo is mounted at /home/coder/nvforest, but the workspace opens at /home/coder. That means terminals, tasks, and repo-relative tooling start outside the checkout by default. This issue affects all four devcontainer configurations.

Patch
-  "workspaceFolder": "/home/coder",
+  "workspaceFolder": "/home/coder/nvforest",
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
"workspaceFolder": "/home/coder",
"workspaceMount": "source=${localWorkspaceFolder},target=/home/coder/nvforest,type=bind,consistency=consistent",
"workspaceFolder": "/home/coder/nvforest",
"workspaceMount": "source=${localWorkspaceFolder},target=/home/coder/nvforest,type=bind,consistency=consistent",
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.devcontainer/cuda12.9-conda/devcontainer.json around lines 27 - 28, The
workspaceFolder is set to /home/coder but the repo is mounted at
/home/coder/nvforest (see workspaceMount), so update the devcontainer JSONs to
point workspaceFolder to the mounted checkout path (/home/coder/nvforest)
instead of /home/coder; locate the "workspaceFolder" key in each devcontainer
config (e.g., the file containing workspaceMount) and change its value to match
the mount target so terminals, tasks, and tooling start inside the repository.

"ghcr.io/rapidsai/devcontainers/features/cuda",
"ghcr.io/rapidsai/devcontainers/features/rapids-build-utils"
],
"initializeCommand": ["/bin/bash", "-c", "mkdir -m 0755 -p ${localWorkspaceFolder}/../.{aws,cache,config/pip,local/share/${localWorkspaceFolderBasename}-cuda12.9-venvs}"],
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

workspace='/tmp/My Repo/nvforest'
bash -lc "set -- ${workspace}/../.{aws,cache,config/pip,local/share/nvforest-cuda12.9-venvs}; printf '<%s>\n' \"\$@\""

Repository: rapidsai/nvforest

Length of output: 323


Quote ${localWorkspaceFolder} in initializeCommand.

The unquoted path on Line 33 is split by the shell at whitespace. A checkout like ~/Work Trees/nvforest will turn into multiple mkdir arguments and break initialization.

🐛 Proposed fix
-  "initializeCommand": ["/bin/bash", "-c", "mkdir -m 0755 -p ${localWorkspaceFolder}/../.{aws,cache,config/pip,local/share/${localWorkspaceFolderBasename}-cuda12.9-venvs}"],
+  "initializeCommand": ["/bin/bash", "-c", "workspace_parent=$(dirname \"${localWorkspaceFolder}\") && mkdir -m 0755 -p \"$workspace_parent/.aws\" \"$workspace_parent/.cache\" \"$workspace_parent/.config/pip\" \"$workspace_parent/.local/share/${localWorkspaceFolderBasename}-cuda12.9-venvs\""],
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
"initializeCommand": ["/bin/bash", "-c", "mkdir -m 0755 -p ${localWorkspaceFolder}/../.{aws,cache,config/pip,local/share/${localWorkspaceFolderBasename}-cuda12.9-venvs}"],
"initializeCommand": ["/bin/bash", "-c", "workspace_parent=$(dirname \"${localWorkspaceFolder}\") && mkdir -m 0755 -p \"$workspace_parent/.aws\" \"$workspace_parent/.cache\" \"$workspace_parent/.config/pip\" \"$workspace_parent/.local/share/${localWorkspaceFolderBasename}-cuda12.9-venvs\""],
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.devcontainer/cuda12.9-pip/devcontainer.json at line 33, The
initializeCommand uses an unquoted ${localWorkspaceFolder} inside the mkdir
argument which breaks when the path contains spaces; update the
initializeCommand entry so the shell argument encloses the entire path expansion
in quotes (i.e., quote ${localWorkspaceFolder} and/or
${localWorkspaceFolderBasename} inside the command string) so mkdir receives a
single path argument — target the "initializeCommand" JSON value in the
devcontainer config and wrap the path expansions in double quotes.

Comment on lines +35 to +36
"workspaceFolder": "/home/coder",
"workspaceMount": "source=${localWorkspaceFolder},target=/home/coder/nvforest,type=bind,consistency=consistent",
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

python - <<'PY'
import json
from pathlib import Path

path = Path(".devcontainer/cuda12.9-pip/devcontainer.json")
data = json.loads(path.read_text())
target = next(
    part.split("=", 1)[1]
    for part in data["workspaceMount"].split(",")
    if part.startswith("target=")
)

print("workspaceFolder:", data["workspaceFolder"])
print("workspaceMount target:", target)
print("matches:", data["workspaceFolder"] == target)
PY

Repository: rapidsai/nvforest

Length of output: 148


🏁 Script executed:

cat -n .devcontainer/cuda12.9-pip/devcontainer.json

Repository: rapidsai/nvforest

Length of output: 2545


Point workspaceFolder at the mounted checkout.

Line 35 opens /home/coder, but Line 36 mounts the repo at /home/coder/nvforest. This leaves the devcontainer rooted outside the checkout, so terminals, tasks, and CI steps that use the workspace root will operate in the wrong directory.

Proposed fix
-  "workspaceFolder": "/home/coder",
+  "workspaceFolder": "/home/coder/nvforest",
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
"workspaceFolder": "/home/coder",
"workspaceMount": "source=${localWorkspaceFolder},target=/home/coder/nvforest,type=bind,consistency=consistent",
"workspaceFolder": "/home/coder/nvforest",
"workspaceMount": "source=${localWorkspaceFolder},target=/home/coder/nvforest,type=bind,consistency=consistent",
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.devcontainer/cuda12.9-pip/devcontainer.json around lines 35 - 36, The
workspaceFolder is set to "/home/coder" but the repo is mounted at
"/home/coder/nvforest", so change the "workspaceFolder" value to point to the
mounted checkout ("/home/coder/nvforest") so the container root, terminals,
tasks and CI use the repository directory; update the "workspaceFolder" field to
match the "workspaceMount" target path (refer to workspaceFolder and
workspaceMount in the file).

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

Labels

ci improvement Improves an existing functionality non-breaking Introduces a non-breaking change

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant