Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .devcontainer/prepare-local-features.sh
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@ repo_root="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
local_features_dir="${repo_root}/.devcontainer/local-features"

mkdir -p "${local_features_dir}"
rm -rf "${local_features_dir}/linux-x11-forwarding" "${local_features_dir}/x11" "${local_features_dir}/wayland"
rm -rf "${local_features_dir}/linux-x11-forwarding" "${local_features_dir}/ros2" "${local_features_dir}/x11" "${local_features_dir}/wayland"
cp -R "${repo_root}/features/src/linux-x11-forwarding" "${local_features_dir}/linux-x11-forwarding"
cp -R "${repo_root}/features/src/ros2" "${local_features_dir}/ros2"

echo "Prepared local smoke-test features in ${local_features_dir}"
8 changes: 8 additions & 0 deletions .devcontainer/ros2-feature-smoke/devcontainer.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"name": "ros2-feature-smoke",
"image": "mcr.microsoft.com/devcontainers/base:ubuntu-24.04",
"features": {
"../local-features/ros2": {}
},
"postCreateCommand": "bash -lc 'ros2 pkg prefix rviz2 >/dev/null && command -v colcon >/dev/null && command -v rosdep >/dev/null && command -v vcs >/dev/null'"
}
114 changes: 90 additions & 24 deletions .github/workflows/test-pr.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -18,18 +18,80 @@ jobs:
with:
template: "gz"

feature-tests:
x11-feature-tests:
runs-on: ubuntu-latest
env:
DISPLAY: ":99"
XDG_RUNTIME_DIR: /tmp/devcontainers-x11-runtime
XAUTHORITY: /tmp/devcontainers-xauthority.test
PULSE_SERVER: unix:/tmp/devcontainers-x11-runtime/pulse-native
steps:
- uses: actions/checkout@v6

- name: Install devcontainer CLI
run: npm install --global @devcontainers/cli@0.88.0

- name: Validate feature metadata
run: bash features/test/test_all.sh
- name: Prepare X11 test environment
run: bash features/test/linux-x11-forwarding/prepare-host.sh

- name: Validate Feature publishing metadata
- name: Test X11 Feature
run: |
devcontainer features test \
--features linux-x11-forwarding \
--project-folder features

ros2-default-test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6

- name: Install devcontainer CLI
run: npm install --global @devcontainers/cli@0.88.0

- name: Validate ROS 2 configuration
run: python3 features/test/ros2/validate_config.py

- name: Test ROS 2 default
run: |
devcontainer features test \
--base-image mcr.microsoft.com/devcontainers/base:ubuntu-24.04 \
--features ros2 \
--project-folder features \
--skip-scenarios

ros2-scenario-tests:
name: "ROS 2 ${{ matrix.scenario }}"
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
scenario:
- humble
- kilted
- lyrical
steps:
- uses: actions/checkout@v6

- name: Install devcontainer CLI
run: npm install --global @devcontainers/cli@0.88.0

- name: Test ROS 2 ${{ matrix.scenario }}
run: |
devcontainer features test \
--features ros2 \
--project-folder features \
--skip-autogenerated \
--filter "${{ matrix.scenario }}"

feature-package:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6

- name: Install devcontainer CLI
run: npm install --global @devcontainers/cli@0.88.0

- name: Package Features
run: |
devcontainer features package features/src \
--output-folder "${RUNNER_TEMP}/features" \
Expand Down Expand Up @@ -64,36 +126,40 @@ jobs:
complete:
needs:
- docs-check
- feature-tests
- feature-package
- x11-feature-tests
- ros2-default-test
- ros2-scenario-tests
- smoke-test
if: always()
runs-on: ubuntu-latest
steps:
- name: Verify required jobs succeeded
env:
SMOKE_TEST_RESULT: ${{ needs.smoke-test.result }}
FEATURE_TESTS_RESULT: ${{ needs.feature-tests.result }}
X11_FEATURE_TESTS_RESULT: ${{ needs.x11-feature-tests.result }}
ROS2_DEFAULT_TEST_RESULT: ${{ needs.ros2-default-test.result }}
ROS2_SCENARIO_TESTS_RESULT: ${{ needs.ros2-scenario-tests.result }}
FEATURE_PACKAGE_RESULT: ${{ needs.feature-package.result }}
DOCS_CHECK_RESULT: ${{ needs.docs-check.result }}
run: |
set -euo pipefail

echo "smoke_test: ${SMOKE_TEST_RESULT}"
echo "feature_tests: ${FEATURE_TESTS_RESULT}"
echo "docs_check: ${DOCS_CHECK_RESULT}"

if [[ "${SMOKE_TEST_RESULT}" != "success" ]]; then
echo "Required job 'smoke_test' did not succeed."
exit 1
fi

if [[ "${FEATURE_TESTS_RESULT}" != "success" ]]; then
echo "Required job 'feature_tests' did not succeed."
exit 1
fi

if [[ "${DOCS_CHECK_RESULT}" != "success" ]]; then
echo "Required job 'docs-check' did not succeed."
exit 1
fi
check_result() {
local job_name="$1"
local result="$2"
echo "${job_name}: ${result}"
if [[ "${result}" != "success" ]]; then
echo "Required job '${job_name}' did not succeed."
exit 1
fi
}

check_result "smoke-test" "${SMOKE_TEST_RESULT}"
check_result "x11-feature-tests" "${X11_FEATURE_TESTS_RESULT}"
check_result "ros2-default-test" "${ROS2_DEFAULT_TEST_RESULT}"
check_result "ros2-scenario-tests" "${ROS2_SCENARIO_TESTS_RESULT}"
check_result "feature-package" "${FEATURE_PACKAGE_RESULT}"
check_result "docs-check" "${DOCS_CHECK_RESULT}"

