From 9242498970f57573702ccf75fcce6980288439a1 Mon Sep 17 00:00:00 2001 From: jichuanh Date: Wed, 20 May 2026 23:11:54 +0000 Subject: [PATCH 1/4] [CI] Add Windows + ARM pytest markers and shared scaffolding Foundation for cross-platform CI. Registers four pytest markers (windows, windows_ci, arm, arm_ci), teaches AppLauncher to recognize them in argv so they do not leak into Isaac Sim's argparse, and moves the AssetConverterBase USD scratch directory from a hardcoded /tmp/IsaacLab to tempfile.gettempdir() for cross-platform compatibility. Tags source/isaaclab/test/deps/test_torch.py and test_scipy.py with the new markers so they are selectable by future cross-platform jobs. Workflow files (arm-ci.yaml, windows-ci.yaml) ship in follow-up PRs. --- pyproject.toml | 4 ++++ .../changelog.d/jichuanh-windows-spark-ci-min.skip | 1 + source/isaaclab/isaaclab/app/app_launcher.py | 10 ++++++++-- .../isaaclab/sim/converters/asset_converter_base.py | 12 +++++++----- source/isaaclab/test/deps/test_scipy.py | 2 ++ source/isaaclab/test/deps/test_torch.py | 2 ++ 6 files changed, 24 insertions(+), 7 deletions(-) create mode 100644 source/isaaclab/changelog.d/jichuanh-windows-spark-ci-min.skip diff --git a/pyproject.toml b/pyproject.toml index 86ab12b38ceb..33ba8e2b1274 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -194,6 +194,10 @@ ignore-words-list = "haa,slq,collapsable,buss,reacher,thirdparty" markers = [ "isaacsim_ci: mark test to run in isaacsim ci", + "windows: mark test as runnable on Windows platforms", + "windows_ci: mark test to run on Windows platforms in CI", + "arm: mark test as runnable on ARM platforms (e.g. NVIDIA DGX Spark)", + "arm_ci: mark test to run on ARM platforms in CI (e.g. NVIDIA DGX Spark)", ] # Add pypi.nvidia.com so that `uv pip install isaaclab[isaacsim]` works without --extra-index-url. diff --git a/source/isaaclab/changelog.d/jichuanh-windows-spark-ci-min.skip b/source/isaaclab/changelog.d/jichuanh-windows-spark-ci-min.skip new file mode 100644 index 000000000000..bfa2b75a780a --- /dev/null +++ b/source/isaaclab/changelog.d/jichuanh-windows-spark-ci-min.skip @@ -0,0 +1 @@ +Skip changelog: CI/test-infrastructure foundation (no user-facing API change). Registers the windows / windows_ci / arm / arm_ci pytest markers in pyproject.toml, teaches AppLauncher to recognize them in argv so they do not leak into Isaac Sim's argparse, and moves the AssetConverterBase USD scratch dir from hardcoded /tmp/IsaacLab to tempfile.gettempdir() for cross-platform compatibility. Workflow files (arm-ci.yaml, windows-ci.yaml) ship in follow-up PRs. diff --git a/source/isaaclab/isaaclab/app/app_launcher.py b/source/isaaclab/isaaclab/app/app_launcher.py index 2bdb8a08932d..a4f7a628f052 100644 --- a/source/isaaclab/isaaclab/app/app_launcher.py +++ b/source/isaaclab/isaaclab/app/app_launcher.py @@ -1127,12 +1127,18 @@ def _create_app(self): sys.stdout = open(os.devnull, "w") # noqa: SIM115 # pytest may have left some things in sys.argv, this will check for some of those - # do a mark and sweep to remove any -m pytest and -m isaacsim_ci and -c **/pyproject.toml + # do a mark and sweep to remove any -m pytest, -m isaacsim_ci, -m windows_ci, -m arm_ci, + # and -c **/pyproject.toml indexes_to_remove = [] for idx, arg in enumerate(sys.argv[:-1]): if arg == "-m": value_for_dash_m = sys.argv[idx + 1] - if "pytest" in value_for_dash_m or "isaacsim_ci" in value_for_dash_m: + if ( + "pytest" in value_for_dash_m + or "isaacsim_ci" in value_for_dash_m + or "windows_ci" in value_for_dash_m + or "arm_ci" in value_for_dash_m + ): indexes_to_remove.append(idx) indexes_to_remove.append(idx + 1) if arg.startswith("--config-file=") and "pyproject.toml" in arg: diff --git a/source/isaaclab/isaaclab/sim/converters/asset_converter_base.py b/source/isaaclab/isaaclab/sim/converters/asset_converter_base.py index 11c200422391..703ef202e2a7 100644 --- a/source/isaaclab/isaaclab/sim/converters/asset_converter_base.py +++ b/source/isaaclab/isaaclab/sim/converters/asset_converter_base.py @@ -9,6 +9,7 @@ import os import pathlib import random +import tempfile from datetime import datetime from isaaclab.sim.converters.asset_converter_base_cfg import AssetConverterBaseCfg @@ -34,9 +35,10 @@ class AssetConverterBase(abc.ABC): can be set to True. When no output directory is defined, lazy conversion is deactivated and the generated USD file is - stored in folder ``/tmp/IsaacLab/usd_{date}_{time}_{random}``, where the parameters in braces are generated - at runtime. The random identifiers help avoid a race condition where two simultaneously triggered conversions - try to use the same directory for reading/writing the generated files. + stored in folder ``/IsaacLab/usd_{date}_{time}_{random}``, where ```` is the system + temporary directory (e.g. ``/tmp`` on POSIX, ``%TEMP%`` on Windows) and the parameters in braces are + generated at runtime. The random identifiers help avoid a race condition where two simultaneously + triggered conversions try to use the same directory for reading/writing the generated files. .. note:: Changes to the parameters :obj:`AssetConverterBaseCfg.asset_path`, :obj:`AssetConverterBaseCfg.usd_dir`, and @@ -64,9 +66,9 @@ def __init__(self, cfg: AssetConverterBaseCfg): # resolve USD directory name if cfg.usd_dir is None: - # a folder in "/tmp/IsaacLab" by the name: usd_{date}_{time}_{random} + # a folder in the system temp dir by the name: IsaacLab/usd_{date}_{time}_{random} time_tag = datetime.now().strftime("%Y%m%d_%H%M%S") - self._usd_dir = f"/tmp/IsaacLab/usd_{time_tag}_{random.randrange(10000)}" + self._usd_dir = os.path.join(tempfile.gettempdir(), "IsaacLab", f"usd_{time_tag}_{random.randrange(10000)}") else: self._usd_dir = cfg.usd_dir diff --git a/source/isaaclab/test/deps/test_scipy.py b/source/isaaclab/test/deps/test_scipy.py index d697716aad7a..f42e54c304e9 100644 --- a/source/isaaclab/test/deps/test_scipy.py +++ b/source/isaaclab/test/deps/test_scipy.py @@ -13,6 +13,8 @@ import numpy as np import scipy.interpolate as interpolate +pytestmark = [pytest.mark.windows_ci, pytest.mark.arm_ci] + @pytest.mark.isaacsim_ci def test_interpolation(): diff --git a/source/isaaclab/test/deps/test_torch.py b/source/isaaclab/test/deps/test_torch.py index 6a50110757de..e651987daa26 100644 --- a/source/isaaclab/test/deps/test_torch.py +++ b/source/isaaclab/test/deps/test_torch.py @@ -7,6 +7,8 @@ import torch import torch.utils.benchmark as benchmark +pytestmark = [pytest.mark.windows_ci, pytest.mark.arm_ci] + @pytest.mark.isaacsim_ci def test_array_slicing(): From 65ca558adea173ca49966e0a21ba80810ac57e56 Mon Sep 17 00:00:00 2001 From: jichuanh Date: Mon, 1 Jun 2026 02:06:10 +0000 Subject: [PATCH 2/4] Drop unused bare windows/arm pytest marker registrations The bare `windows` and `arm` markers were registered alongside the live `windows_ci`/`arm_ci` selectors, but no test in this PR or in the follow-up cross-platform parts uses them. The `_ci` variants are the ones consumed by conftest's CI_MARKER orchestration and by the windows-ci workflow's `pytest -m windows_ci` invocation. Registering markers without a consumer just enlarges the surface a reviewer has to evaluate. Drop the bare entries; revisit when there's an actual use case (e.g. an exhaustive platform-compat sweep that's separate from the curated `_ci` canaries). --- pyproject.toml | 2 -- 1 file changed, 2 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 33ba8e2b1274..a2a781e466aa 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -194,9 +194,7 @@ ignore-words-list = "haa,slq,collapsable,buss,reacher,thirdparty" markers = [ "isaacsim_ci: mark test to run in isaacsim ci", - "windows: mark test as runnable on Windows platforms", "windows_ci: mark test to run on Windows platforms in CI", - "arm: mark test as runnable on ARM platforms (e.g. NVIDIA DGX Spark)", "arm_ci: mark test to run on ARM platforms in CI (e.g. NVIDIA DGX Spark)", ] From 1e321386c080add69e1adacf3f77e4437f9bc1d1 Mon Sep 17 00:00:00 2001 From: jichuanh Date: Mon, 1 Jun 2026 02:09:43 +0000 Subject: [PATCH 3/4] Drop test-file pytestmark annotations; ship registrations only MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 #5698 and #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. --- source/isaaclab/test/deps/test_scipy.py | 2 -- source/isaaclab/test/deps/test_torch.py | 2 -- 2 files changed, 4 deletions(-) diff --git a/source/isaaclab/test/deps/test_scipy.py b/source/isaaclab/test/deps/test_scipy.py index f42e54c304e9..d697716aad7a 100644 --- a/source/isaaclab/test/deps/test_scipy.py +++ b/source/isaaclab/test/deps/test_scipy.py @@ -13,8 +13,6 @@ import numpy as np import scipy.interpolate as interpolate -pytestmark = [pytest.mark.windows_ci, pytest.mark.arm_ci] - @pytest.mark.isaacsim_ci def test_interpolation(): diff --git a/source/isaaclab/test/deps/test_torch.py b/source/isaaclab/test/deps/test_torch.py index e651987daa26..6a50110757de 100644 --- a/source/isaaclab/test/deps/test_torch.py +++ b/source/isaaclab/test/deps/test_torch.py @@ -7,8 +7,6 @@ import torch import torch.utils.benchmark as benchmark -pytestmark = [pytest.mark.windows_ci, pytest.mark.arm_ci] - @pytest.mark.isaacsim_ci def test_array_slicing(): From ec875a207d20c18ea5f1632980967619c665f8e9 Mon Sep 17 00:00:00 2001 From: jichuanh Date: Thu, 11 Jun 2026 05:26:24 +0000 Subject: [PATCH 4/4] Align changelog fragment with registered markers --- source/isaaclab/changelog.d/jichuanh-windows-spark-ci-min.skip | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/isaaclab/changelog.d/jichuanh-windows-spark-ci-min.skip b/source/isaaclab/changelog.d/jichuanh-windows-spark-ci-min.skip index bfa2b75a780a..7dc9110d9f75 100644 --- a/source/isaaclab/changelog.d/jichuanh-windows-spark-ci-min.skip +++ b/source/isaaclab/changelog.d/jichuanh-windows-spark-ci-min.skip @@ -1 +1 @@ -Skip changelog: CI/test-infrastructure foundation (no user-facing API change). Registers the windows / windows_ci / arm / arm_ci pytest markers in pyproject.toml, teaches AppLauncher to recognize them in argv so they do not leak into Isaac Sim's argparse, and moves the AssetConverterBase USD scratch dir from hardcoded /tmp/IsaacLab to tempfile.gettempdir() for cross-platform compatibility. Workflow files (arm-ci.yaml, windows-ci.yaml) ship in follow-up PRs. +Skip changelog: CI/test-infrastructure foundation (no user-facing API change). Registers the windows_ci and arm_ci pytest markers in pyproject.toml, teaches AppLauncher to recognize them in argv so they do not leak into Isaac Sim's argparse, and moves the AssetConverterBase USD scratch dir from hardcoded /tmp/IsaacLab to tempfile.gettempdir() for cross-platform compatibility. Test tagging and the cross-platform workflow files (arm-ci.yaml, windows-ci.yaml) ship in follow-up PRs.