Repository navigation
Conversation
There was a problem hiding this comment.
Review Summary
This PR adds experimental Windows CI jobs for perception smoke testing, building on the uv-based installation path. The approach is well-structured, with incremental jobs that progressively test more functionality.
✅ Strengths
- Incremental approach: The workflow builds from simple torch/scipy tests → IsaacLab core install → full perception smoke
- Cross-platform fix in
AssetConverterBase: Moving from hardcoded/tmp/IsaacLabtotempfile.gettempdir()is the correct POSIX/Windows-agnostic solution - Proper marker recognition in AppLauncher: The
windows_ciandarm_cimarkers are now correctly filtered fromsys.argv - Good use of
continue-on-error: true: Appropriate for experimental jobs that should not gate merges
Architecture
- ✅ Clean separation of reusable GitHub Actions (
windows-instance-state,windows-sim-paths) from the main workflow - ✅ Consolidated single-job design prevents runner teardown between steps — smart approach for autoscaling runners
- ✅ OS-level watchdogs via
Start-Process + WaitForExitinstead of relying on GIL-vulnerable Python thread watchdogs - ✅ Develop-aligned Isaac Sim builds from internal Artifactory index (authenticated)
- ✅ Perception and training smoke tests enabled (WDDM mode confirmed)
⚠️ Optional Suggestions (Non-blocking)
run_docker_tests: 'false'inbuild.yaml: The comment says "TEMP: disable heavy Linux Docker + Tests" — should be reverted before merge if not intentional.- Hardcoded Git Bash Path:
C:\Program Files\Git\bin\bash.exeassumes standard installation. Consider fallback or documentation.
Update (ad92f43): Reviewed incremental diff from bae6977...ad92f43 (rebase on develop + Windows CI refinements):
Windows CI Changes:
- ✅ Perception test fully re-enabled: Both the standalone
test-perceptionstep and the perception subcase in training smoke now run. Perception added to$blockingin aggregate. - ✅ Develop-aligned Isaac Sim install: Setup step now resolves and installs the develop-branch-aligned Isaac Sim build from the internal Artifactory index (authenticated via
ISAACSIM_ARTIFACTORY_READONLY_*secrets). This replaces the previous public pip install and ensures CI tests against the same Sim as the Linux/ARM develop container. - ✅ Wheel install adjusted: The
[all]extra (which pinsisaacsim==5.1.0) is no longer used during wheel validation, preventing a downgrade of the develop Sim build. - ✅ Training smoke expanded: Step renamed to "state + perception" with increased timeout (25 min);
-k "not perception"filter removed.
Non-CI changes (develop rebase): The diff includes a large number of unrelated develop-branch changes (cloner refactoring, observation pipeline improvements, new tutorials, bugfixes, etc.) that are not part of this PR's Windows CI scope. No new issues found.
Approval stands.
d25f9bb to
6811028
Compare
Duplicate test_cartpole_training_smoke.py from PR isaac-sim#5698's branch so PR isaac-sim#5700 doesn't chain on it. Cross-platform tweaks vs ARM's copy: - pytestmark = [arm_ci, windows_ci] # dual marker - _LAUNCHER picks isaaclab.bat on Windows, isaaclab.sh elsewhere Add training-smoke-windows job that pytests this file in the same install + Sim-paths context as perception-windows. continue-on-error true and timeout-minutes 30 mirror the other Windows jobs. State case (Isaac-Cartpole-Direct-v0 / rsl_rl) should pass on TCC — no RTX, no Vulkan touch. Perception case (Isaac-Cartpole-RGB-Camera-Direct-v0 / rl_games) needs Vulkan and will fail on this runner until WDDM is enabled. Whichever of isaac-sim#5698 / isaac-sim#5700 merges first wins the test file; the other PR will drop the duplicate on rebase.
PR 5695 lays foundation only. The two tagged tests (test_scipy.py, test_torch.py) had pytestmark applied here but no in-PR consumer — the arm-ci and windows-ci workflows that select on these markers ship in isaac-sim#5698 and isaac-sim#5700 respectively. Each downstream PR should land the marker annotations on the tests it actually wants in its canary, alongside the workflow that runs them. This keeps 5695 self-contained as scaffolding and prevents unused annotations from accumulating here.
There was a problem hiding this comment.
Updated Review: Windows CI Pipeline (Part 3)
This is a comprehensive and well-structured PR that adds Windows CI support to IsaacLab. The implementation shows strong attention to platform-specific challenges and includes robust error handling. Below is my detailed analysis:
✅ Strengths
1. Solid Architecture
- Clean separation of reusable GitHub Actions (
windows-instance-state,windows-sim-paths) from the main workflow - Marker-driven test discovery (
windows_ci) allows adding tests without YAML edits - Consolidated single-job design prevents runner teardown between steps — smart approach for autoscaling runners
2. Robust Process Management
- OS-level watchdogs via
Start-Process + WaitForExitinstead of relying on GIL-vulnerable Python thread watchdogs - Per-job timeouts with
--timeout-method=thread(correctly avoiding Unix-only SIGALRM) - Hard timeouts with explicit kill on hung Kit/Vulkan processes
3. Cross-Platform Improvements
AssetConverterBasenow usestempfile.gettempdir()instead of hardcoded/tmp— correct fixwheel_builder/build.shPYTHONoverride handles Windows git-bash (which only haspython, notpython3)- HDF5 fixture uses
ignore_cleanup_errors=Trueto handle Windows file-lock races — good catch
4. Comprehensive Environment Setup
- EULA acceptance variables properly configured
- DLL search paths correctly prepended for Vulkan ICD discovery
- Instance state reporting helps diagnose runner issues (GPU presence, disk space, cache sizes)
⚠️ Suggestions & Minor Issues
1. Temporary Docker/Tests Disable in build.yaml
run_docker_tests: 'false' # TEMP: disable heavy Linux Docker + TestsThe comment says "revert before final review" — this should be reverted before merge. Consider adding a # TODO: tag that linters/CI can catch.
2. Hardcoded Git Bash Path
$gitBash = "C:\Program Files\Git\bin\bash.exe"
if (-not (Test-Path $gitBash)) { throw "Git Bash not found at $gitBash" }This assumes a standard Git for Windows installation. Consider:
- Falling back to
where.exe bashor checking common alternate paths (C:\Program Files (x86)\Git\bin\bash.exe) - Or documenting this as a runner requirement
3. Perception Test Gating
The perception test depends on WDDM mode for Vulkan. If runners could be in TCC mode, consider:
- Auto-detecting driver mode via
nvidia-smioutput - Adding a conditional skip rather than a CI failure
4. pytestmark Placement in test_configclass.py
from isaaclab.utils.configclass import _field_module_dir, configclass
pytestmark = pytest.mark.windows_ci
from isaaclab.utils.dict import class_to_dict, ...The pytestmark is sandwiched between imports — while functional, it's unconventional. Consider grouping it with other module-level declarations after all imports.
5. Magic Numbers
Several timeout values are hardcoded (300000ms, 180000ms, 600s, etc.). Consider:
- Documenting why these specific values were chosen
- Using named constants or environment variables for runner-specific tuning
📝 Questions
-
Checkpoint Cleanup: The cartpole training smoke tests run two iterations and create checkpoints. Are these cleaned up, or will they accumulate on runners?
-
Change Detection Logic: The
changesjob patterns don't include.github/actions/windows-*— is this intentional? Changes to these actions wouldn't trigger the workflow for validation. -
Python 3.12 Assumption: The
user site-packagespath assumes Python 3.12:"user site-pkgs" = "$env:APPDATA\Python\Python312\site-packages"
Should this be dynamic based on the installed Python version?
🔧 Final Notes
Overall, this is high-quality CI infrastructure work. The attention to Windows-specific quirks (DLL search order, file locking, PowerShell encoding, process watchdogs) demonstrates deep platform expertise.
Before merge:
- Revert the
run_docker_tests: 'false'workaround inbuild.yaml - Consider addressing the Git Bash path hardcoding
Other items are suggestions for future improvement rather than blockers.
Update (ad92f43): Reviewed the new commits since bae6977.
Changes Observed
-
Perception/Rendering Steps Re-enabled ✅
- Commit
27def394re-enables the perception and rendering test steps in the Windows CI workflow - The cartpole-camera perception smoke test now exercises the full RTX/Vulkan path
- Commit
-
Develop-Aligned Isaac Sim Installation ✅
- The workflow now installs a develop-aligned Isaac Sim build from the internal Artifactory index (instead of the public pip release)
- Uses authenticated index URLs with
ISAACSIM_ARTIFACTORY_READONLY_USERNAME/PASSWORDsecrets - The
tools/resolve_isaacsim_develop.pyresolver verifies the build is on the develop branch - Good approach to ensure Windows CI tests the same Sim as Linux/ARM develop
-
Authentication with Read-Only Secrets ✅
- Proper credential handling with URL-encoding for special characters
- GitHub masks secrets and uv redacts credentials when echoing index URLs
Outstanding Items
-
build.yaml Still Has
run_docker_tests: 'false'⚠️ - The temporary disable is still in place with the comment "revert before final review"
- This needs to be reverted before merge
-
Hardcoded Git Bash Path (unchanged from previous review)
- Still assumes standard Git for Windows installation at
C:\Program Files\Git\bin\bash.exe
- Still assumes standard Git for Windows installation at
Summary
The new commits address the perception/rendering testing and add proper develop-aligned Isaac Sim installation with authentication. The Windows CI workflow is now more comprehensive and aligned with the develop branch testing strategy.
Remaining before merge:
- Revert
run_docker_tests: 'false'in build.yaml
Update (5c04d23): Reviewed incremental changes since ad92f43.
Changes in This Push
- Artifactory URL Migration ✅
- All internal Artifactory URLs updated from
urm.nvidia.comtoartifactory.nvidia.com - PyPI index paths updated from
sw-isaacsim-pypi/simple→sw-isaacsim-pypi-local/simpleandct-omniverse-pypi/simple→ct-omniverse-pypi-local/simple - This affects both the
uv pip installindex URLs and theresolve_isaacsim_develop.py --index-urlargument - Standard infrastructure migration from the legacy URM hostname to the canonical Artifactory hostname with corrected local repository paths
- All internal Artifactory URLs updated from
Assessment
This is a straightforward infrastructure-only change — no logic modifications, no new features. The URL pattern change (-local/simple suffix) suggests these now point to the correct local Artifactory repositories rather than virtual aggregators.
No new concerns introduced. Previously noted items still apply:
build.yamlstill hasrun_docker_tests: 'false'that needs reverting before merge- Hardcoded Git Bash path remains unchanged
Update (5941931): Reviewed incremental changes since 5c04d23.
Changes in This Push
-
Fork PR Secret Handling — Graceful Degradation ✅
- Previously the workflow would hard-fail (
throw) whenISAACSIM_ARTIFACTORY_READONLY_*secrets were not set - Now emits a GitHub Actions
::warning::annotation and proceeds unauthenticated - This allows fork PRs (which don't receive repository secrets) to still exercise URL/DNS reachability
- Auth-dependent failures will surface later in in-repo runs where secrets are present
- Good approach — matches standard CI best practice for fork-safe workflows
- Previously the workflow would hard-fail (
-
Artifactory URL Path Correction ✅
- Removed
/api/pypi/prefix and/simplesuffix from all Artifactory index URLs - Before:
https://...artifactory.nvidia.com/artifactory/api/pypi/sw-isaacsim-pypi-local/simple - After:
https://...artifactory.nvidia.com/artifactory/sw-isaacsim-pypi-local/ - Same change applied to
ct-omniverse-pypi-localand theresolve_isaacsim_develop.py --index-urlargument - This likely aligns with the actual repository layout on the new
artifactory.nvidia.comhost (non-virtual repos don't use the/api/pypi/.../simplePEP 503 endpoint)
- Removed
Assessment
Both changes are operational improvements with no logic risk:
- The fork PR fix unblocks external contributors from running the workflow
- The URL path fix ensures correct repository resolution on the migrated Artifactory instance
No new concerns introduced. Previously noted items still apply:
build.yamlstill hasrun_docker_tests: 'false'that needs reverting before merge- Hardcoded Git Bash path remains unchanged
Update (77685d1): Reviewed incremental changes since 5941931.
Changes in This Push
- Network Reachability Diagnostic Step ✅
- Added a new "Probe index reachability (diagnostic)" step in the Windows CI workflow
- Uses
if: always()andcontinue-on-error: true— purely diagnostic, won't block the build - Probes three hosts:
artifactory.nvidia.com,urm.nvidia.com,pypi.nvidia.com - Tests both DNS resolution (
[System.Net.Dns]::GetHostAddresses) and TCP 443 connectivity (Test-NetConnection) - Logs runner metadata:
COMPUTERNAME,RUNNER_NAME, proxy environment variables, DNS server addresses - This decouples network/DNS diagnostics from pip failures — useful for debugging transient CI infra issues
Assessment
This is a non-blocking diagnostic addition. It helps isolate whether Windows CI failures stem from network reachability issues vs. package availability, especially given the recent Artifactory URL migrations. The step runs unconditionally (always()) so it will capture state even on prior step failures.
No new concerns introduced. Previously noted items still apply:
build.yamlstill hasrun_docker_tests: 'false'that needs reverting before merge- Hardcoded Git Bash path remains unchanged
|
Superseded by #6086 — re-opened from a branch in this repo (not a fork) so the Windows CI job receives the |
|
Reopened — #6086 (same-repo variant) is closed. Confirmed the fork rule was not the blocker: even on an in-repo PR the |
…base) (#5695) ## Summary Base PR for cross-platform CI on Windows and NVIDIA DGX Spark (ARM/aarch64 Linux). No user-facing API change. - Registers `windows_ci` and `arm_ci` pytest markers in pyproject.toml. - AppLauncher argv strip recognizes the new markers so `pytest -m windows_ci` (etc.) does not leak into Isaac Sim's argparse. - AssetConverterBase USD scratch dir: hardcoded `/tmp/IsaacLab` → `tempfile.gettempdir()` for cross-platform compatibility. This base PR ships only the marker registration and the shared scaffolding. Tagging specific suites with these markers, and the CI workflows that consume them, ship in the follow-up parts below — that keeps the marker/scaffolding change reviewable on its own and lets the consumer PRs rebase cleanly once it lands. ## Prior art and credits This work is a derivative of and builds directly on two prior PRs by other contributors: - #3900 by Kelly Guo (kellyguo11), against `main`, 2025-10-31 — "test windows CI". Designed and introduced the cross-platform marker scheme (`windows`, `windows_ci`, `arm`, `arm_ci`), tagged ~50 existing tests across the codebase, added the AppLauncher argv-strip pattern so the new pytest `-m` filters do not leak into Isaac Sim's argument parser, and pioneered the Windows CI job wiring. The marker design and AppLauncher behavior in this PR are taken directly from #3900. - #3845 by Alexander Poddubny (nv-apoddubny), against `main`, 2025-10-27 — "Adds basic CI verification on Windows". Built the original Windows self-hosted runner infrastructure: `isaaclab.bat` entry script, the initial `.github/workflows/build.yml` Windows job, and the self-hosted-runner labeling conventions this PR's downstream Part 2/Part 3 workflows still rely on. Both PRs target `main` and have not been merged. This PR rebases that work onto `develop` (where the active development happens — `main` is behind by hundreds of commits), narrows the base PR to just the marker scheme plus shared scaffolding (so the marker/runner plumbing can be validated end-to-end before tests are tagged and re-expanded), and adds an `arm_ci` marker variant + ARM/Spark runner support that #3900/#3845 did not include. Credit for the architecture goes to the authors above; this PR is the rebase + minimization step. ## Series PRs prefixed with `[CI] Cross-platform —` all contribute to bringing Isaac Lab CI up on Windows and NVIDIA DGX Spark runners. This PR is the base everything else builds on. Current siblings: - Part 1 (this PR, base) — Markers and shared scaffolding - Part 2 — #5698 — ARM/Spark workflow (`.github/workflows/arm-ci.yaml`) - Part 3 — #5700 — Windows workflow (`.github/workflows/windows-ci.yaml`) Siblings depend on this PR's marker scheme; the same scaffolding lines are carried in their branches and dedupe on rebase after this lands. Additional follow-up parts can be added later without renumbering existing ones. ## Test plan - [x] `pytest --markers` lists `windows_ci` and `arm_ci` (registered, no `PytestUnknownMarkWarning`). - [x] AppLauncher argv strip drops `-m windows_ci` / `-m arm_ci` before Isaac Sim's argparse runs. - [x] `./isaaclab.sh -f` (pre-commit) passes. - [x] Merged latest `develop`: the markers list is the union with the newly added `device_split` marker, and `--capture=no` argv stripping from develop is preserved.
## Summary - Adds an `arm-ci` job to the existing `Docker + Tests` workflow for NVIDIA DGX Spark self-hosted runners. It builds and tests on the same ARM runner because ECR is not wired for arm64. - Adds marker-driven ARM test selection through `CI_MARKER`, plus a shared kitless Cartpole state/camera smoke used by ARM and installation CI. - Extracts Docker dependency-hash and registry-login setup into shared composite actions used by the local Docker and ECR build paths. - Makes Docker dependency-cache keys platform-specific and bounds stale ARM cache tags on the long-lived Spark runner. ## 1. ARM/Spark CI 1.1 The `arm-ci` job shares the existing `changes` and `config` gating. It builds `Dockerfile.base` for `linux/arm64`, runs the `arm_ci`-selected tests, and then runs the shared Cartpole smoke. 1.2 OVRTX and OVPhysX are installed explicitly for the rendering probes. Missing ARM runtime dependencies fail instead of being hidden by architecture-specific skips. 1.3 The job uses the same workflow and shared actions as the amd64 jobs. ARM enables 14-day stale dependency-cache eviction because its runner has persistent local Docker storage and no ECR handoff. 1.4 The `arm_ci` marker run passes `test-k-expr: not ovphysx`, the same per-file `-k` expression the x86 `rendering-correctness-kitless` job applies on public pip-index runs. The ovphysx-backed rendering params require OVPhysX >= 0.5.1, which has no aarch64 wheel. ## 2. Shared CI utilities 2.1 `_lib/compute-deps-hash` computes one dependency-cache identity from install inputs, the resolved base-image digest, and target platform. Both `docker-build` and `ecr-build-push-pull` consume it. 2.2 `_lib/setup-docker-config` centralizes the credential-helper workaround and optional NGC login. It is idempotent when the ECR action delegates to `docker-build`. 2.3 `run-tests` forwards both upstream's per-file `test-k-expr` and this PR's `ci-marker` inputs into the test container. ## 3. Shared Cartpole smoke 3.1 `source/isaaclab/test/install_ci/misc/cartpole_training_smoke.py` is the common prepared-environment probe for state Cartpole training, camera observation/reward validity, and camera Cartpole training. 3.2 CLI and wheel installation tests execute the same probe inside their newly installed environments; ARM executes it inside its prepared image. 3.3 The base image installs `git-lfs` so RSL-RL can snapshot repository state from a mounted LFS checkout. ## 4. Cross-platform support 4.1 `AppLauncher` derives `EXP_PATH` from the installed `isaacsim` package when the variable is missing, while leaving existing configured environments unchanged. 4.2 `tools/conftest.py` supports `CI_MARKER` as a file-selection and pytest marker filter parallel to `ISAACSIM_CI_SHORT`, exact node-ID selection, and per-file `-k` filtering. ## Known problems - The three rendering modules apply `arm_ci` at module scope, so ARM collects all 32 cases per module. The ovphysx-backed cases are now deselected via `test-k-expr: not ovphysx` (section 1.4), leaving 15 Newton cases running per module. Without the filter, the extra ovphysx-ovrtx cases in `test_rendering_cartpole_kitless.py` pushed a single process past the OVRTX per-process SyncScopeId limit (~15 renderer creations), crashing HydraEngine initialization on the 16th env; this also reproduces on x86, so the failure is not ARM-specific. Narrowing ARM to the two intended representative tests is still pending. - Current `develop` pins OVPhysX `0.5.2+head.f62c22207c`, while this job installs the publicly available ARM `0.4.13` wheel. With the `not ovphysx` filter the ARM rendering selection is Newton-only, matching the x86 public pip-index fallback; revisit if an aarch64 OVPhysX >= 0.5.1 wheel or wheelhouse becomes available. ## 5. Series Part 2 of `[CI] Cross-platform —`. Depends on #5695 (Part 1). The Windows workflow is #5700 (Part 3). ## Test plan - [x] Merge current `develop` (`5f2db9902baa724427b7aa654835aa559fce64e8`). - [x] Run `./isaaclab.sh -f` before commit and before push. - [x] Collect the refreshed ARM rendering selection locally: 96 items (32 per rendering module), confirming the current over-selection. - [x] Deselect ovphysx rendering params in the ARM job (`test-k-expr: not ovphysx`), mirroring the x86 kitless public pip-index fallback. - [ ] Narrow ARM rendering coverage to the two intended representative tests. - [ ] Run the two selected tests and shared Cartpole smoke on Spark/aarch64. - [ ] Confirm the refreshed `Docker + Tests` workflow is green. - [ ] Trigger `daily-compatibility` before merge.
…base) (isaac-sim#5695) ## Summary Base PR for cross-platform CI on Windows and NVIDIA DGX Spark (ARM/aarch64 Linux). No user-facing API change. - Registers `windows_ci` and `arm_ci` pytest markers in pyproject.toml. - AppLauncher argv strip recognizes the new markers so `pytest -m windows_ci` (etc.) does not leak into Isaac Sim's argparse. - AssetConverterBase USD scratch dir: hardcoded `/tmp/IsaacLab` → `tempfile.gettempdir()` for cross-platform compatibility. This base PR ships only the marker registration and the shared scaffolding. Tagging specific suites with these markers, and the CI workflows that consume them, ship in the follow-up parts below — that keeps the marker/scaffolding change reviewable on its own and lets the consumer PRs rebase cleanly once it lands. ## Prior art and credits This work is a derivative of and builds directly on two prior PRs by other contributors: - isaac-sim#3900 by Kelly Guo (kellyguo11), against `main`, 2025-10-31 — "test windows CI". Designed and introduced the cross-platform marker scheme (`windows`, `windows_ci`, `arm`, `arm_ci`), tagged ~50 existing tests across the codebase, added the AppLauncher argv-strip pattern so the new pytest `-m` filters do not leak into Isaac Sim's argument parser, and pioneered the Windows CI job wiring. The marker design and AppLauncher behavior in this PR are taken directly from isaac-sim#3900. - isaac-sim#3845 by Alexander Poddubny (nv-apoddubny), against `main`, 2025-10-27 — "Adds basic CI verification on Windows". Built the original Windows self-hosted runner infrastructure: `isaaclab.bat` entry script, the initial `.github/workflows/build.yml` Windows job, and the self-hosted-runner labeling conventions this PR's downstream Part 2/Part 3 workflows still rely on. Both PRs target `main` and have not been merged. This PR rebases that work onto `develop` (where the active development happens — `main` is behind by hundreds of commits), narrows the base PR to just the marker scheme plus shared scaffolding (so the marker/runner plumbing can be validated end-to-end before tests are tagged and re-expanded), and adds an `arm_ci` marker variant + ARM/Spark runner support that isaac-sim#3900/isaac-sim#3845 did not include. Credit for the architecture goes to the authors above; this PR is the rebase + minimization step. ## Series PRs prefixed with `[CI] Cross-platform —` all contribute to bringing Isaac Lab CI up on Windows and NVIDIA DGX Spark runners. This PR is the base everything else builds on. Current siblings: - Part 1 (this PR, base) — Markers and shared scaffolding - Part 2 — isaac-sim#5698 — ARM/Spark workflow (`.github/workflows/arm-ci.yaml`) - Part 3 — isaac-sim#5700 — Windows workflow (`.github/workflows/windows-ci.yaml`) Siblings depend on this PR's marker scheme; the same scaffolding lines are carried in their branches and dedupe on rebase after this lands. Additional follow-up parts can be added later without renumbering existing ones. ## Test plan - [x] `pytest --markers` lists `windows_ci` and `arm_ci` (registered, no `PytestUnknownMarkWarning`). - [x] AppLauncher argv strip drops `-m windows_ci` / `-m arm_ci` before Isaac Sim's argparse runs. - [x] `./isaaclab.sh -f` (pre-commit) passes. - [x] Merged latest `develop`: the markers list is the union with the newly added `device_split` marker, and `--capture=no` argv stripping from develop is preserved.
## Summary - Adds an `arm-ci` job to the existing `Docker + Tests` workflow for NVIDIA DGX Spark self-hosted runners. It builds and tests on the same ARM runner because ECR is not wired for arm64. - Adds marker-driven ARM test selection through `CI_MARKER`, plus a shared kitless Cartpole state/camera smoke used by ARM and installation CI. - Extracts Docker dependency-hash and registry-login setup into shared composite actions used by the local Docker and ECR build paths. - Makes Docker dependency-cache keys platform-specific and bounds stale ARM cache tags on the long-lived Spark runner. ## 1. ARM/Spark CI 1.1 The `arm-ci` job shares the existing `changes` and `config` gating. It builds `Dockerfile.base` for `linux/arm64`, runs the `arm_ci`-selected tests, and then runs the shared Cartpole smoke. 1.2 OVRTX and OVPhysX are installed explicitly for the rendering probes. Missing ARM runtime dependencies fail instead of being hidden by architecture-specific skips. 1.3 The job uses the same workflow and shared actions as the amd64 jobs. ARM enables 14-day stale dependency-cache eviction because its runner has persistent local Docker storage and no ECR handoff. 1.4 The `arm_ci` marker run passes `test-k-expr: not ovphysx`, the same per-file `-k` expression the x86 `rendering-correctness-kitless` job applies on public pip-index runs. The ovphysx-backed rendering params require OVPhysX >= 0.5.1, which has no aarch64 wheel. ## 2. Shared CI utilities 2.1 `_lib/compute-deps-hash` computes one dependency-cache identity from install inputs, the resolved base-image digest, and target platform. Both `docker-build` and `ecr-build-push-pull` consume it. 2.2 `_lib/setup-docker-config` centralizes the credential-helper workaround and optional NGC login. It is idempotent when the ECR action delegates to `docker-build`. 2.3 `run-tests` forwards both upstream's per-file `test-k-expr` and this PR's `ci-marker` inputs into the test container. ## 3. Shared Cartpole smoke 3.1 `source/isaaclab/test/install_ci/misc/cartpole_training_smoke.py` is the common prepared-environment probe for state Cartpole training, camera observation/reward validity, and camera Cartpole training. 3.2 CLI and wheel installation tests execute the same probe inside their newly installed environments; ARM executes it inside its prepared image. 3.3 The base image installs `git-lfs` so RSL-RL can snapshot repository state from a mounted LFS checkout. ## 4. Cross-platform support 4.1 `AppLauncher` derives `EXP_PATH` from the installed `isaacsim` package when the variable is missing, while leaving existing configured environments unchanged. 4.2 `tools/conftest.py` supports `CI_MARKER` as a file-selection and pytest marker filter parallel to `ISAACSIM_CI_SHORT`, exact node-ID selection, and per-file `-k` filtering. ## Known problems - The three rendering modules apply `arm_ci` at module scope, so ARM collects all 32 cases per module. The ovphysx-backed cases are now deselected via `test-k-expr: not ovphysx` (section 1.4), leaving 15 Newton cases running per module. Without the filter, the extra ovphysx-ovrtx cases in `test_rendering_cartpole_kitless.py` pushed a single process past the OVRTX per-process SyncScopeId limit (~15 renderer creations), crashing HydraEngine initialization on the 16th env; this also reproduces on x86, so the failure is not ARM-specific. Narrowing ARM to the two intended representative tests is still pending. - Current `develop` pins OVPhysX `0.5.2+head.f62c22207c`, while this job installs the publicly available ARM `0.4.13` wheel. With the `not ovphysx` filter the ARM rendering selection is Newton-only, matching the x86 public pip-index fallback; revisit if an aarch64 OVPhysX >= 0.5.1 wheel or wheelhouse becomes available. ## 5. Series Part 2 of `[CI] Cross-platform —`. Depends on isaac-sim#5695 (Part 1). The Windows workflow is isaac-sim#5700 (Part 3). ## Test plan - [x] Merge current `develop` (`5f2db9902baa724427b7aa654835aa559fce64e8`). - [x] Run `./isaaclab.sh -f` before commit and before push. - [x] Collect the refreshed ARM rendering selection locally: 96 items (32 per rendering module), confirming the current over-selection. - [x] Deselect ovphysx rendering params in the ARM job (`test-k-expr: not ovphysx`), mirroring the x86 kitless public pip-index fallback. - [ ] Narrow ARM rendering coverage to the two intended representative tests. - [ ] Run the two selected tests and shared Cartpole smoke on Spark/aarch64. - [ ] Confirm the refreshed `Docker + Tests` workflow is green. - [ ] Trigger `daily-compatibility` before merge.
# Conflicts: # source/isaaclab/test/install_ci/misc/cartpole_training_smoke.py
The Cartpole smoke now renders the camera through the Newton renderer and Kit's RTX renderer, each in a fresh interpreter, and the ovrtx coexistence test reuses that check instead of keeping its own copy.
…ark-ci-perception # Conflicts: # .github/workflows/install-ci.yml
[Medium impact] The changes affect Windows CI and installation checks on GPU runners. The PR appears safe to merge, with a non-blocking gap in tests for Windows output capture and timeout cleanup. Findings
SummaryAdds native Windows installation tests and a Windows CI workflow using the shared test runner.
Diagram%%{init: {'theme': 'neutral'}}%%
flowchart TD
A[Relevant changes] --> B[Windows CI]
A --> C[Windows installation tests]
B --> D[Sync locked environment]
D --> E[Run windows_ci tests]
E --> F[Run Cartpole smoke tests]
C --> G[Build wheel with Git Bash]
G --> H[Run native installation suite]
F --> I[Upload reports]
H --> I
Reviews (1) · Last reviewed commit: "Keep the Windows installation venvs unde..." · Reviewed by Greptile |
| def _readable(fds, timeout): | ||
| """Return the pipes in ``fds`` that a read would not block on, waiting up to ``timeout`` seconds for one.""" | ||
| if os.name != "nt": | ||
| return select.select(fds, [], [], timeout)[0] | ||
| # Windows cannot select() on pipes, so poll each one instead. | ||
| deadline = time.monotonic() + timeout | ||
| while not (ready := [fd for fd in fds if _pipe_readable(fd)]) and time.monotonic() < deadline: | ||
| time.sleep(0.01) | ||
| return ready |
There was a problem hiding this comment.
Windows timeout paths lack tests
The new Windows pipe and process-kill paths have no focused tests. The existing test that runs a hung child is POSIX-only, so it cannot catch Windows failures in output capture or timeout cleanup. This is a non-blocking coverage gap: ordinary passing tests do not exercise cleanup after a timeout.
Add Windows tests for short output followed by silence, pipe closure, and killing a hung child with descendants, including the taskkill fallback.
Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!
|
run-ci |
There was a problem hiding this comment.
Isaac Lab Review Bot
Needs attention: Design and architecture (1), Style consistency (1). Other reviewed categories look good.
- PR description: Remove the unsupported claim that prior inline scripts became test files; the diff adds one coexistence test and modifies an existing smoke, while cited CI timings include run IDs.
- Design and architecture: Windows skips post-exit process-tree cleanup, allowing orphaned Kit processes to accumulate; launch tests in a Windows job object that terminates descendants on close.
- Scope and over-engineering: No over-engineering issues.
- API: API changes look good.
- Compatibility and deprecation: No breaking changes identified.
- Implementation: Implementation looks good.
- Style consistency: The new workflow uses
.yamlwhile adjacent workflows use.yml; rename it towindows-ci.ymland update its detect-changes pattern. - Test quality: Test quality looks good.
Minor fixes needed. Posted 2 inline findings.
Automated review; human maintainers own approval decisions.
| @@ -0,0 +1,160 @@ | |||
| # Copyright (c) 2022-2026, The Isaac Lab Project Developers (https://github.com/isaac-sim/IsaacLab/blob/main/CONTRIBUTORS.md). | |||
There was a problem hiding this comment.
🟡 Warning · Style Consistency — Workflow uses .yaml, not .yml
Adjacent workflows use .yml (install-ci.yml, and arm-ci.yml named in this file's header). Rename to windows-ci.yml and update the detect-changes pattern on line 65.
There was a problem hiding this comment.
Keeping .yaml. The workflows directory uses both extensions (10 .yaml, 13 .yml), and build.yaml, which runs the x86 test jobs, is .yaml.
| pass | ||
| # Kill any orphaned child processes (Kit, Isaac Sim) left by the test. On Windows the | ||
| # tree is unreachable once its root has exited. | ||
| if pgid is not None: |
There was a problem hiding this comment.
🟡 Warning · Design Architecture — Windows never reaps orphaned simulator children
On Windows pgid is None, so the post-exit cleanup that kills orphaned Kit processes on Linux is skipped entirely; self-hosted runners accumulate them. Launch the child in a job object that terminates on close.
There was a problem hiding this comment.
Not adding a job object here. A test that times out is killed with taskkill /T while its root is still alive, so its tree goes with it. Children that outlive a root that exited normally are reaped by the runner at job end: the Windows job logs show its "Cleaning up orphan processes" step, and in this PR's runs it has found nothing to terminate.
usd-exchange 3.0.1 fixed the DLL name clash the test guarded against (nvbug 6817794). The Cartpole smoke returns to the Newton probes it runs on main, so ARM CI runs what it runs there.
ARM CI's smoke runs Newton only, so Windows syncs the base environment with the test extra and no longer installs Isaac Sim or ovrtx, or keeps their shader caches.
Checkout cleans the workspace, so the environment moves to the runner's tool cache. A reused runner then re-syncs only what uv.lock changed and keeps the packages' compiled bytecode.
Skips ARM CI, the x86 and ARM installation tests, multi-GPU pytest, the license checks and the docs build. Must be reverted before final review.
Prints the runner, its boot time and the size of uv's cache, the kept environment and Warp's kernel cache before the sync and after the tests. Must be reverted before final review.
…ark-ci-perception
Adds a job that trains camera Cartpole for each physics and renderer pair in an environment kept on the runner, and masks the other Windows jobs meanwhile. Must be reverted before final review.
…ark-ci-perception
Pull requests restore the newest snapshot of a Windows Warp cache collection and pushes to protected branches save what they compiled, the policy of the Linux test jobs. The key comes from the same collection_id.py; the shared actions run bash, which resolves to WSL on these runners.
Simulates a fresh instance (attempts 1-2 of windows-ci; the seed and fresh legs of the Cartpole combinations), lets this PR save the caches, and restores Warp, Kit and ovrtx shader caches in the combinations job. Must be reverted before final review.
The runner empties RUNNER_TEMP at the start of every job and pull requests only restore, so a reused runner recompiled every kernel on each pull request. The cache now lives in the tool cache beside the environment; a save clears it first, so it never publishes kernels a pull request built.
It carries no signal for the Windows CI Warp cache change. Must be reverted before final review.
Warp reports its kernel cache directory with the \\?\ prefix on Windows, so tools/verify_warp_cache.py's os.path.commonpath raises. Its version check always passes on an environment synced from uv.lock, so Windows CI checks the path itself instead of changing the tool the Linux jobs share.
Windows CI installs the isaacsim and ov extras and trains camera Cartpole on each of the ten physics and renderer pairings that can share a process. The Kit and OVRTX driver shader caches join the Warp kernel cache under the Linux policy, so a fresh runner skips the shader compiles once main has saved them. The cache steps live in one script, since the shared actions run bash.
Summary
windows_cimarker tests through the shared orchestrator (tools/conftest.py), then the shared Cartpole smoke, then camera Cartpole trained on every physics and renderer pairing. Windows has no Docker, so the job syncs the environment on the runner and keeps it there between jobs, and restores the Linux jobs' Warp and shader caches.install_ci) gets a Windows job beside x86 and ARM, run natively.Description
Part 3 of the cross-platform CI series (Part 1 #5695 and Part 2 #5698 are merged). Runs on the
[self-hosted, gpu-windows]runners.1. Jobs
Windows CI / windows-ciARM CI / Build & Testuv sync --frozen --extra test --extra isaacsim --extra ovinto an environment kept in the runner's tool cache; restores the Warp kernel, Kit shader and OVRTX shader caches;CI_MARKER=windows_ci pytest tools;install_ci/misc/cartpole_training_smoke.pyon Newton, as on ARM;install_ci/misc/cartpole_backend_combinations_smoke.py:Isaac-Cartpole-Camera-Directon each of the 10 pairings of {Newton MJWarp, Newton Kamino, Isaac Sim PhysX, OvPhysX} x {Newton, OVRTX, Isaac RTX} renderer that can share a processInstallation Tests / Installation Tests (Windows)Installation Tests (x86)/(ARM)tools/run_install_ci.py nativeon a wheel built with Git's bash: freshuv sync --locked(base,isaacsim) with Cartpole training on Newton and Isaac Sim PhysX, wheel installs, lock resolution2.
windows_citestsisaaclab/test/utils/test_{configclass,dict,episode_data,hdf5_dataset_file_handler}.py3. Orchestrator on Windows
tools/conftest.pykeeps its Linux behavior and gains three Windows paths:select()on pipes, so each pipe is peeked (PeekNamedPipe) before a read.taskkill /T.4. Design notes
astral-sh/setup-uvv10.2.0 with uv 0.12.9, the uv the Docker images pin. v6, which the Linux workflows and the install-CI actions use, crashes on exit on these runners once uv is in the tool cache (Node/libuv assertion error on Windows self-hosted GitHub Actions runner astral-sh/setup-uv#686).uv.lockchanged and keeps the packages' compiled bytecode; a failed sync rebuilds it once..github/scripts/windows_ci_caches.ps1rebuilds the same keys (with the installed Isaac Sim and ovrtx versions) and reports. The caches sit on the runner beside the environment, so a reused runner keeps what earlier pull requests compiled; a save clears them first and publishes only the restored snapshot plus what that push compiled. Pull requests also run in the kept environment and uv cache, so a save reinstalls the environment from a uv cache of its own. uv, the Python it installs and the runner's own files still carry over from pull-request jobs; only runners kept apart from pull requests avoid that. Warp reports its directory with the\\?\prefix on Windows, whichtools/verify_warp_cache.pyrejects, so the script checks the path itself.isaacsim6.2.0.0 from pypi.nvidia.com, as the lock gives users.5. Test plan
tools/test_crash_journal.py,tools/test_file_scheduler.py) pass.CI_MARKER=windows_ci pytest toolsselects the four marked files and passes them (62 tests).windows-cigreen with the combinations and caches (run 40006339958): 5.0 min on a reused runner (sync 0 s, combinations 220 s); 17.3 min on a runner with nothing installed or cached, before main has saved a Windows cache (sync 245 s, combinations 680 s, of which the first OVRTX and Isaac RTX pairings compile shaders for 223 and 189 s). The Kit, OVRTX and Warp caches fill to 141, 119 and 75 MB.Installation Tests (Windows)under 10 min on a reused runner, the budgetwindows-cimeets at 5.0 min. While iterating, TEMP commits mask jobs with no signal for this change; they are reverted before review.Installation Tests (Windows)green, 8/8 in 10.1 min (run 38380247601). The first run failedtest_workspace_trains[isaacsim]: pytest's default base temp on the runner put Kit's DLLs past the 260-character path limit, so the job now passes--basetempunderRUNNER_TEMP.Type of change
Release backport
developScreenshots
Not applicable.
Checklist
Docker and GPU tests run on demand. Push the commits you want tested, then
comment
run-cion the pull request.pre-commitchecks withuv run isaaclab --formatsource/<pkg>/changelog.d/for every touched package (do not editCHANGELOG.rstor bump package versions — CI handles that)CONTRIBUTORS.mdor my name already exists there