echo "All required jobs completed successfully."
148 changes: 148 additions & 0 deletions .vscode/tasks.json
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,154 @@
],
"problemMatcher": []
},
{
"label": "Prepare Local Features",
"type": "process",
"command": "bash",
"args": [
".devcontainer/prepare-local-features.sh"
],
"options": {
"cwd": "${workspaceFolder}"
},
"problemMatcher": []
},
{
"label": "Local Smoke Test ROS 2 Feature",
"dependsOrder": "sequence",
"dependsOn": [
"Prepare Local Features"
],
"type": "process",
"command": "devcontainer",
"args": [
"up",
"--workspace-folder",
"${workspaceFolder}",
"--config",
"${workspaceFolder}/.devcontainer/ros2-feature-smoke/devcontainer.json"
],
"options": {
"cwd": "${workspaceFolder}"
},
"problemMatcher": []
},
{
"label": "Validate ROS 2 Configuration",
"type": "process",
"command": "python3",
"args": [
"features/test/ros2/validate_config.py"
],
"options": {
"cwd": "${workspaceFolder}"
},
"problemMatcher": []
},
{
"label": "Prepare X11 Test Environment",
"type": "process",
"command": "bash",
"args": [
"features/test/linux-x11-forwarding/prepare-host.sh"
],
"options": {
"cwd": "${workspaceFolder}",
"env": {
"DISPLAY": ":99",
"XDG_RUNTIME_DIR": "/tmp/devcontainers-x11-runtime",
"XAUTHORITY": "/tmp/devcontainers-xauthority.test",
"PULSE_SERVER": "unix:/tmp/devcontainers-x11-runtime/pulse-native"
}
},
"problemMatcher": []
},
{
"label": "Test ROS 2 Default",
"dependsOrder": "sequence",
"dependsOn": [
"Validate ROS 2 Configuration"
],
"type": "process",
"command": "devcontainer",
"args": [
"features",
"test",
"--base-image",
"mcr.microsoft.com/devcontainers/base:ubuntu-24.04",
"--features",
"ros2",
"--project-folder",
"./features",
"--skip-scenarios"
],
"options": {
"cwd": "${workspaceFolder}"
},
"problemMatcher": []
},
{
"label": "Test X11 Feature",
"dependsOrder": "sequence",
"dependsOn": [
"Prepare X11 Test Environment"
],
"type": "process",
"command": "devcontainer",
"args": [
"features",
"test",
"--features",
"linux-x11-forwarding",
"--project-folder",
"./features"
],
"options": {
"cwd": "${workspaceFolder}",
"env": {
"DISPLAY": ":99",
"XDG_RUNTIME_DIR": "/tmp/devcontainers-x11-runtime",
"XAUTHORITY": "/tmp/devcontainers-xauthority.test",
"PULSE_SERVER": "unix:/tmp/devcontainers-x11-runtime/pulse-native"
}
},
"problemMatcher": []
},
{
"label": "Test ROS 2 Compatibility Matrix",
"dependsOrder": "sequence",
"dependsOn": [
"Validate ROS 2 Configuration"
],
"type": "process",
"command": "devcontainer",
"args": [
"features",
"test",
"--features",
"ros2",
"--project-folder",
"./features",
"--skip-autogenerated"
],
"options": {
"cwd": "${workspaceFolder}"
},
"problemMatcher": []
},
{
"label": "Test Feature Suite",
"dependsOn": [
"Test X11 Feature",
"Test ROS 2 Default",
"Test ROS 2 Compatibility Matrix"
],
"group": {
"kind": "test",
"isDefault": true
},
"problemMatcher": []
},
{
"label": "Generate Feature Docs",
"type": "process",
Expand Down
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,11 @@ Devcontainer templates repository focused on robotics and simulation.

- `.devcontainer/gz-smoke/devcontainer.json`
- `.devcontainer/linux-x11-forwarding-smoke/devcontainer.json`
- `.devcontainer/ros2-feature-smoke/devcontainer.json`

Before using the samples locally, run
`bash .devcontainer/prepare-local-features.sh` so `devcontainer up` can resolve
the unpublished Feature.
the unpublished Features.

On classic Xorg hosts where the authority cookie lives outside
`XDG_RUNTIME_DIR`, add a bind mount to `/tmp/devcontainer-xauthority-host`.
Expand Down
32 changes: 32 additions & 0 deletions features/src/ros2/NOTES.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
## Supported Ubuntu releases

ROS 2 deb packages target a specific Ubuntu release. Choose a compatible base
image for the selected `distro`. The default `auto` setting selects:

| ROS 2 distribution | Ubuntu release |
|---|---|
| Humble | 22.04 (Jammy) |
| Jazzy | 24.04 (Noble) |
| Kilted | 24.04 (Noble) |
| Lyrical | 26.04 (Resolute) |

The installation stops with an explanatory error when the selected ROS 2 and
Ubuntu releases are incompatible. On Ubuntu 24.04, `auto` selects Jazzy because
it is the long-term ROS 2 release; select Kilted explicitly if desired.

The `package` option defaults to the GUI-oriented `desktop` installation. Select
`ros-base` for a smaller installation. In both cases, the Feature installs
`ros-dev-tools`, including common ROS development commands such as `colcon`,
`rosdep`, and `vcs`.

## Shell and workspace setup

The ROS installation is sourced automatically for the existing container user.
If the configured `workspace` contains `install/setup.sh`, that overlay is
sourced afterward. The Feature does not create or replace the container user.

ROS 2 packages installed from debs use Ubuntu's system Python. Conda or a
separately installed Python interpreter may be incompatible with those packages.

The Feature's ROS 2-to-Ubuntu compatibility data is stored in
`distributions.json` and packaged with the Feature.
Loading