Repository navigation
[Backport release/3.0.0] Towncrier changelog, camera hot-path 7B, and uv docs CLI (#8118, #8105, #8179) - #8210
Conversation
…ck in sync (isaac-sim#8118) - Replaces the custom changelog compiler with towncrier and `uv version`: `tools/changelog/cli.py` shrinks from 1,146 to ~320 lines and compiles today's pending fragments to the same versions and entries. - Keeps `uv.lock` in step with the nightly version bumps, so a clean checkout's first `uv run` no longer rewrites it. - **Fragments:** one `<slug>.<type>.rst` per entry type (`added`, `changed`, `deprecated`, `removed`, `fixed`) holding only `* ` bullets; an empty `<slug>.minor` / `<slug>.major` raises the bump; `<slug>.skip` is unchanged. The check rejects the old `<slug>[.minor|.major].rst` format. The nightly still splits old-format fragments merged before this change or without re-running CI, in a marked workaround section of `cli.py` that never overwrites an existing fragment; delete that section once none are pending. - **`cli.py check`** (pre-commit and the fragment-check job): each changed package must add a valid fragment and may not change a pending one; every `CHANGELOG.rst` keeps the `.. towncrier release notes start` marker line; each local package must be in `uv.lock` at its `pyproject.toml` version. The rest of the lock is not resolved, so unrelated dependency drift never fails a PR. - **`cli.py compile`** (nightly): runs only on a clean checkout. Per package, `uv version --bump` + `towncrier build`, then one `uv lock` on the uv pinned in the Docker images. If the re-lock fails or would change anything but local packages' versions, nothing is committed that night. `compile` stages exactly its outputs and reports any other changed file. - **Nightly:** compiles only branches carrying `tools/changelog/towncrier.toml`; release branches pick the change up by backport. - **`isaaclab_tasks_experimental`** gains a `CHANGELOG.rst`, so its pending fragments now compile. - **`uv.lock`** is re-locked once: 9 local package pins had fallen behind their `pyproject.toml`. - Supersedes isaac-sim#5867. **Before / after**, for a PR that adds a feature and a fix with a minor bump. Before: one file, `source/isaaclab/changelog.d/add-foo-sensor.minor.rst`: ```rst Added ^^^^^ * Added :class:`~isaaclab.sensors.FooSensor` for per-link foo readings. Fixed ^^^^^ * Fixed contact sensor reset behavior when only a subset of environments was reset. ``` After: one file per type, plus an empty tier file: ```text * Added :class:`~isaaclab.sensors.FooSensor` for per-link foo readings. * Fixed contact sensor reset behavior when only a subset of environments was reset. (empty) ``` Both compile to the same `CHANGELOG.rst` entry: the check rejects the first in new PRs, and the nightly splits any already merged into the second. Verified in a scratch clone of `develop`: `compile` produced the old tool's versions for all 9 packages with pending fragments, byte-identical `CHANGELOG.rst` entries for 7 and the same bullets in fragment-name order (instead of merge order) for 2, consumed every fragment, staged only its outputs, and changed only version lines in `uv.lock`. CI also runs a unit test with the real uv and towncrier. - New feature (non-breaking change which adds functionality) - Bug fix (non-breaking change which fixes an issue) - Documentation update - [x] <!-- backport-active-release --> Backport this pull request to the active release branch after it merges into `develop` Not applicable. Docker and GPU tests run on demand. Push the commits you want tested, then comment `run-ci` on the pull request. - [x] I have read and understood the [contribution guidelines](https://isaac-sim.github.io/IsaacLab/main/source/refs/contributing.html) - [x] I have run the [`pre-commit` checks](https://pre-commit.com/) on the changed files - [x] I have made corresponding changes to the documentation - [ ] My changes generate no new warnings - [x] I have added tests that prove my fix is effective or that my feature works - [x] I have added a `.skip` changelog fragment for each package whose `CHANGELOG.rst` gained the marker; the tooling itself is outside the source packages - [x] I have added my name to the `CONTRIBUTORS.md` or my name already exists there (cherry picked from commit ee99db6)
…aac-sim#8105) Part 7B of the camera performance series, based on the latest `develop` (including isaac-sim#8039, isaac-sim#8042, and isaac-sim#8087). A sweep of the per-step hot path found remaining host-device synchronizations and code that costs more than it gives. This PR fixes the verified findings: it removes the synchronizations, launch overhead, and dead or over-defensive code, and fixes the verified bugs. Profiling on `develop` motivated this. The GPU sat idle 20–27% of each step, because the CPU blocked on synchronizations and then launched hundreds of small kernels. On `Isaac-Velocity-Rough-AnymalD` (4096 environments), for example, the CPU was blocked 12.8 ms of a 25.4 ms step. - **Episode logging:** the command, termination, and curriculum managers, `survival_success_rate`, the pose commands, and task success rates (Cabinet, Locomotion, Lift deformable/cable, Fourbar) log 0-d device tensors instead of reading back `.item()`/`.cpu()` on every reset. `RewardManager` already logged tensors, and the RL wrappers accept them. Curriculum states are logged as copies, because rsl_rl keeps episode infos for a whole rollout. The inspection accessor `get_active_iterable_terms()` still returns Python scalars. - **Velocity command:** heading control is branchless (`torch.where`) instead of `is_heading_env.nonzero()` every step. Output is identical. - **Event ranges:** core and Lift event terms use `sample_uniform_from_ranges()` to draw named components directly. One private, bounded bounds cache replaces both sets of tensor-building helpers; it is keyed by values, resolved device, and dtype. Curriculum edits take effect on the next call, and every call draws fresh samples in the existing order. - **Ray caster:** `reset()` no longer uploads its range tensor or samples drift when the drift ranges are zero (the default). In rough locomotion this reset runs almost every step. When drift is disabled after sampling, reset clears the selected environments’ old drift. - **DiffIK:** the `if ee_quat.norm() != 0` guard in `apply_actions`, which synchronized every physics substep, is now a `torch.where` with the same all-or-nothing behavior. - **Direct tasks:** Reorient (about 14 host-list indexes per substep), Cabinet, and Locomotion store joint and body indices as device tensors, precompute static joint limits and default positions, and use the non-deprecated `actuators.target_command` API. - **Other task terms:** - Locomotion `walk_target_w` caches its device target (it synchronized 4 times per step). - Reorient's `EpisodeErrorRecorder` uses `torch.where` with NaN reductions instead of boolean masks. - Lift reset events share the named-range sampler with the core event terms. - **Joint limits:** Newton, PhysX, and OvPhysX position-limit writes reuse the clamping counter and read it back only when the resulting message would be logged. - **`RewardManager`:** each term writes its weighted value into a step-reward matrix column, followed by one sum and one batched episode-sum update. Reset is one mean and one fill. With 20 terms at 4096 environments, compute drops from 121 to 23 kernels (471 → 152 µs) and reset from 80 to 4 kernels (504 → 49 µs). - **`ObservationManager`:** the built-in noise functions (`constant_noise`, `gaussian_noise`, `uniform_noise`) are out-of-place, so the pre-noise clone and the second clone are skipped. Safe built-in noise functions are identified during `_prepare_terms`; custom noise functions, noise models, and modifiers still clone, including when a caller replaces a noise function after setup. The noise sampling order is unchanged. - **`CircularBuffer`:** one staged shift replaces K−1 slot copies for frames up to 2 MiB. Image-sized frames keep the slot loop, which is faster for them. - **Lift contacts:** one stacked norm replaces per-sensor norms. `contacts()` runs 5 times per step in Kuka Allegro, and this removes about 80 kernels per step. - **ANYmal symmetry augmentation:** one cached permutation and sign tensor per transform, bitwise-equal to the original, is 1.56 → 0.15 ms per call at 4096 environments. - **RTX renderer:** normals, motion vectors, `rgb_hdr`, and simple shading no longer copy each frame into a contiguous channel slice before reshaping. - **Smaller changes:** - Reorient reads its command slices directly instead of concatenating them. - sb3 computes `dones` on the host side. - **`NewtonManager.step()`** ran the solver-internals reset every physics step. `forward()` already performs it when kinematics are dirty, so the extra call only launched with an all-False mask. - **`WrenchComposer.reset()`** returns early when inactive. Its buffers are already zero, and this removes about 7 memsets per rigid object per physics step (21 µs → 0.07 µs per call). - **`SensorBase`:** sensors with `debug_vis=True` no longer refresh on every physics substep. That refresh existed because debug callbacks once read private data. The callbacks now refresh the outdated buffers themselves. The original eager update was introduced in commit `4565902f5` to make visualization work without a `data` read; it did not pump rendering. - **`VisualizationMarkers.visualize()`** returns early when no backend is active. - **Dead code:** removed the Newton Warp renderer's output copy loop (every output is a zero-copy alias), the impossible PhysX ray-caster guard, and the redundant Lift `body_state_b` index conversion (redundant since isaac-sim#8087). - **Newton `body_com_acc_w`:** the finite difference divided by the physics timestep even when an update spans several physics steps (Newton owning the decimation loop). That made the acceleration, and `body_lin_acc_l2`, `decimation`× too large. It now uses the elapsed time, matching `joint_acc`. The OvPhysX rigid-object implementation uses the same elapsed-time formula. PhysX and OvPhysX articulations read acceleration from the backend, so they do not need this finite-difference change. - **`reset_root_state_uniform`** built its range tensors in `__init__` and ignored call-time `pose_range`/`velocity_range`, so curriculum updates were silently dropped. - **Step reset, command resample, and interval-event `nonzero`:** these are now the only synchronizations left in `Isaac-Velocity-Rough-AnymalD`. Each converts a mask into variable-length environment IDs consumed across the reset, command, and event APIs. Removing them requires a mask-based API redesign and is left for a separate design. - **Needs a Kit trace before changing:** the PhysX IMU/PVA per-update COM upload, PhysX contact-sensor per-substep fetches, and the Fabric render synchronizations. They rely on PhysX/Fabric semantics we have not measured. A similar "pageable upload synchronizes" assumption proved false for the Newton sensor flags. - **Deferring the MPM sparse-grid status check:** a solver reset clears the status, so a deferred check could lose capacity errors, and no test covers this path. - **RMPflow guard:** it already runs on the host, so removing the guard gains nothing. The `joint_actions` allocation is needed for LEAPP export tracing. - **Lower confidence, left out:** collection mask-write kernels and batching model-change notifications. - Bug fix (non-breaking change which fixes an issue) - Behavior changes with migration notes in the changelog fragments: - Episode log values are 0-d tensors; use `float()` or `.item()` where a Python number is needed. - Reorient direct index attributes (`actuated_dof_indices`, `finger_bodies`, `finger_wrench_bodies`) and `resolve_actuated_tendons` ids are tensors. - `EpisodeErrorRecorder` reports NaN for an empty selection after its first update. - Custom sensors should refresh their buffers inside `_debug_vis_callback`. RTX PRO 6000 Blackwell Workstation Edition (driver 595.91.07); PyTorch 2.12.0+cu130; Warp 1.17.0; Newton 1.6.0; GPU otherwise idle. `develop` at `60bc09f17` compared with this PR on that base, with the same `uv.lock`. The branch has since merged `develop` at `f25d3f09b` (isaac-sim#8042, changes the Kuka camera observations and isaac-sim#8090 touches the simulation context, so they have not been re-measured on the merged branch or after review fixes. Static Lift success markers now resend positions to support late backend activation; the earlier marker-index-only optimization is not included. Runtime benchmark (`isaaclab benchmark runtime`), Newton/MJWarp, seed 42, no visualizer. Three fresh processes per revision, run in alternating order. Figures are the mean step time across processes; every workload's per-process ranges are disjoint. | Workload | `develop` | This PR | Change | | --- | ---: | ---: | ---: | | `Isaac-Ant`, 4096 envs | 3.369 ms | 2.629 ms | **−22.0%** (+28.1% throughput) | | `Isaac-Open-Drawer-Franka-Direct`, 4096 envs | 11.106 ms | 10.100 ms | **−9.1%** (+10.0%) | | `Isaac-Reorient-Cube-Allegro-Direct`, 4096 envs | 27.114 ms | 25.221 ms | **−7.0%** (+7.5%) | | `Isaac-Velocity-Rough-AnymalD`, 4096 envs | 23.078 ms | 22.573 ms | −2.2% (+2.2%) | | `Isaac-Lift-KukaAllegro-Camera`, 256 envs, `presets=duo_camera,rgb128`, Newton renderer | 12.396 ms | 12.202 ms | −1.6% (+1.6%) | Per-process step times (`develop` → PR): - Ant: `3.367, 3.359, 3.382` → `2.639, 2.638, 2.611` ms. - Drawer: `11.113, 11.102, 11.104` → `10.099, 10.100, 10.100` ms. - Reorient: `27.136, 27.136, 27.070` → `25.217, 25.250, 25.197` ms. - AnymalD: `23.081, 23.050, 23.103` → `22.551, 22.568, 22.599` ms. - Camera: `12.389, 12.374, 12.424` → `12.373, 12.119, 12.113` ms. Host synchronizations per `env.step()`, attributed to call sites with PyTorch sync-debug mode over 170 steps: | Task | `develop` | This PR | Remaining | | --- | ---: | ---: | --- | | `Isaac-Velocity-Rough-AnymalD` | 6.75 | 3.00 | step reset, command resample, and interval-event `nonzero` | | `Isaac-Lift-KukaAllegro-Camera` | 2.11 | 2.04 | step reset and command resample `nonzero`; curriculum difficulty `.item()` (0.04 per step) | PyTorch labels sync-debug mode a prototype that does not detect every synchronization, and it does not see synchronizations issued by Warp, so these counts are lower bounds. - The shared sampling refactor passed 257 tests across the existing math, root-state event, and Lift configuration suites. The existing event test now checks exact seeded samples, key order, missing axes, fresh draws, range edits, and warm-cache CUDA synchronization. Eight standalone equivalence checks also passed across CPU/CUDA, float32/float64, and flat/nodal batch shapes. No new tests or test files were added. - Before the shared-sampler refactor, 205 focused tests passed, with each file run in its own process: curriculum, observation, reward, and termination managers; heading commands and mutable event ranges; DiffIK; wrench composition; ray-caster and sensor-base behavior; marker visualization; Lift and reorientation helpers; and the existing joint-limit tests on both PhysX and OvPhysX, on CPU and CUDA. Kit tests used the `isaacsim` extra, and OvPhysX used `ovphysx` with separate CPU/GPU processes. - Regression checks fail with the old curriculum accessor, stale drift, and static marker behavior restored. Mutations also turn the retained tests red for custom-noise aliasing, eager debug-visualization refreshes, partial reward reset corruption, and missing reorientation NaN statistics. - Applied the test-audit skill: seven standalone tests were consolidated into existing reward, wrench, reorientation, marker, ray-caster, sensor-update, and Lift tests. Synchronization tests run on CUDA instead of repeating the same bookkeeping on CPU. No new test functions or files were added in the review-fix commit. - Retained unique heading, curriculum snapshot, mutable-range, and ANYmal symmetry coverage: there is no equivalent existing owner test. The symmetry test checks the new permutation tables against the previous independent index-assignment formulation. - `uv run isaaclab -f` passed, including changelog checks against the actual PR base, and `git diff --check` passed. - The full test suite and training smoke runs have not been repeated on this revision; benchmark figures above describe the earlier measured revision. - [x] <!-- backport-active-release --> Backport this pull request to the active release branch after it merges into `develop` - [x] I have read and understood the contribution guidelines. - [x] I have run the pre-commit checks with `uv run --frozen isaaclab -f`. - [x] I have made corresponding changes to the documentation. - [x] I have added tests that prove the behavior and checked the regressions against the unfixed code. - [x] I have added a changelog fragment for every touched source package. - [x] My name already exists in `CONTRIBUTORS.md`. (cherry picked from commit cd91769)
Use the existing uv-backed `isaaclab --docs` command for current documentation on Windows and Linux. Add `isaaclab --docs_multi` for the multi-version build, remove the obsolete Windows batch script, and simplify `docs/README.md` to use the same commands on both platforms. Set an explicit Isaac Sim intersphinx inventory URL. The single-slash inventory URL returns 200; the double-slash URL reported in the issue returns 404. Add a Windows docs build check for PRs that change docs or the CLI. Documentation builds reuse the repository uv environment with the `dev` extra. Current builds clear HTML output and doctrees before running Sphinx. Missing multi-version redirect targets report an actionable CLI error. Fixes isaac-sim#5273. - Bug fix - Documentation update - Focused CLI tests with uv-managed Python — 9 passed. Covered current output/cache cleanup, `--docs_multi` dispatch, redirect generation and ref override, and missing-ref failure. - Full local current-documentation Sphinx build passed without warnings using the existing uv-managed environment. The corrected deprecated-material link was verified in rendered HTML. - Repository formatting and lint hooks passed. Changelog fragments passed against the upstream base; the fork's local `origin/develop` is stale. - Windows build is covered by the PR workflow and will run on this update. - [x] <!-- backport-active-release --> Backport this pull request to the active release branch after it merges into `develop` (cherry picked from commit c1a8bfa)
|
run-ci |
|
| template = (docs_dir / "_redirect" / "index.html").read_text(encoding="utf-8") | ||
| (out_dir / "index.html").write_text(template.replace("__DOCS_DEFAULT_REF__", default_ref), encoding="utf-8") |
There was a problem hiding this comment.
Redirect targets the wrong version
When isaaclab --docs_multi builds the default v3.0.0-EA ref or a ref selected through DOCS_DEFAULT_REF, this replacement does nothing: the checked-in template contains ./main/index.html, not __DOCS_DEFAULT_REF__. The target check can pass while the generated redirect still sends readers to main, or to a missing page if main was not built. The existing Makefile rewrites the actual URL; the new test instead uses a template with the placeholder.
| if MARKER_RE.match(path.name): | ||
| return [] |
There was a problem hiding this comment.
Marker content is silently discarded
The gate accepts a nonempty .skip, .minor, or .major file without checking its contents. These files are meant to be empty, and Towncrier hides their contents, so a contributor who puts release-note text in one gets a passing check but loses that note during compilation. Reject nonempty markers to make the mistake visible.
| if not re.search(r"^\s*\*", text, re.MULTILINE): | ||
| return "has no ``* `` bullet" | ||
| if re.search(r"^(?!\*|\s|$)", text, re.MULTILINE): | ||
| return "has a line that is neither a ``* `` bullet nor an indented continuation" | ||
| return None |
There was a problem hiding this comment.
Orphan paragraphs pass validation
A fragment can start with an indented paragraph and place a bullet later: the first check finds that bullet, while the second accepts the earlier indented line as a continuation. The PR gate therefore accepts content that is not a bullet list, leaving malformed RST for the nightly changelog. Only accept an indented continuation after a bullet.
There was a problem hiding this comment.
Isaac Lab Review Bot
The backport coherently integrates towncrier, hot-path optimizations, and the uv-backed documentation CLI, but it also introduces several immediate compatibility breaks without deprecation bridges. The release-specific multi-version redirect and marker-fragment validation also need correction, and the Windows workflow should follow the repository’s action-pinning convention.
- Design and architecture: The changelog check/compiler split, cached range tensors, batched reward updates, and cached ANYmal symmetry tables are coherent. However, the hot-path design transfers ownership obligations from framework boundaries to extension implementations: noise callbacks must now preserve inputs, and sensor debug callbacks must refresh buffers themselves. Those shifts affect established extension contracts and need a compatibility transition rather than immediate enforcement.
- API: The additive
isaaclab --docs_multi,command_build_docs(multi_version=...), andsample_uniform_from_rangesAPIs are consistent with surrounding interfaces. Existing API behavior changes are not additive: manager reset and logging values switch from floats to tensors, task index attributes andresolve_actuated_tendonsswitch from lists to tensors, headless marker visualization stops validating inputs, noise callbacks lose defensive copies, and sensor debug callbacks acquire a new refresh obligation. - Compatibility and deprecation: Breaking changes:
docs/make.batis removed without a forwarding wrapper; manager reset and task logging values change from Python floats to device tensors; configured noise callbacks now receive un-cloned observation storage; headlessVisualizationMarkers.visualizecalls no longer enforce the prior validation contract; externalSensorBasedebug-visualization implementations must refresh their own buffers; and public task index attributes plusresolve_actuated_tendonschange from lists to tensors. Changelog and documentation migration notes are present, but none of these changes has the required functional old-contract bridge, targeted warning, removal guidance, and transition coverage. - Implementation: The changelog rollback/staging flow, lock-pin checks, docs build cleanup, drift caching, reward batching, and circular-buffer shift paths were traced. Two concrete issues remain: the release branch’s redirect template hardcodes
./main/, so replacing__DOCS_DEFAULT_REF__is ineffective while the gate checks a different default target; and marker fragments matching.skip,.minor, or.majorare accepted even when non-empty, allowing hidden content to be silently discarded during compilation. - Style consistency: The Python naming, docstrings, helper placement, and surrounding implementation patterns are generally consistent. The new Windows documentation workflow uses the floating
actions/checkout@v6tag despite adjacent workflows—and the setup-uv step in the same file—pinning actions to reviewed commit SHAs. Pin checkout consistently. - Test quality: The changed tests provide distinct coverage for root-state range edits, noise ownership, reward batching and partial reset, drift clearing, lazy sensor visualization, marker behavior, circular-buffer shifts, renderer channel handling, and changelog compilation. Several tests currently codify the immediate breaking contracts rather than covering deprecation transitions. The docs redirect test supplies a placeholder template and therefore misses the release branch’s hardcoded
./main/template, while the changelog tests do not reject non-empty marker files.
Significant concerns. Posted 9 actionable findings inline.
Automated review; human maintainers own approval decisions.
| @@ -1,65 +0,0 @@ | |||
| @ECHO OFF | |||
There was a problem hiding this comment.
🟡 Warning · Compatibility — Windows docs entry point removed outright
Deleting docs/make.bat removes the documented make.bat current-docs and make.bat multi-docs entry points immediately; updating docs/README.md and the contribution guide is migration guidance, not a transition. Existing Windows scripts and contributor muscle memory break without notice. Keep a thin batch wrapper that forwards both targets to isaaclab --docs / --docs_multi and prints replacement and removal guidance for the deprecation window.
| for metric_name, metric_value in self.metrics.items(): | ||
| # compute the mean metric value | ||
| extras[metric_name] = torch.mean(metric_value[env_ids]).item() | ||
| extras[metric_name] = torch.mean(metric_value[env_ids]) |
There was a problem hiding this comment.
🟡 Warning · Compatibility — Reset metrics change from floats to tensors
CommandTerm.reset changes its annotated and actual return from dict[str, float] to device tensors, and the same swap lands in TerminationManager.reset, CurriculumManager.reset and the task extras["log"] writers. Consumers that serialize or apply float-only arithmetic to these values break with no compatibility path. Retain the scalar contract during deprecation and expose the sync-free tensor metrics under a separate key or API.
| # Noise callbacks must not modify their input, but may return borrowed storage. | ||
| if isinstance(term_cfg.noise, noise.NoiseCfg): | ||
| obs = term_cfg.noise.func(obs.clone(), term_cfg.noise) | ||
| obs = term_cfg.noise.func(obs, term_cfg.noise) |
There was a problem hiding this comment.
🟡 Warning · Compatibility — Noise callbacks lose defensive input copy
Dropping obs.clone() requires every configured NoiseCfg.func/NoiseModelCfg to leave its input untouched. An existing in-place callback (previously safe, and not forbidden by the old docstring) now writes into term-owned or asset-owned storage. The changelog marks this Breaking, but no transition exists: no warning on the old path and no opt-out. Keep the copy for the deprecation window while warning on mutation, or gate zero-copy behind explicit opt-in.
| if not self.is_visible(): | ||
| # If no backend consumes markers (e.g. headless) or markers are hidden, do not spend | ||
| # time normalizing or dispatching marker state. | ||
| if not self._backends or not self.is_visible(): |
There was a problem hiding this comment.
🟡 Warning · Compatibility — Headless visualize skips documented input validation
Returning before normalization when self._backends is empty means mismatched shapes and all-None calls now succeed silently in headless runs, although the docstring still documents ValueError for both. The same call then raises once a backend is active, making the failure contract depend on rendering configuration. Keep the inexpensive validation ahead of the backend early return and skip only the backend dispatch.
| # Update the buffers | ||
| if force_recompute or self._is_visualizing: | ||
| # Update the buffers; debug visualization refreshes lazily from its callback. | ||
| if force_recompute: |
There was a problem hiding this comment.
🟡 Warning · Compatibility — Debug visualization refresh moved to subclasses
update() no longer refreshes outdated buffers when debug_vis is enabled, so every sensor overriding the protected _debug_vis_callback must now call _update_outdated_buffers() itself. In-repo sensors were updated, but external sensors silently draw stale data with no warning or error. Preserve the eager refresh for the deprecation window, or refresh once before dispatching callbacks from the visualization registry.
| device: str, | ||
| position_limits: tuple[float, float], | ||
| ) -> tuple[list[int], torch.Tensor, torch.Tensor]: | ||
| ) -> tuple[torch.Tensor, torch.Tensor, torch.Tensor]: |
There was a problem hiding this comment.
🟡 Warning · Compatibility — Public index attributes change to tensors
resolve_actuated_tendons now returns a torch.Tensor instead of list[int], and the changelog documents the same switch for the public actuated_dof_indices, finger_bodies, finger_wrench_bodies, arm_joint_ids and finger_joint_ids attributes. Callers using list equality, membership, concatenation or serialization break immediately; a .tolist() note is migration guidance, not a bridge. Keep the list contracts and cache device tensors privately until a deprecation cycle completes.
| runs-on: windows-latest | ||
| timeout-minutes: 45 | ||
| steps: | ||
| - uses: actions/checkout@v6 |
There was a problem hiding this comment.
🔵 Suggestion · Style Consistency — Checkout action not pinned to SHA
Every other workflow pins actions to a commit SHA with a version comment (actions/checkout@de0fac2e... # v6 in changelog-check.yml), and the astral-sh/setup-uv step two lines below in this same file is pinned. Pin actions/checkout the same way instead of the floating @v6 tag so the action cannot drift outside reviewed changes.
| if multi_version: | ||
| default_ref = os.getenv("DOCS_DEFAULT_REF", "v3.0.0-EA") | ||
| run_command(cmd + ["sphinx-multiversion", ".", str(out_dir), "--jobs=auto"], cwd=docs_dir) | ||
| if not (out_dir / default_ref / "index.html").is_file(): |
There was a problem hiding this comment.
🔵 Suggestion · Implementation — Multi-version redirect gate may mismatch target
The new gate aborts unless DOCS_DEFAULT_REF (default v3.0.0-EA) was built, while the redirect is produced by substituting __DOCS_DEFAULT_REF__ in _redirect/index.html. On this branch that template still hardcodes ./main/, so the substitution is a no-op: a build with main present fails the gate, and a passing build still redirects elsewhere. Add the placeholder to the release template or default the ref to the hardcoded target.
| def check_fragment(path: Path) -> list[str]: | ||
| """Return the errors of one added fragment, named relative to the repository.""" | ||
| rel = path.relative_to(REPO_ROOT) | ||
| if MARKER_RE.match(path.name): |
There was a problem hiding this comment.
🔵 Suggestion · Implementation — Marker fragments accepted without empty-content check
check_fragment returns success for any name matching MARKER_RE without inspecting contents, but the contribution guide defines <slug>.skip, <slug>.minor and <slug>.major as empty files and the towncrier config hides them with showcontent = false. A contributor who writes bullets into a tier file passes the gate and loses the entry at compile time. Reject marker files with non-whitespace content.
Summary
Backports three
developPRs torelease/3.0.0, in merge order:The automatic backport failed for #8118 and #8105. For #8179, this supersedes the bot's draft:
Once merged, the nightly compiles
release/3.0.0again: it skips release branches withouttools/changelog/towncrier.toml.Description
Each PR is cherry-picked with
-x; every code file matches its source patch. Release-specific changes:ee99db6a820)CHANGELOG.rstconflict resolved as the marker line above the release entries.uv.lockunchanged: release's local package pins already match theirpyproject.toml.uv.lockpushed its conflict context past the 1.5M-character inference limit.cd917691992).github/workflows/build.yamlhunk: it edits theperformance-smokejob, whichrelease/3.0.0does not have. The bot's validation rejected this omission.cli.py'ssplit_legacy, keeping all 34 bullets; [Changelog] Compile changelog fragments with towncrier and keep uv.lock in sync #8118's check rejects the old format.c1a8bfa50b5)docs/make.bat; release held an older copy.docs/_redirect/index.htmlstill hardcodes./main/([CI] Prepare develop as repository and docs default #7767 is not on this branch), soisaaclab --docs_multiwrites that redirect unchanged, as release'smake multi-docsdoes.Type of change
isaaclabmajor bump)Validation
cli.py check release/3.0.0passes.tools/changelogtests: 18 passed.pre-commitover the range passes.cli.py compileon a scratch copy of this branch:isaaclab25.1.0 → 26.0.0 andisaaclab_tasks_experimental0.0.1 → 1.0.0uv.lockchanged in version lines onlyRelease backport
This PR targets the release branch; no additional backport is needed.
Checklist
pre-commitchecks on the changed filessource/<pkg>/changelog.d/for every touched package (carried from the source PRs; [Camera] Remove remaining hot-path host syncs and overhead [7B/7] #8105 and [Docs] Use uv CLI for Windows documentation builds #8179 converted to the new format)CONTRIBUTORS.mdor my name already exists there