Skip to content
Open
Show file tree
Hide file tree
Changes from 62 commits
Commits
Show all changes
63 commits
Select commit Hold shift + click to select a range
39cf8b8
Adds CI to dev/newton branch
kellyguo11 Nov 30, 2025
bd18d55
update CI
kellyguo11 Nov 30, 2025
8ac1825
fix test
kellyguo11 Nov 30, 2025
de72bed
format
kellyguo11 Nov 30, 2025
8a00aa9
update docker
kellyguo11 Nov 30, 2025
5856277
test docker
kellyguo11 Nov 30, 2025
8cec587
Revert "test docker"
kellyguo11 Nov 30, 2025
b17ed05
format
kellyguo11 Nov 30, 2025
e33894f
update CI jobs
kellyguo11 Nov 30, 2025
b027046
Updates sim to 5.1, updates install scripts, mujoco version
kellyguo11 Nov 30, 2025
91d561f
update conftest.py
kellyguo11 Nov 30, 2025
3e9574a
add pytest.ini
kellyguo11 Nov 30, 2025
3a9e80a
fix env tests
kellyguo11 Nov 30, 2025
d631a44
add print
kellyguo11 Nov 30, 2025
a91da43
fix -v flag
kellyguo11 Nov 30, 2025
afc6456
update sb3
kellyguo11 Nov 30, 2025
d252999
update tests
kellyguo11 Dec 1, 2025
f4f8989
fix environment training test; skip failing tests
kellyguo11 Dec 3, 2025
a5f293d
update tests
kellyguo11 Dec 3, 2025
4edb4c4
Merge branch 'dev/newton' into add_ci
kellyguo11 Dec 3, 2025
84071b4
fix schema tests
kellyguo11 Dec 3, 2025
d9b04f1
format
kellyguo11 Dec 3, 2025
4ee24fc
skip failing solver tests
kellyguo11 Dec 3, 2025
a29eacd
test solver convergence only
kellyguo11 Dec 3, 2025
723f111
test solver tests
kellyguo11 Dec 4, 2025
9265af9
skip reach-ur10 solver test
kellyguo11 Dec 4, 2025
3f928c3
lower threshold
kellyguo11 Dec 4, 2025
a3cbe5f
reset test job
kellyguo11 Dec 4, 2025
99dff4b
Adds CI job to run tests on latest newton builds
kellyguo11 Dec 4, 2025
996cb64
separate into tasks and general tests
kellyguo11 Dec 4, 2025
3fba7cf
add mujoco pypi link
kellyguo11 Dec 4, 2025
8d2e299
fix mujoco-warp
kellyguo11 Dec 4, 2025
a5d1965
fix mjwarp version
kellyguo11 Dec 4, 2025
b832484
fix mjwarp installg
kellyguo11 Dec 4, 2025
52e2c53
update remaining numpy versions to 2+
kellyguo11 Dec 4, 2025
92c4cc2
revert numpy 2 since it doesn't work with replicator
kellyguo11 Dec 4, 2025
ba4daa7
update rerun dependency
kellyguo11 Dec 4, 2025
03674c4
revert dex-retargeting for numpy
kellyguo11 Dec 4, 2025
0a623dc
Merge branch 'dev/newton' of github.com:isaac-sim/IsaacLab into add_ci
kellyguo11 Dec 5, 2025
ed44783
Merge branch 'dev/newton' of github.com:isaac-sim/IsaacLab into add_ci
kellyguo11 Dec 5, 2025
ffd3a65
Merge branch 'dev/newton' of github.com:isaac-sim/IsaacLab into add_ci
kellyguo11 Dec 5, 2025
df08679
fix more tests
kellyguo11 Dec 5, 2025
a881492
fix more tests
kellyguo11 Dec 5, 2025
c949941
fix articulation test
kellyguo11 Dec 5, 2025
b037ec7
Merge branch 'dev/newton' of github.com:isaac-sim/IsaacLab into newto…
kellyguo11 Dec 5, 2025
8d01d33
Merge branch 'add_ci' of github.com:kellyguo11/IsaacLab-public into n…
kellyguo11 Dec 5, 2025
ee87c08
fix more tests
kellyguo11 Dec 5, 2025
b9a75f1
traverse variants in assets.py
kellyguo11 Dec 5, 2025
3b2135c
keep numpy 2
kellyguo11 Dec 5, 2025
a2808be
disable camera tests
kellyguo11 Dec 6, 2025
62c2889
Merge branch 'dev/newton' into add_ci
kellyguo11 Dec 6, 2025
fdc5b99
Merge branch 'dev/newton' of github.com:isaac-sim/IsaacLab into add_ci
kellyguo11 Dec 6, 2025
8e0b927
Merge branch 'add_ci' of github.com:kellyguo11/IsaacLab-public into a…
kellyguo11 Dec 6, 2025
956ea0c
fix mesh converter test
kellyguo11 Dec 6, 2025
84f111e
Merge branch 'add_ci' of github.com:kellyguo11/IsaacLab-public into n…
kellyguo11 Dec 6, 2025
dc9eb3a
Merge branch 'dev/newton' into newton-latest-ci
kellyguo11 Dec 7, 2025
7eab2fc
Merge branch 'dev/newton' into newton-latest-ci
kellyguo11 Dec 7, 2025
f6c48f0
fix tests
kellyguo11 Dec 7, 2025
02cad78
Merge branch 'dev/newton' into newton-latest-ci
kellyguo11 Dec 7, 2025
15f0add
fix conftest
kellyguo11 Dec 7, 2025
5b926d7
Merge branch 'newton-latest-ci' of github.com:kellyguo11/IsaacLab-pub…
kellyguo11 Dec 7, 2025
a10af96
update stdout?
kellyguo11 Dec 7, 2025
1dcf6e9
Update .github/actions/run-tests-newton-latest/action.yml
kellyguo11 Dec 7, 2025
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
214 changes: 214 additions & 0 deletions .github/actions/run-tests-newton-latest/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,214 @@
# Copyright (c) 2022-2025, The Isaac Lab Project Developers (https://github.com/isaac-sim/IsaacLab/blob/main/CONTRIBUTORS.md).
# All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause

name: 'Run Tests with Latest Newton'
description: 'Runs pytest tests in a Docker container with the latest Newton from main branch'

inputs:
test-path:
description: 'Path to test directory or pytest arguments'
required: true
result-file:
description: 'Name of the result XML file'
required: true
container-name:
description: 'Name for the Docker container'
required: true
image-tag:
description: 'Docker image tag to use'
required: true
reports-dir:
description: 'Directory to store test results'
default: 'reports'
required: false
pytest-options:
description: 'Additional pytest options (e.g., -k filter)'
default: ''
required: false
filter-pattern:
description: 'Pattern to filter test files (e.g., isaaclab_tasks)'
default: ''
required: false

runs:
using: composite
steps:
- name: Run Tests with Latest Newton in Docker Container
shell: bash
run: |
# Function to run tests in Docker container with latest Newton
run_tests() {
local test_path="$1"
local result_file="$2"
local container_name="$3"
local image_tag="$4"
local reports_dir="$5"
local pytest_options="$6"
local filter_pattern="$7"

echo "Running tests with latest Newton in: $test_path"
if [ -n "$pytest_options" ]; then
echo "With pytest options: $pytest_options"
fi
if [ -n "$filter_pattern" ]; then
echo "With filter pattern: $filter_pattern"
fi

# Create reports directory
mkdir -p "$reports_dir"

# Clean up any existing container
docker rm -f $container_name 2>/dev/null || true

# Build Docker environment variables
docker_env_vars="\
-e OMNI_KIT_ACCEPT_EULA=yes \
-e ACCEPT_EULA=Y \
-e OMNI_KIT_DISABLE_CUP=1 \
-e ISAAC_SIM_HEADLESS=1 \
-e ISAAC_SIM_LOW_MEMORY=1 \
-e PYTHONUNBUFFERED=1 \
-e PYTHONIOENCODING=utf-8 \
-e TEST_RESULT_FILE=$result_file"

if [ -n "$filter_pattern" ]; then
if [[ "$filter_pattern" == not* ]]; then
# Handle "not pattern" case
exclude_pattern="${filter_pattern#not }"
docker_env_vars="$docker_env_vars -e TEST_EXCLUDE_PATTERN=$exclude_pattern"
echo "Setting exclude pattern: $exclude_pattern"
else
# Handle positive pattern case
docker_env_vars="$docker_env_vars -e TEST_FILTER_PATTERN=$filter_pattern"
echo "Setting include pattern: $filter_pattern"
fi
else
echo "No filter pattern provided"
fi

echo "Docker environment variables: '$docker_env_vars'"

# Run tests in container with error handling
echo "🚀 Starting Docker container for tests with latest Newton..."
if docker run --name $container_name \
--entrypoint bash --gpus all --network=host \
--security-opt=no-new-privileges:true \
--memory=$(echo "$(free -m | awk '/^Mem:/{print $2}') * 0.9 / 1" | bc)m \
--cpus=$(echo "$(nproc) * 0.9" | bc) \
--oom-kill-disable=false \
--ulimit nofile=65536:65536 \
--ulimit nproc=4096:4096 \
$docker_env_vars \
$image_tag \
-c "
set -e
cd /workspace/isaaclab
mkdir -p tests

echo '=== Uninstalling existing newton and mujoco-warp ==='
/isaac-sim/python.sh -m pip uninstall -y newton mujoco-warp mujoco || echo 'Some packages may not have been installed'

echo '=== Cloning latest Newton from main branch ==='
git clone --depth 1 https://github.com/newton-physics/newton.git /tmp/newton

echo '=== Installing Newton with dependencies from uv.lock ==='
cd /tmp/newton

# Extract mujoco-warp and mujoco versions from uv.lock and install them
# Parse the uv.lock file to get the package versions
if [ -f uv.lock ]; then
echo 'Parsing uv.lock for mujoco-warp and mujoco versions...'

# Set PIP_FIND_LINKS for mujoco packages
export PIP_FIND_LINKS=https://py.mujoco.org/

# Extract mujoco version from uv.lock
mujoco_version=\$(grep -A5 'name = \"mujoco\"' uv.lock | grep 'version = ' | head -1 | sed 's/.*version = \"\(.*\)\"/\1/')
if [ -n \"\$mujoco_version\" ]; then
echo \"Installing mujoco==\$mujoco_version\"
/isaac-sim/python.sh -m pip install \"mujoco==\$mujoco_version\"
else
echo 'mujoco version not found in uv.lock, installing latest'
/isaac-sim/python.sh -m pip install mujoco
fi

# Extract mujoco-warp git URL from uv.lock (it's installed from git source)
mujoco_warp_git=\$(grep -A10 'name = \"mujoco-warp\"' uv.lock | grep 'git = ' | head -1 | sed 's/.*git = \"\([^\"]*\)\".*/\1/')
if [ -n \"\$mujoco_warp_git\" ]; then
# Parse the git URL - format is https://github.com/org/repo#commit_hash
git_url=\$(echo \"\$mujoco_warp_git\" | cut -d'#' -f1)
commit_hash=\$(echo \"\$mujoco_warp_git\" | cut -d'#' -f2)
echo \"Installing mujoco-warp from git: \$git_url at commit \$commit_hash\"
/isaac-sim/python.sh -m pip install \"git+\${git_url}@\${commit_hash}\"
else
echo 'mujoco-warp git source not found in uv.lock, installing from pip'
/isaac-sim/python.sh -m pip install mujoco-warp
fi
else
echo 'uv.lock not found, installing latest versions'
export PIP_FIND_LINKS=https://py.mujoco.org/
/isaac-sim/python.sh -m pip install mujoco
/isaac-sim/python.sh -m pip install git+https://github.com/google-deepmind/mujoco_warp.git
fi

# Install Newton from the cloned repo
echo '=== Installing Newton from source ==='
/isaac-sim/python.sh -m pip install -e .

echo '=== Verifying installations ==='
/isaac-sim/python.sh -c \"import newton; print(f'Newton version: {newton.__version__}')\" || echo 'Newton import check'
/isaac-sim/python.sh -c \"import mujoco_warp; print('mujoco_warp imported successfully')\" || echo 'mujoco_warp not available'
/isaac-sim/python.sh -c \"import mujoco; print(f'mujoco version: {mujoco.__version__}')\" || echo 'mujoco not available'

cd /workspace/isaaclab
echo '=== Starting pytest with path: $test_path ==='
/isaac-sim/python.sh -m pytest --ignore=tools/conftest.py $test_path $pytest_options -v --junitxml=tests/$result_file || echo 'Pytest completed with exit code: \$?'
"; then
echo "✅ Docker container completed successfully"
else
echo "⚠️ Docker container failed, but continuing to copy results..."
fi

# Copy test results with error handling
echo "📋 Attempting to copy test results..."
if docker cp $container_name:/workspace/isaaclab/tests/$result_file "$reports_dir/$result_file" 2>/dev/null; then
echo "✅ Test results copied successfully"
else
echo "❌ Failed to copy specific result file, trying to copy all test results..."
if docker cp $container_name:/workspace/isaaclab/tests/ "$reports_dir/" 2>/dev/null; then
echo "✅ All test results copied successfully"
# Look for any XML files and use the first one found
if [ -f "$reports_dir/full_report.xml" ]; then
mv "$reports_dir/full_report.xml" "$reports_dir/$result_file"
echo "✅ Found and renamed full_report.xml to $result_file"
elif [ -f "$reports_dir/test-reports-"*".xml" ]; then
Copy link
Contributor

Choose a reason for hiding this comment

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

logic: This test condition will always fail. When using wildcards in [ -f ], the pattern won't expand and it will literally check for a file named test-reports-*.xml with an asterisk in the name.

Suggested change
elif [ -f "$reports_dir/test-reports-"*".xml" ]; then
elif ls "$reports_dir"/test-reports-*.xml 1> /dev/null 2>&1; then

# Combine individual test reports if no full report exists
echo "📊 Combining individual test reports..."
echo '<?xml version="1.0" encoding="utf-8"?><testsuites>' > "$reports_dir/$result_file"
for xml_file in "$reports_dir"/test-reports-*.xml; do
if [ -f "$xml_file" ]; then
echo " Processing: $xml_file"
sed '1d; /^<testsuite/d; /^<\/testsuite/d' "$xml_file" >> "$reports_dir/$result_file" 2>/dev/null || true
fi
done
echo '</testsuites>' >> "$reports_dir/$result_file"
echo "✅ Combined individual test reports into $result_file"
else
echo "❌ No test result files found, creating fallback"
echo "<?xml version=\"1.0\" encoding=\"utf-8\"?><testsuite name=\"$container_name\" tests=\"0\" failures=\"0\" errors=\"1\" time=\"0\"><testcase classname=\"setup\" name=\"no_results_found\"><error message=\"No test results found\">Container may have failed to generate any results</error></testcase></testsuite>" > "$reports_dir/$result_file"
fi
else
echo "❌ Failed to copy any test results, creating fallback"
echo "<?xml version=\"1.0\" encoding=\"utf-8\"?><testsuite name=\"$container_name\" tests=\"0\" failures=\"0\" errors=\"1\" time=\"0\"><testcase classname=\"setup\" name=\"copy_failed\"><error message=\"Failed to copy test results\">Container may have failed to generate results</error></testcase></testsuite>" > "$reports_dir/$result_file"
fi
fi

# Clean up container
echo "🧹 Cleaning up Docker container..."
docker rm $container_name 2>/dev/null || echo "⚠️ Container cleanup failed, but continuing..."
}

# Call the function with provided parameters
run_tests "${{ inputs.test-path }}" "${{ inputs.result-file }}" "${{ inputs.container-name }}" "${{ inputs.image-tag }}" "${{ inputs.reports-dir }}" "${{ inputs.pytest-options }}" "${{ inputs.filter-pattern }}"
119 changes: 118 additions & 1 deletion .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -151,8 +151,110 @@ jobs:
exit 1
fi

test-newton-latest-tasks:
runs-on: [self-hosted, gpu]
timeout-minutes: 180
continue-on-error: true

steps:
- name: Checkout Code
uses: actions/checkout@v4
with:
fetch-depth: 0
lfs: true

- name: Build Docker Image
uses: ./.github/actions/docker-build
with:
image-tag: ${{ env.DOCKER_IMAGE_TAG }}
isaacsim-base-image: ${{ env.ISAACSIM_BASE_IMAGE }}
isaacsim-version: ${{ env.ISAACSIM_BASE_VERSION }}

- name: Run IsaacLab Tasks Tests with Latest Newton
uses: ./.github/actions/run-tests-newton-latest
with:
test-path: "tools"
result-file: "newton-latest-tasks-report.xml"
container-name: "isaac-lab-newton-latest-tasks-test-$$"
image-tag: ${{ env.DOCKER_IMAGE_TAG }}
pytest-options: ""
filter-pattern: "isaaclab_tasks"

- name: Upload Newton Latest Tasks Test Results
uses: actions/upload-artifact@v4
if: always()
with:
name: newton-latest-tasks-test-results
path: reports/newton-latest-tasks-report.xml
retention-days: 1
compression-level: 9

- name: Check Test Results for Fork PRs
if: github.event.pull_request.head.repo.full_name != github.repository
run: |
if [ -f "reports/newton-latest-tasks-report.xml" ]; then
if grep -q 'failures="[1-9]' reports/newton-latest-tasks-report.xml || grep -q 'errors="[1-9]' reports/newton-latest-tasks-report.xml; then
echo "Tests failed for PR from fork. The test report is in the logs. Failing the job."
exit 1
fi
else
echo "No test results file found. This might indicate test execution failed."
exit 1
fi

test-newton-latest-general:
runs-on: [self-hosted, gpu]
timeout-minutes: 180
continue-on-error: true

steps:
- name: Checkout Code
uses: actions/checkout@v4
with:
fetch-depth: 0
lfs: true

- name: Build Docker Image
uses: ./.github/actions/docker-build
with:
image-tag: ${{ env.DOCKER_IMAGE_TAG }}
isaacsim-base-image: ${{ env.ISAACSIM_BASE_IMAGE }}
isaacsim-version: ${{ env.ISAACSIM_BASE_VERSION }}

- name: Run General Tests with Latest Newton
uses: ./.github/actions/run-tests-newton-latest
with:
test-path: "tools"
result-file: "newton-latest-general-report.xml"
container-name: "isaac-lab-newton-latest-general-test-$$"
image-tag: ${{ env.DOCKER_IMAGE_TAG }}
pytest-options: ""
filter-pattern: "not isaaclab_tasks"

- name: Upload Newton Latest General Test Results
uses: actions/upload-artifact@v4
if: always()
with:
name: newton-latest-general-test-results
path: reports/newton-latest-general-report.xml
retention-days: 1
compression-level: 9

- name: Check Test Results for Fork PRs
if: github.event.pull_request.head.repo.full_name != github.repository
run: |
if [ -f "reports/newton-latest-general-report.xml" ]; then
if grep -q 'failures="[1-9]' reports/newton-latest-general-report.xml || grep -q 'errors="[1-9]' reports/newton-latest-general-report.xml; then
echo "Tests failed for PR from fork. The test report is in the logs. Failing the job."
exit 1
fi
else
echo "No test results file found. This might indicate test execution failed."
exit 1
fi

combine-results:
needs: [test-isaaclab-tasks, test-general]
needs: [test-isaaclab-tasks, test-general, test-newton-latest-tasks, test-newton-latest-general]
runs-on: [self-hosted, gpu]
if: always()

Expand All @@ -179,6 +281,21 @@ jobs:
with:
name: general-test-results
path: reports/
continue-on-error: true

- name: Download Newton Latest Tasks Test Results
uses: actions/download-artifact@v4
with:
name: newton-latest-tasks-test-results
path: reports/
continue-on-error: true

- name: Download Newton Latest General Test Results
uses: actions/download-artifact@v4
with:
name: newton-latest-general-test-results
path: reports/
continue-on-error: true

- name: Combine All Test Results
uses: ./.github/actions/combine-results
Expand Down
7 changes: 5 additions & 2 deletions source/isaaclab/isaaclab/app/app_launcher.py
Original file line number Diff line number Diff line change
Expand Up @@ -877,12 +877,15 @@ def _create_app(self):

# disable sys stdout and stderr to avoid printing the warning messages
# this is mainly done to purge the print statements from the simulation app
# Note: We save the current stdout (not sys.__stdout__) to properly restore it
# when running under pytest or other tools that capture output
original_stdout = sys.stdout
if "--verbose" not in sys.argv and "--info" not in sys.argv:
sys.stdout = open(os.devnull, "w") # noqa: SIM115
# launch simulation app
self._app = SimulationApp(self._sim_app_config, experience=self._sim_experience_file)
# enable sys stdout and stderr
sys.stdout = sys.__stdout__
# restore the original stdout
sys.stdout = original_stdout

# add Isaac Lab modules back to sys.modules
for key, value in hacked_modules.items():
Expand Down
2 changes: 0 additions & 2 deletions source/isaaclab/test/assets/test_articulation.py
Original file line number Diff line number Diff line change
Expand Up @@ -106,15 +106,13 @@ def generate_articulation_cfg(
articulation_cfg.actuators = {
"cart_actuator": ImplicitActuatorCfg(
joint_names_expr=["slider_to_cart"],
control_mode="position",
effort_limit=400.0,
velocity_limit=100.0,
stiffness=10.0,
damping=10.0,
),
"pole_actuator": ImplicitActuatorCfg(
joint_names_expr=["cart_to_pole"],
control_mode="none",
effort_limit=400.0,
velocity_limit=100.0,
stiffness=0.0,
Expand Down
Loading
Loading