diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md index 0202ae4a..3aeb0438 100644 --- a/.github/copilot-instructions.md +++ b/.github/copilot-instructions.md @@ -4,7 +4,7 @@ **ros2_medkit** is a ROS 2 diagnostics gateway that exposes ROS 2 system information via a RESTful HTTP API aligned with the **SOVD (Service-Oriented Vehicle Diagnostics)** specification. It models robots as a diagnostic entity tree: **Area -> Component -> App**, with optional **Function** groupings. -**Tech Stack**: C++17, ROS 2 Jazzy/Humble/Rolling, Ubuntu 24.04/22.04 +**Tech Stack**: C++17, ROS 2 Jazzy/Humble/Lyrical, Ubuntu 26.04/24.04/22.04 ## Package Structure @@ -294,7 +294,7 @@ Every code change must include corresponding tests. A feature without tests is n - **Flag** new `.cpp` source files under `src/core/` that aren't picked up by `gateway_core`'s `GLOB_RECURSE` source list, or new ROS-adapter `.cpp` files that aren't added to the `gateway_ros2` STATIC library target in CMakeLists.txt. - **Flag** any `#include ` or message-package include in a file under `core/` - the layer must stay middleware-neutral. The `gateway_core_purity` linter and `test_gateway_core_smoke` link test enforce this; do not paper over their failures. - **Flag** new test targets that don't link to `gateway_ros2` (the default), unless the test is intentionally a core-only smoke test linking `gateway_core` directly. -- **Flag** use of `ament_target_dependencies()` - use `medkit_target_dependencies()` instead (removed in Rolling). +- **Flag** use of `ament_target_dependencies()` - use `medkit_target_dependencies()` instead (deprecated in Kilted, removed in ament_cmake 2.8.5+ which Lyrical ships). - **Flag** direct `find_package(yaml-cpp)` or `find_package(httplib)` - use `medkit_find_yaml_cpp()` / `medkit_find_cpp_httplib()` for multi-distro compatibility. ### Documentation diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 9a34a9c3..ec26d728 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -15,8 +15,8 @@ jobs: include: - ros_distro: humble os_image: ubuntu:jammy - - ros_distro: rolling - os_image: ubuntu:noble + - ros_distro: lyrical + os_image: ubuntu:resolute container: image: ${{ matrix.os_image }} timeout-minutes: 60 @@ -58,11 +58,12 @@ jobs: fi source /opt/ros/${{ matrix.ros_distro }}/setup.bash rosdep update - # Linters (clang-tidy / clang-format) are gated to the Jazzy lint job - # in quality.yml, but multiple package.xml files still list them as - # . Their rosdep keys are not registered for noble - # (Rolling), which breaks rosdep install on that runner. Skip them - # on every distro this workflow targets - the linters never run here. + # Linters (clang-tidy / clang-format) only run in the Jazzy quality + # job (quality.yml). Multiple package.xml files still list them as + # , so we skip the rosdep keys here to keep build-and- + # test runners from pulling in linter packages they never use. Also + # defensive against transient binary-deb gaps on newly-released + # distros. rosdep install --from-paths src --ignore-src -y \ --skip-keys "ament_cmake_clang_tidy ament_cmake_clang_format" @@ -85,10 +86,11 @@ jobs: # FastRTPS 2.6 on Humble has a known use-after-free in the # discovery-teardown path (EDP::unpairWriterProxy) that segfaults # peer nodes when the gateway shuts down, so we force CycloneDDS - # there. Rolling + Jazzy ship a newer FastRTPS without that bug - # and hit a separate iceoryx-shared-memory crash under CycloneDDS - # during shutdown ("string capacity was zero for allocated data"), - # so on those distros we keep the default FastRTPS. + # there. Lyrical ships a newer FastRTPS without that bug and hits + # a separate iceoryx-shared-memory crash under CycloneDDS during + # shutdown ("string capacity was zero for allocated data"), so on + # Lyrical we keep the default FastRTPS. (Jazzy still uses + # CycloneDDS - see jazzy-test job below for its rationale.) RMW_IMPLEMENTATION: ${{ matrix.ros_distro == 'humble' && 'rmw_cyclonedds_cpp' || '' }} run: | source /opt/ros/${{ matrix.ros_distro }}/setup.bash diff --git a/.github/workflows/docker-publish.yml b/.github/workflows/docker-publish.yml index 8587fa30..8743b44d 100644 --- a/.github/workflows/docker-publish.yml +++ b/.github/workflows/docker-publish.yml @@ -18,7 +18,7 @@ jobs: strategy: fail-fast: false matrix: - ros_distro: [jazzy, humble, rolling] + ros_distro: [jazzy, humble, lyrical] steps: - name: Checkout repository diff --git a/.github/workflows/opcua-plugin.yml b/.github/workflows/opcua-plugin.yml index 9c321ad9..bfaf1399 100644 --- a/.github/workflows/opcua-plugin.yml +++ b/.github/workflows/opcua-plugin.yml @@ -43,9 +43,9 @@ jobs: os_image: ubuntu:jammy - ros_distro: jazzy os_image: ubuntu:noble - - ros_distro: rolling - os_image: ubuntu:noble - continue-on-error: ${{ matrix.ros_distro == 'rolling' }} + - ros_distro: lyrical + os_image: ubuntu:resolute + continue-on-error: ${{ matrix.ros_distro == 'lyrical' }} container: image: ${{ matrix.os_image }} timeout-minutes: 60 @@ -84,8 +84,8 @@ jobs: source /opt/ros/${{ matrix.ros_distro }}/setup.bash rosdep update # Skip nav2_msgs (vda5050_agent declares it; not available on all - # distros) and the linter rosdep keys. The clang_format / clang_tidy - # keys are not registered for noble (Rolling), and the upstream + # distros) and the linter rosdep keys. Linters only run in the Jazzy + # quality job, so we don't need them installed here. The upstream # medkit packages have already been switched to QUIET + FOUND for # those find_package calls so the build degrades gracefully without # the linter packages installed. diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index ad6b2093..deb93188 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -107,7 +107,7 @@ Open `coverage_html/index.html` in your browser. #### CI/CD -All PRs are tested on Ubuntu 24.04 (Jazzy) with parallel lint + test jobs, plus Humble and Rolling (allowed to fail). Coverage is uploaded to Codecov on push to main. All CI jobs use ccache. +All PRs are tested on Ubuntu 24.04 (Jazzy) with parallel lint + test jobs, plus Humble and Lyrical. Coverage is uploaded to Codecov on push to main. All CI jobs use ccache. ### Pull Request Checklist diff --git a/QUALITY_DECLARATION.md b/QUALITY_DECLARATION.md index 6b276e7c..984074fb 100644 --- a/QUALITY_DECLARATION.md +++ b/QUALITY_DECLARATION.md @@ -86,7 +86,7 @@ GitHub Copilot code review is used in addition to human review. All pull requests must pass CI before merging: -- **Build & Test job:** Full build + unit/integration tests on Ubuntu Noble / ROS 2 Jazzy, Ubuntu Jammy / ROS 2 Humble, and Ubuntu Noble / ROS 2 Rolling (best-effort, allow-failure). Linter tests on Jazzy only +- **Build & Test job:** Full build + unit/integration tests on Ubuntu Noble / ROS 2 Jazzy, Ubuntu Jammy / ROS 2 Humble, and Ubuntu Resolute / ROS 2 Lyrical. Linter tests on Jazzy only - **Coverage job:** Debug build with coverage. Reports are generated for all PRs as artifacts and uploaded to [Codecov](https://codecov.io/gh/selfpatch/ros2_medkit) on pushes to `main` - Linting enforced: `clang-format`, `clang-tidy` via `ament_lint_auto` @@ -203,9 +203,9 @@ Linter tests are enforced in CI on every pull request. - **Ubuntu 24.04 (Noble)** with **ROS 2 Jazzy** (primary) - **Ubuntu 22.04 (Jammy)** with **ROS 2 Humble** -- **Ubuntu 24.04 (Noble)** with **ROS 2 Rolling** (experimental, best-effort) +- **Ubuntu 26.04 (Resolute)** with **ROS 2 Lyrical** (newest LTS, released May 2026) -Jazzy and Humble are the Tier 1 platforms per [REP-2000](https://www.ros.org/reps/rep-2000.html) and are tested in CI. Rolling is tested as best-effort (allow-failure) for forward-compatibility. +Jazzy and Humble are Tier 1 LTS platforms per [REP-2000](https://www.ros.org/reps/rep-2000.html); Lyrical is the newest LTS (May 2026) and is also tested in CI. --- @@ -234,7 +234,7 @@ Security issues can be reported via GitHub Security Advisories on the | Feature tests | Met | 65 tests across unit + integration | | Coverage | Met | 75% line coverage | | Linting | Met | clang-format, clang-tidy, ament_lint | -| Platform support | Met | Ubuntu Noble / ROS 2 Jazzy + Ubuntu Jammy / ROS 2 Humble + Rolling (best-effort) | +| Platform support | Met | Ubuntu Noble / ROS 2 Jazzy + Ubuntu Jammy / ROS 2 Humble + Ubuntu Resolute / ROS 2 Lyrical | | Security policy | Met | REP-2006 compliant | **Caveat:** Version is 0.3.0 (pre-1.0.0, requirement 1.ii). The REST API is versioned (`/api/v1/`) diff --git a/README.md b/README.md index 92d02fab..6beacae4 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](LICENSE) [![ROS 2 Jazzy](https://img.shields.io/badge/ROS%202-Jazzy-blue)](https://docs.ros.org/en/jazzy/) [![ROS 2 Humble](https://img.shields.io/badge/ROS%202-Humble-blue)](https://docs.ros.org/en/humble/) -[![ROS 2 Rolling](https://img.shields.io/badge/ROS%202-Rolling-orange)](https://docs.ros.org/en/rolling/) +[![ROS 2 Lyrical](https://img.shields.io/badge/ROS%202-Lyrical-blue)](https://docs.ros.org/en/lyrical/) [![Discord](https://img.shields.io/badge/Discord-Join%20Us-7289DA?logo=discord&logoColor=white)](https://discord.gg/6CXPMApAyq) [![Quality Level 3](https://img.shields.io/badge/Quality-Level%203-yellow)](QUALITY_DECLARATION.md) @@ -42,7 +42,7 @@ cd selfpatch_demos/demos/turtlebot3_integration Open `http://localhost:3000` in your browser. You will see a TurtleBot3 with Nav2, organized into a browsable entity tree with live faults, topic data, and parameter access. -**Build from source** (ROS 2 Jazzy, Humble, or Rolling): +**Build from source** (ROS 2 Jazzy, Humble, or Lyrical): ```bash source /opt/ros/jazzy/setup.bash # or humble - adjust for your distro @@ -148,8 +148,8 @@ This entity model follows the **SOVD (Service-Oriented Vehicle Diagnostics)** st ## 📋 Requirements -- **OS:** Ubuntu 24.04 LTS (Jazzy / Rolling) or Ubuntu 22.04 LTS (Humble) -- **ROS 2:** Jazzy Jalisco, Humble Hawksbill, or Rolling (experimental) +- **OS:** Ubuntu 26.04 LTS (Resolute, for Lyrical), Ubuntu 24.04 LTS (Noble, for Jazzy), or Ubuntu 22.04 LTS (Jammy, for Humble) +- **ROS 2:** Jazzy Jalisco, Humble Hawksbill, or Lyrical Luth (LTS, released May 2026) - **Compiler:** GCC 11+ (C++17 support) - **Build System:** colcon + ament_cmake diff --git a/docs/installation.rst b/docs/installation.rst index d5993934..80626094 100644 --- a/docs/installation.rst +++ b/docs/installation.rst @@ -2,7 +2,7 @@ Installation ============ This guide covers installation of ros2_medkit on Ubuntu 24.04 with ROS 2 Jazzy, -Ubuntu 22.04 with ROS 2 Humble, or Ubuntu 24.04 with ROS 2 Rolling. +Ubuntu 22.04 with ROS 2 Humble, or Ubuntu 26.04 with ROS 2 Lyrical. System Requirements ------------------- @@ -14,25 +14,25 @@ System Requirements * - Requirement - Version * - Operating System - - Ubuntu 24.04 LTS (Noble) or Ubuntu 22.04 LTS (Jammy) + - Ubuntu 26.04 LTS (Resolute), Ubuntu 24.04 LTS (Noble), or Ubuntu 22.04 LTS (Jammy) * - ROS 2 Distribution - - Jazzy, Humble, or Rolling + - Jazzy, Humble, or Lyrical * - C++ Compiler - GCC 11+ (C++17 support required) * - CMake - 3.22+ * - Python - - 3.10+ (Humble) / 3.12+ (Jazzy / Rolling) + - 3.10+ (Humble) / 3.12+ (Jazzy) / 3.14+ (Lyrical) Prerequisites ------------- -**ROS 2 Jazzy, Humble, or Rolling** must be installed and sourced. Follow the official installation guide +**ROS 2 Jazzy, Humble, or Lyrical** must be installed and sourced. Follow the official installation guide for your distribution: - Jazzy: https://docs.ros.org/en/jazzy/Installation/Ubuntu-Install-Debs.html - Humble: https://docs.ros.org/en/humble/Installation/Ubuntu-Install-Debs.html -- Rolling: https://docs.ros.org/en/rolling/Installation/Ubuntu-Install-Debs.html +- Lyrical: https://docs.ros.org/en/lyrical/Installation/Ubuntu-Install-Debs.html .. note:: @@ -136,8 +136,8 @@ ROS 2 distributions: # Humble docker run -p 8080:8080 ghcr.io/selfpatch/ros2_medkit-humble:latest - # Rolling - docker run -p 8080:8080 ghcr.io/selfpatch/ros2_medkit-rolling:latest + # Lyrical + docker run -p 8080:8080 ghcr.io/selfpatch/ros2_medkit-lyrical:latest The gateway will be available at http://localhost:8080/api/v1/health. diff --git a/docs/troubleshooting.rst b/docs/troubleshooting.rst index 29bddb6c..5f5057b1 100644 --- a/docs/troubleshooting.rst +++ b/docs/troubleshooting.rst @@ -219,7 +219,7 @@ parameter changes) only happen when explicitly requested via the API. **Q: Can I use ros2_medkit with ROS 1?** -No. ros2_medkit requires ROS 2 (Jazzy, Humble, or Rolling). For ROS 1 systems, consider using +No. ros2_medkit requires ROS 2 (Jazzy, Humble, or Lyrical). For ROS 1 systems, consider using the ``ros1_bridge`` and running ros2_medkit on the ROS 2 side. **Q: Is ros2_medkit production-ready?** diff --git a/docs/tutorials/docker.rst b/docs/tutorials/docker.rst index 62924868..61cbf9fb 100644 --- a/docs/tutorials/docker.rst +++ b/docs/tutorials/docker.rst @@ -33,8 +33,8 @@ Images are available for all supported ROS 2 distributions: - ``ghcr.io/selfpatch/ros2_medkit-jazzy:latest`` * - Humble - ``ghcr.io/selfpatch/ros2_medkit-humble:latest`` - * - Rolling - - ``ghcr.io/selfpatch/ros2_medkit-rolling:latest`` + * - Lyrical + - ``ghcr.io/selfpatch/ros2_medkit-lyrical:latest`` Each image includes the gateway and all open-core packages: diff --git a/docs/tutorials/plugin-system.rst b/docs/tutorials/plugin-system.rst index 00195619..eb0289cf 100644 --- a/docs/tutorials/plugin-system.rst +++ b/docs/tutorials/plugin-system.rst @@ -271,7 +271,7 @@ providing access to gateway data and utilities: ``create_generic_subscription()``, or ``create_callback_group()`` directly on this node. Issue #375 showed that concurrent rcl mutations on the gateway node race its internal hash map and - SIGSEGV under load on Rolling. The regression gate in + SIGSEGV under load on Rolling/Lyrical. The regression gate in ``scripts/check_no_naked_subscriptions.sh`` is run in CI and will fail PRs that add such calls outside the allowlist. Use ``ros2_medkit_gateway::ros2_common::Ros2SubscriptionSlot::create_typed`` diff --git a/scripts/check_no_naked_subscriptions.sh b/scripts/check_no_naked_subscriptions.sh index 38f0309a..57c64296 100755 --- a/scripts/check_no_naked_subscriptions.sh +++ b/scripts/check_no_naked_subscriptions.sh @@ -5,7 +5,8 @@ # callback-group creation APIs from gateway and fault_manager code outside # `ros2_common/` is forbidden because it bypasses Ros2SubscriptionExecutor's # serial worker (or fault_manager's LockedSubscriptionGuard) and reintroduces -# the rcl hash-map race that triggered SIGSEGV on Rolling. +# the rcl hash-map race that triggered SIGSEGV on Rolling (still applicable +# on Lyrical and any future distro that ships the same rcl hash-map code). # # Callers in the gateway must go through: # ros2_medkit_gateway::ros2_common::Ros2SubscriptionSlot::create_typed / create_generic diff --git a/src/ros2_medkit_cmake/README.md b/src/ros2_medkit_cmake/README.md index 7f5bb502..8d2052f6 100644 --- a/src/ros2_medkit_cmake/README.md +++ b/src/ros2_medkit_cmake/README.md @@ -9,7 +9,7 @@ build acceleration, and centralized linting configuration across all packages. |--------|-------------| | `ROS2MedkitCcache.cmake` | Auto-detect and configure ccache with PCH-aware sloppiness settings | | `ROS2MedkitLinting.cmake` | Centralized clang-tidy configuration (opt-in locally, mandatory in CI) | -| `ROS2MedkitCompat.cmake` | Multi-distro compatibility shims for ROS 2 Humble, Jazzy, and Rolling | +| `ROS2MedkitCompat.cmake` | Multi-distro compatibility shims for ROS 2 Humble, Jazzy, and Lyrical | ### ROS2MedkitCompat @@ -17,7 +17,7 @@ Resolves dependency differences across ROS 2 distributions: - `medkit_find_yaml_cpp()` - Finds yaml-cpp (namespaced targets on Jazzy, manual fallback on Humble) - `medkit_find_cpp_httplib()` - Finds cpp-httplib >= 0.14 via pkg-config, CMake config, or vendored fallback (`VENDORED_DIR` param) -- `medkit_target_dependencies()` - Drop-in replacement for `ament_target_dependencies` (removed on Rolling) +- `medkit_target_dependencies()` - Drop-in replacement for `ament_target_dependencies` (removed on Lyrical) - `medkit_detect_compat_defs()` / `medkit_apply_compat_defs()` - Compile definitions for version-specific APIs ## Usage diff --git a/src/ros2_medkit_cmake/cmake/ROS2MedkitCompat.cmake b/src/ros2_medkit_cmake/cmake/ROS2MedkitCompat.cmake index bcb7f5c8..e5f93460 100644 --- a/src/ros2_medkit_cmake/cmake/ROS2MedkitCompat.cmake +++ b/src/ros2_medkit_cmake/cmake/ROS2MedkitCompat.cmake @@ -17,7 +17,7 @@ # ============================================================================= # # Centralizes all dependency resolution workarounds for supporting multiple -# ROS 2 distributions (Humble, Jazzy, Rolling) in a single place. +# ROS 2 distributions (Humble, Jazzy, Lyrical) in a single place. # # Usage (in each package's CMakeLists.txt): # find_package(ros2_medkit_cmake REQUIRED) @@ -31,7 +31,7 @@ # medkit_target_dependencies(target ...) - Drop-in ament_target_dependencies replacement # # Variables set by medkit_detect_compat_defs(): -# MEDKIT_RCLCPP_VERSION_MAJOR — integer (e.g., 16 for Humble, 28 for Jazzy) +# MEDKIT_RCLCPP_VERSION_MAJOR — integer (16=Humble, 28=Jazzy, 32+=Lyrical) # MEDKIT_ROSBAG2_OLD_TIMESTAMP — ON if rosbag2_storage < 0.22.0 (Humble) # @@ -40,9 +40,11 @@ include_guard(GLOBAL) # --------------------------------------------------------------------------- # medkit_find_yaml_cpp() # --------------------------------------------------------------------------- -# Jazzy's yaml_cpp_vendor exports a namespaced yaml-cpp::yaml-cpp cmake target. -# Humble's yaml_cpp_vendor bundles yaml-cpp but does NOT export the cmake target. -# This macro creates an IMPORTED INTERFACE target when find_package doesn't. +# Jazzy's and Lyrical's yaml_cpp_vendor export a namespaced yaml-cpp::yaml-cpp +# cmake target (Jazzy directly; Lyrical via its Findyaml-cpp.cmake module that +# aliases the upstream yaml-cpp 0.8+ target). Humble's yaml_cpp_vendor bundles +# yaml-cpp but does NOT export the cmake target. This macro creates an IMPORTED +# INTERFACE target when find_package doesn't. # # Prerequisite: find_package(yaml_cpp_vendor REQUIRED) must be called before. # --------------------------------------------------------------------------- @@ -72,14 +74,19 @@ endmacro() # --------------------------------------------------------------------------- # medkit_find_cpp_httplib() # --------------------------------------------------------------------------- -# Finds cpp-httplib >= 0.14 through a multi-tier fallback chain: +# Finds cpp-httplib in the [0.14, 0.20) range through a multi-tier fallback chain: # 1. pkg-config (Jazzy/Noble system package) # 2. cmake find_package(httplib) (source builds, Pixi) -# 3. VENDORED_DIR parameter (bundled header-only copy) +# 3. VENDORED_DIR parameter (bundled header-only copy, currently 0.14.3) # # On Humble/Jammy the system package is 0.10.x (too old); the vendored # fallback in ros2_medkit_gateway handles this automatically. # +# On Lyrical/Resolute the system package is 0.26.x which removed the +# multipart `Request::has_file` / `get_file_value` API used by +# BulkDataHandlers, so we cap pkg-config at < 0.20 and fall back to the +# vendored copy until the handler is migrated to the newer API. +# # Creates a unified alias target `cpp_httplib_target` for consumers. # --------------------------------------------------------------------------- macro(medkit_find_cpp_httplib) @@ -87,6 +94,13 @@ macro(medkit_find_cpp_httplib) find_package(PkgConfig QUIET) if(PkgConfig_FOUND) pkg_check_modules(cpp_httplib IMPORTED_TARGET cpp-httplib>=0.14) + if(cpp_httplib_FOUND AND cpp_httplib_VERSION VERSION_GREATER_EQUAL "0.20") + message(STATUS "[MedkitCompat] cpp-httplib: system package ${cpp_httplib_VERSION} removes the multipart Request::has_file API; falling back to vendored 0.14") + # `unset` in a macro does not clear caller-scope variables set by + # pkg_check_modules, so explicitly mask FOUND to redirect through the + # find_package / VENDORED_DIR fallback chain below. + set(cpp_httplib_FOUND FALSE) + endif() endif() if(cpp_httplib_FOUND) add_library(cpp_httplib_target ALIAS PkgConfig::cpp_httplib) @@ -120,7 +134,7 @@ endmacro() # Call AFTER find_package(rclcpp) and optionally find_package(rosbag2_storage). # # Sets: -# MEDKIT_RCLCPP_VERSION_MAJOR — integer (16=Humble, 21+=Iron, 28+=Jazzy) +# MEDKIT_RCLCPP_VERSION_MAJOR — integer (16=Humble, 21+=Iron, 28+=Jazzy, 32+=Lyrical) # MEDKIT_ROSBAG2_OLD_TIMESTAMP — ON if rosbag2_storage < 0.22.0 (Humble) # --------------------------------------------------------------------------- macro(medkit_detect_compat_defs) @@ -166,11 +180,14 @@ endfunction() # --------------------------------------------------------------------------- # medkit_target_dependencies(target [PUBLIC|PRIVATE|INTERFACE] dep1 dep2 ...) # --------------------------------------------------------------------------- -# Drop-in replacement for ament_target_dependencies that works on Rolling -# (where ament_target_dependencies was removed from ament_cmake). +# Drop-in replacement for ament_target_dependencies that works on Lyrical +# (ament_target_dependencies was deprecated in Kilted / ament_cmake 2.7.3 +# and removed in ament_cmake 2.8.5+, which Lyrical ships). # # On Humble/Jazzy: delegates to ament_target_dependencies (available). -# On Rolling: uses target_link_libraries with ${dep_TARGETS}. +# On Lyrical: uses target_link_libraries with ${dep_TARGETS}. +# The branch is selected at runtime via if(COMMAND ament_target_dependencies) +# so any future distro keeps working regardless of where the removal lands. # # When no visibility keyword (PUBLIC/PRIVATE/INTERFACE) is passed, the macro # uses the plain target_link_libraries signature. This avoids conflicts with @@ -185,7 +202,7 @@ macro(medkit_target_dependencies target) if(COMMAND ament_target_dependencies) ament_target_dependencies(${target} ${ARGN}) else() - # Rolling fallback: resolve dependency targets explicitly. + # Lyrical fallback: resolve dependency targets explicitly. # # CMake forbids mixing the "plain" and "keyword" (PUBLIC/PRIVATE/INTERFACE) # signatures of target_link_libraries on the same target. diff --git a/src/ros2_medkit_cmake/design/index.rst b/src/ros2_medkit_cmake/design/index.rst index 90741d3d..c21709c4 100644 --- a/src/ros2_medkit_cmake/design/index.rst +++ b/src/ros2_medkit_cmake/design/index.rst @@ -41,7 +41,7 @@ The package provides four CMake modules installed to the ament index: - ``medkit_find_cpp_httplib()`` - Finds cpp-httplib >= 0.14 via pkg-config, cmake config, or vendored fallback (``VENDORED_DIR`` param) - ``medkit_detect_compat_defs()`` - Detects rclcpp and rosbag2 versions, sets ``MEDKIT_RCLCPP_VERSION_MAJOR`` and ``MEDKIT_ROSBAG2_OLD_TIMESTAMP`` - ``medkit_apply_compat_defs(target)`` - Applies compile definitions based on detected versions - - ``medkit_target_dependencies(target ...)`` - Drop-in replacement for ``ament_target_dependencies`` that also works on Rolling (where ``ament_target_dependencies`` was removed) + - ``medkit_target_dependencies(target ...)`` - Drop-in replacement for ``ament_target_dependencies`` that also works on Lyrical (where ``ament_target_dependencies`` was removed) Design Decisions ---------------- @@ -60,5 +60,5 @@ Multi-Distro Strategy Rather than maintaining separate branches per ROS 2 distribution, the compat module detects version numbers at configure time and adapts. This keeps a single -source tree building on Humble, Jazzy, and Rolling without ``#ifdef`` proliferation +source tree building on Humble, Jazzy, and Lyrical without ``#ifdef`` proliferation in application code. diff --git a/src/ros2_medkit_discovery_plugins/ros2_medkit_beacon_common/CMakeLists.txt b/src/ros2_medkit_discovery_plugins/ros2_medkit_beacon_common/CMakeLists.txt index b30e4190..28936579 100644 --- a/src/ros2_medkit_discovery_plugins/ros2_medkit_beacon_common/CMakeLists.txt +++ b/src/ros2_medkit_discovery_plugins/ros2_medkit_beacon_common/CMakeLists.txt @@ -79,9 +79,9 @@ if(BUILD_TESTING) ) ament_lint_auto_find_test_dependencies() - # ci.yml skips the ament_cmake_clang_format rosdep key on Humble + Rolling - # (linters only run in the Jazzy quality job), so QUIET + FOUND check - # avoids hard-failing on those runners. + # ci.yml skips the ament_cmake_clang_format rosdep key in the build-and-test + # job (linters only run in the Jazzy quality job), so QUIET + FOUND check + # avoids hard-failing when the package is not installed. find_package(ament_cmake_clang_format QUIET) if(ament_cmake_clang_format_FOUND) file(GLOB_RECURSE _format_files diff --git a/src/ros2_medkit_discovery_plugins/ros2_medkit_param_beacon/CMakeLists.txt b/src/ros2_medkit_discovery_plugins/ros2_medkit_param_beacon/CMakeLists.txt index 556edce5..68d04f6b 100644 --- a/src/ros2_medkit_discovery_plugins/ros2_medkit_param_beacon/CMakeLists.txt +++ b/src/ros2_medkit_discovery_plugins/ros2_medkit_param_beacon/CMakeLists.txt @@ -65,9 +65,9 @@ if(BUILD_TESTING) ) ament_lint_auto_find_test_dependencies() - # ci.yml skips the ament_cmake_clang_format rosdep key on Humble + Rolling - # (linters only run in the Jazzy quality job), so QUIET + FOUND check - # avoids hard-failing on those runners. + # ci.yml skips the ament_cmake_clang_format rosdep key in the build-and-test + # job (linters only run in the Jazzy quality job), so QUIET + FOUND check + # avoids hard-failing when the package is not installed. find_package(ament_cmake_clang_format QUIET) if(ament_cmake_clang_format_FOUND) file(GLOB_RECURSE _format_files diff --git a/src/ros2_medkit_discovery_plugins/ros2_medkit_param_beacon/src/param_beacon_plugin.cpp b/src/ros2_medkit_discovery_plugins/ros2_medkit_param_beacon/src/param_beacon_plugin.cpp index 93f2d87e..a00dc5ff 100644 --- a/src/ros2_medkit_discovery_plugins/ros2_medkit_param_beacon/src/param_beacon_plugin.cpp +++ b/src/ros2_medkit_discovery_plugins/ros2_medkit_param_beacon/src/param_beacon_plugin.cpp @@ -35,9 +35,10 @@ using ros2_medkit_gateway::PluginContext; using ros2_medkit_gateway::SovdEntityType; ParameterBeaconPlugin::~ParameterBeaconPlugin() noexcept { - // On Rolling, ~rclcpp::Node can throw graph_listener::NodeNotFoundError - // once rclcpp::shutdown() has invalidated the context. An exception - // escaping a destructor calls std::terminate(), so swallow it here. + // On Lyrical (originally observed on Rolling), ~rclcpp::Node can throw + // graph_listener::NodeNotFoundError once rclcpp::shutdown() has invalidated + // the context. An exception escaping a destructor calls std::terminate(), + // so swallow it here. try { shutdown(); } catch (...) { @@ -157,8 +158,8 @@ void ParameterBeaconPlugin::shutdown() { backoff_counts_.clear(); skip_remaining_.clear(); } - // ~rclcpp::Node can throw graph_listener::NodeNotFoundError on Rolling - // when the context was already torn down by rclcpp::shutdown(). Swallow + // ~rclcpp::Node can throw graph_listener::NodeNotFoundError on Lyrical + // (and Rolling) when the context was already torn down by rclcpp::shutdown(). Swallow // it so the plugin_manager shutdown sequence (and the plugin destructor // that calls back into us) does not abort the process. try { diff --git a/src/ros2_medkit_discovery_plugins/ros2_medkit_topic_beacon/CMakeLists.txt b/src/ros2_medkit_discovery_plugins/ros2_medkit_topic_beacon/CMakeLists.txt index b20a45ef..a9deaddf 100644 --- a/src/ros2_medkit_discovery_plugins/ros2_medkit_topic_beacon/CMakeLists.txt +++ b/src/ros2_medkit_discovery_plugins/ros2_medkit_topic_beacon/CMakeLists.txt @@ -71,9 +71,9 @@ if(BUILD_TESTING) ) ament_lint_auto_find_test_dependencies() - # ci.yml skips the ament_cmake_clang_format rosdep key on Humble + Rolling - # (linters only run in the Jazzy quality job), so QUIET + FOUND check - # avoids hard-failing on those runners. + # ci.yml skips the ament_cmake_clang_format rosdep key in the build-and-test + # job (linters only run in the Jazzy quality job), so QUIET + FOUND check + # avoids hard-failing when the package is not installed. find_package(ament_cmake_clang_format QUIET) if(ament_cmake_clang_format_FOUND) file(GLOB_RECURSE _format_files diff --git a/src/ros2_medkit_discovery_plugins/ros2_medkit_topic_beacon/src/topic_beacon_plugin.cpp b/src/ros2_medkit_discovery_plugins/ros2_medkit_topic_beacon/src/topic_beacon_plugin.cpp index aa8ce05a..c133cb9c 100644 --- a/src/ros2_medkit_discovery_plugins/ros2_medkit_topic_beacon/src/topic_beacon_plugin.cpp +++ b/src/ros2_medkit_discovery_plugins/ros2_medkit_topic_beacon/src/topic_beacon_plugin.cpp @@ -33,9 +33,10 @@ using ros2_medkit_gateway::PluginContext; using ros2_medkit_gateway::SovdEntityType; TopicBeaconPlugin::~TopicBeaconPlugin() noexcept { - // On Rolling, ~rclcpp::Subscription can throw graph_listener::NodeNotFoundError - // once rclcpp::shutdown() has invalidated the context. An exception - // escaping a destructor calls std::terminate(), so swallow it here. + // On Lyrical (originally observed on Rolling), ~rclcpp::Subscription can throw + // graph_listener::NodeNotFoundError once rclcpp::shutdown() has invalidated + // the context. An exception escaping a destructor calls std::terminate(), + // so swallow it here. try { shutdown(); } catch (...) { @@ -113,9 +114,9 @@ void TopicBeaconPlugin::shutdown() { if (shutdown_requested_.exchange(true)) { return; } - // ~rclcpp::Subscription can throw on Rolling when the rclcpp context - // was torn down before us; swallow so plugin_manager shutdown and the - // plugin destructor calling back into us do not abort the process. + // ~rclcpp::Subscription can throw on Lyrical (and Rolling) when the rclcpp + // context was torn down before us; swallow so plugin_manager shutdown and + // the plugin destructor calling back into us do not abort the process. try { subscription_.reset(); } catch (...) { diff --git a/src/ros2_medkit_fault_manager/src/snapshot_capture.cpp b/src/ros2_medkit_fault_manager/src/snapshot_capture.cpp index f833053d..625d0c04 100644 --- a/src/ros2_medkit_fault_manager/src/snapshot_capture.cpp +++ b/src/ros2_medkit_fault_manager/src/snapshot_capture.cpp @@ -44,9 +44,9 @@ struct LockedSubscriptionGuard { // C++20 [dcl.init.aggr] disqualifies a class as an aggregate if it has // any user-declared constructors, including ``= delete`` ones (the rule // tightened from "user-provided" in C++17 to "user-declared" in C++20). - // Rolling's gcc 14 / libstdc++ enforces the C++20 wording even when + // Lyrical's gcc 15 / libstdc++ enforces the C++20 wording even when // CMAKE_CXX_STANDARD is 17, so brace-init ``LockedSubscriptionGuard{ - // &mtx, sub, cg}`` would fail to find a matching constructor on rolling. + // &mtx, sub, cg}`` would fail to find a matching constructor on Lyrical. // An explicit constructor sidesteps the aggregate-init rules entirely. LockedSubscriptionGuard(std::mutex * m, rclcpp::GenericSubscription::SharedPtr s, rclcpp::CallbackGroup::SharedPtr cg) : mtx(m), subscription(std::move(s)), callback_group(std::move(cg)) { diff --git a/src/ros2_medkit_gateway/CMakeLists.txt b/src/ros2_medkit_gateway/CMakeLists.txt index 171a5c09..5bbf59df 100644 --- a/src/ros2_medkit_gateway/CMakeLists.txt +++ b/src/ros2_medkit_gateway/CMakeLists.txt @@ -317,7 +317,7 @@ if(BUILD_TESTING) # Configure clang-format to only check our source files (not vendored). # ament_cmake_clang_format is intentionally only installed in the Jazzy - # quality job (ci.yml skips its rosdep key on Humble + Rolling), so use + # quality job (ci.yml skips its rosdep key in the build-and-test job), so use # QUIET + FOUND check instead of REQUIRED to gracefully degrade on the # build-and-test runners without breaking the build. find_package(ament_cmake_clang_format QUIET) diff --git a/src/ros2_medkit_gateway/README.md b/src/ros2_medkit_gateway/README.md index db7203a1..d9f79603 100644 --- a/src/ros2_medkit_gateway/README.md +++ b/src/ros2_medkit_gateway/README.md @@ -1592,7 +1592,7 @@ All rcl subscription create/destroy calls must go through `Ros2SubscriptionSlot::create_typed` / `create_generic` (defined in `ros2_common/`). Calling `node->create_subscription()`, `create_generic_subscription()`, or `create_callback_group()` anywhere -else triggers the race from issue #375 and SIGSEGVs on Rolling under +else triggers the race from issue #375 and SIGSEGVs on Rolling/Lyrical under concurrent HTTP load. The regression gate is `scripts/check_no_naked_subscriptions.sh`. It diff --git a/src/ros2_medkit_gateway/design/ros2_subscription_architecture.rst b/src/ros2_medkit_gateway/design/ros2_subscription_architecture.rst index 918c95a6..df2dc0e1 100644 --- a/src/ros2_medkit_gateway/design/ros2_subscription_architecture.rst +++ b/src/ros2_medkit_gateway/design/ros2_subscription_architecture.rst @@ -8,9 +8,10 @@ The gateway's original ``NativeTopicSampler`` created a short-lived ``rclcpp::GenericSubscription`` for every ``/data`` sample call. Under concurrent HTTP load, multiple cpp-httplib handler threads invoked ``Node::create_generic_subscription()`` on the same node, racing inside rcl's -internal hash map and corrupting its linked entries. The symptom was a Rolling -SIGSEGV in ``test_data_read`` (issue #375) and intermittent non-deterministic -crashes on sample-heavy deployments. +internal hash map and corrupting its linked entries. The symptom was a SIGSEGV +in ``test_data_read`` (issue #375, first reproduced on the Rolling distro that +later became Lyrical) and intermittent non-deterministic crashes on sample-heavy +deployments. This document describes the replacement architecture: a single-writer subscription executor, a RAII slot handle, and a per-topic pool. @@ -92,7 +93,7 @@ Public API (summary): Graph change detection uses the public ``rclcpp::Node::get_graph_event()`` API and a wall timer polling ``event->check_and_clear()`` on the subscription node. Internal ``GraphListener`` is intentionally avoided - it is not a stable -public API across Humble / Jazzy / Rolling. +public API across Humble / Jazzy / Lyrical. Shutdown drains the queue: the worker processes any already-enqueued tasks so pending ``run_sync`` promises are fulfilled before the worker exits. Bounded @@ -226,8 +227,8 @@ executor:: node.reset(); // ~GatewayNode with executor still alive rclcpp::shutdown(); -``remove_node`` + explicit ``node.reset()`` are required on rolling / newer -jazzy: rclcpp aborts with ``Node ... needs to be associated with an executor`` +``remove_node`` + explicit ``node.reset()`` are required on Lyrical / newer +Jazzy: rclcpp aborts with ``Node ... needs to be associated with an executor`` if ``~GatewayNode`` touches a service client while stack-unwind has already destroyed the executor. diff --git a/src/ros2_medkit_gateway/include/ros2_medkit_gateway/compat/generic_client_compat.hpp b/src/ros2_medkit_gateway/include/ros2_medkit_gateway/compat/generic_client_compat.hpp index e095b38c..a7a704ef 100644 --- a/src/ros2_medkit_gateway/include/ros2_medkit_gateway/compat/generic_client_compat.hpp +++ b/src/ros2_medkit_gateway/include/ros2_medkit_gateway/compat/generic_client_compat.hpp @@ -32,7 +32,7 @@ #include // Detect whether rclcpp::GenericClient is available. -// rclcpp/version.h exists in all supported distros (Humble, Jazzy, Rolling). +// rclcpp/version.h exists in all supported distros (Humble, Jazzy, Lyrical). #include #if defined(RCLCPP_VERSION_MAJOR) && RCLCPP_VERSION_MAJOR >= 21 diff --git a/src/ros2_medkit_gateway/include/ros2_medkit_gateway/ros2_common/ros2_subscription_executor.hpp b/src/ros2_medkit_gateway/include/ros2_medkit_gateway/ros2_common/ros2_subscription_executor.hpp index aec60187..6cc7a240 100644 --- a/src/ros2_medkit_gateway/include/ros2_medkit_gateway/ros2_common/ros2_subscription_executor.hpp +++ b/src/ros2_medkit_gateway/include/ros2_medkit_gateway/ros2_common/ros2_subscription_executor.hpp @@ -303,7 +303,7 @@ class Ros2SubscriptionExecutor final { std::array graph_in_flight_{}; std::condition_variable graph_in_flight_cv_; - // Public rclcpp graph API - stable across Humble / Jazzy / Rolling + // Public rclcpp graph API - stable across Humble / Jazzy / Lyrical rclcpp::Event::SharedPtr graph_event_; // Dedicated auxiliary thread driving the watchdog and graph-event polling. diff --git a/src/ros2_medkit_gateway/src/main.cpp b/src/ros2_medkit_gateway/src/main.cpp index 06e64e94..b28f68b5 100644 --- a/src/ros2_medkit_gateway/src/main.cpp +++ b/src/ros2_medkit_gateway/src/main.cpp @@ -80,7 +80,7 @@ int main(int argc, char ** argv) { // Stand up the ROS 2 subscription executor + topic data provider. // Issue #375: all subscription create/destroy calls are funneled through the // serial worker owned by sub_exec, eliminating the rcl hash-map race that - // previously killed /data on Rolling when concurrent HTTP handler threads + // previously killed /data on Rolling (now Lyrical) when concurrent HTTP handler threads // created subscriptions on the same node. const auto exec_cfg = declare_executor_config(*node); const auto dp_cfg = declare_data_provider_config(*node); @@ -104,7 +104,7 @@ int main(int argc, char ** argv) { // Teardown order (issue #375): stack-unwind destructs executor before node // which leaves ~GatewayNode running against a dead executor. Newer rclcpp - // (rolling; recent jazzy patch releases) asserts 'node needs to be + // (Lyrical; recent Jazzy patch releases) asserts 'node needs to be // associated with an executor' and aborts with exit -6 when the managers' // shutdown paths touch service clients. Explicit teardown avoids that: // 1. detach the provider from GatewayNode so the managers stop using it diff --git a/src/ros2_medkit_gateway/test/test_data_access_manager_routing.cpp b/src/ros2_medkit_gateway/test/test_data_access_manager_routing.cpp index 050dc152..e414953e 100644 --- a/src/ros2_medkit_gateway/test/test_data_access_manager_routing.cpp +++ b/src/ros2_medkit_gateway/test/test_data_access_manager_routing.cpp @@ -16,6 +16,7 @@ #include #include +#include #include #include #include @@ -162,7 +163,10 @@ TEST(DataAccessManagerRoutingTest, NativeSampleAlwaysIncludesNanosecondTimestamp ASSERT_TRUE(with_data["timestamp"].is_number_integer()); const auto ts_data = with_data["timestamp"].get(); EXPECT_GT(ts_data, static_cast(1e18)); // would only ever be true for ns - EXPECT_LT(ts_data, static_cast(1e20)); + // Upper bound stays inside int64_t range: 1e20 exceeds INT64_MAX and the + // narrowing cast is UB (gcc 15 / Lyrical materialises it as INT64_MIN, + // making the comparison silently fail). + EXPECT_LT(ts_data, std::numeric_limits::max()); // status == "metadata_only" mock->sample_publishers_ = 0; @@ -172,7 +176,7 @@ TEST(DataAccessManagerRoutingTest, NativeSampleAlwaysIncludesNanosecondTimestamp ASSERT_TRUE(meta["timestamp"].is_number_integer()); const auto ts_meta = meta["timestamp"].get(); EXPECT_GT(ts_meta, static_cast(1e18)); - EXPECT_LT(ts_meta, static_cast(1e20)); + EXPECT_LT(ts_meta, std::numeric_limits::max()); } // Failure-path coverage: publish() in the real transport throws on diff --git a/src/ros2_medkit_integration_tests/test/features/test_openapi_response_drift.test.py b/src/ros2_medkit_integration_tests/test/features/test_openapi_response_drift.test.py index 4591ede2..9fe9bac8 100644 --- a/src/ros2_medkit_integration_tests/test/features/test_openapi_response_drift.test.py +++ b/src/ros2_medkit_integration_tests/test/features/test_openapi_response_drift.test.py @@ -52,9 +52,9 @@ import requests # Humble (Ubuntu 22.04) ships python3-jsonschema 3.2 which only has draft-7; -# Jazzy/Rolling (Ubuntu 24.04) ship 4.10+ with Draft202012. Prefer the newest -# draft for OpenAPI 3.1 alignment, fall back to Draft7 on Humble. The properties -# we validate (required, type, properties) behave identically across drafts. +# Jazzy (Ubuntu 24.04) / Lyrical (Ubuntu 26.04) ship 4.10+ with Draft202012. +# Prefer the newest draft for OpenAPI 3.1 alignment, fall back to Draft7 on Humble. +# The properties we validate (required, type, properties) behave identically across drafts. try: from jsonschema.validators import Draft202012Validator as _Validator except ImportError: diff --git a/src/ros2_medkit_integration_tests/test/features/test_tls.test.py b/src/ros2_medkit_integration_tests/test/features/test_tls.test.py index 0f787106..1e7b09ed 100644 --- a/src/ros2_medkit_integration_tests/test/features/test_tls.test.py +++ b/src/ros2_medkit_integration_tests/test/features/test_tls.test.py @@ -64,13 +64,18 @@ def generate_test_certificates(output_dir: str) -> dict: key_file = os.path.join(output_dir, 'key.pem') ca_file = os.path.join(output_dir, 'ca.pem') - # Generate CA key and certificate + # Generate CA key and certificate. + # `basicConstraints` + `keyUsage` are required by Python 3.14 / OpenSSL + # on Ubuntu 26.04 (Resolute) - omitting them triggers + # "CA cert does not include key usage extension" during HTTPS verify. subprocess.run([ 'openssl', 'req', '-x509', '-newkey', 'rsa:2048', '-keyout', os.path.join(output_dir, 'ca_key.pem'), '-out', ca_file, '-days', '1', '-nodes', - '-subj', '/C=US/ST=Test/L=Test/O=Test/CN=TestCA' + '-subj', '/C=US/ST=Test/L=Test/O=Test/CN=TestCA', + '-addext', 'basicConstraints=critical,CA:TRUE', + '-addext', 'keyUsage=critical,keyCertSign,cRLSign', ], check=True, capture_output=True) # Generate server key diff --git a/src/ros2_medkit_plugins/ros2_medkit_graph_provider/CMakeLists.txt b/src/ros2_medkit_plugins/ros2_medkit_graph_provider/CMakeLists.txt index 1f4e0f3a..665ab812 100644 --- a/src/ros2_medkit_plugins/ros2_medkit_graph_provider/CMakeLists.txt +++ b/src/ros2_medkit_plugins/ros2_medkit_graph_provider/CMakeLists.txt @@ -74,9 +74,9 @@ if(BUILD_TESTING) ) ament_lint_auto_find_test_dependencies() - # ci.yml skips the ament_cmake_clang_format rosdep key on Humble + Rolling - # (linters only run in the Jazzy quality job), so QUIET + FOUND check - # avoids hard-failing on those runners. + # ci.yml skips the ament_cmake_clang_format rosdep key in the build-and-test + # job (linters only run in the Jazzy quality job), so QUIET + FOUND check + # avoids hard-failing when the package is not installed. find_package(ament_cmake_clang_format QUIET) if(ament_cmake_clang_format_FOUND) file(GLOB_RECURSE _format_files diff --git a/src/ros2_medkit_plugins/ros2_medkit_graph_provider/src/graph_provider_plugin.cpp b/src/ros2_medkit_plugins/ros2_medkit_graph_provider/src/graph_provider_plugin.cpp index ad3cf0f4..7ad0cb52 100644 --- a/src/ros2_medkit_plugins/ros2_medkit_graph_provider/src/graph_provider_plugin.cpp +++ b/src/ros2_medkit_plugins/ros2_medkit_graph_provider/src/graph_provider_plugin.cpp @@ -318,10 +318,10 @@ nlohmann::json build_graph_document_for_apps(const std::string & function_id, } // namespace GraphProviderPlugin::~GraphProviderPlugin() noexcept { - // On Rolling, destroying rclcpp resources (Subscription, Node) after - // rclcpp::shutdown() has invalidated the context can throw - // graph_listener::NodeNotFoundError. An exception escaping a destructor - // calls std::terminate(), so swallow it here. + // On Lyrical (originally observed on Rolling), destroying rclcpp resources + // (Subscription, Node) after rclcpp::shutdown() has invalidated the context + // can throw graph_listener::NodeNotFoundError. An exception escaping a + // destructor calls std::terminate(), so swallow it here. try { shutdown(); } catch (...) { @@ -332,9 +332,9 @@ void GraphProviderPlugin::shutdown() { if (shutdown_requested_.exchange(true)) { return; } - // ~rclcpp::Subscription can throw on Rolling when the rclcpp context - // was torn down before us; swallow so plugin_manager shutdown and the - // plugin destructor calling back into us do not abort the process. + // ~rclcpp::Subscription can throw on Lyrical (and Rolling) when the rclcpp + // context was torn down before us; swallow so plugin_manager shutdown and + // the plugin destructor calling back into us do not abort the process. try { diagnostics_sub_.reset(); } catch (...) { diff --git a/src/ros2_medkit_plugins/ros2_medkit_opcua/CMakeLists.txt b/src/ros2_medkit_plugins/ros2_medkit_opcua/CMakeLists.txt index b2a4fcd3..d66c3ecc 100644 --- a/src/ros2_medkit_plugins/ros2_medkit_opcua/CMakeLists.txt +++ b/src/ros2_medkit_plugins/ros2_medkit_opcua/CMakeLists.txt @@ -133,9 +133,9 @@ if(BUILD_TESTING) ) ament_lint_auto_find_test_dependencies() - # ci.yml skips the ament_cmake_clang_format rosdep key on Humble + Rolling - # (linters only run in the Jazzy quality job), so QUIET + FOUND check - # avoids hard-failing on those runners. + # ci.yml skips the ament_cmake_clang_format rosdep key in the build-and-test + # job (linters only run in the Jazzy quality job), so QUIET + FOUND check + # avoids hard-failing when the package is not installed. find_package(ament_cmake_clang_format QUIET) if(ament_cmake_clang_format_FOUND) file(GLOB_RECURSE _format_files diff --git a/src/ros2_medkit_plugins/ros2_medkit_opcua/src/opcua_client.cpp b/src/ros2_medkit_plugins/ros2_medkit_opcua/src/opcua_client.cpp index 64850ac6..f26a13e5 100644 --- a/src/ros2_medkit_plugins/ros2_medkit_opcua/src/opcua_client.cpp +++ b/src/ros2_medkit_plugins/ros2_medkit_opcua/src/opcua_client.cpp @@ -44,7 +44,7 @@ inline rclcpp::Logger opcua_client_logger() { // Pre-gate for traces whose stream-build cost is non-trivial (e.g. per-arg // loops). RCLCPP_DEBUG_STREAM constructs the std::stringstream // unconditionally, so for hot paths we check the effective level first. -// Uses the rcutils-level API (available in Humble through Rolling) instead +// Uses the rcutils-level API (available in Humble through Lyrical) instead // of rclcpp::Logger::get_effective_level (Jazzy+ only). inline bool client_debug_enabled() { return rcutils_logging_logger_is_enabled_for("opcua.client", RCUTILS_LOG_SEVERITY_DEBUG); diff --git a/src/ros2_medkit_plugins/ros2_medkit_sovd_service_interface/CMakeLists.txt b/src/ros2_medkit_plugins/ros2_medkit_sovd_service_interface/CMakeLists.txt index 0e238b21..63db5912 100644 --- a/src/ros2_medkit_plugins/ros2_medkit_sovd_service_interface/CMakeLists.txt +++ b/src/ros2_medkit_plugins/ros2_medkit_sovd_service_interface/CMakeLists.txt @@ -73,9 +73,9 @@ if(BUILD_TESTING) ) ament_lint_auto_find_test_dependencies() - # ci.yml skips the ament_cmake_clang_format rosdep key on Humble + Rolling - # (linters only run in the Jazzy quality job), so QUIET + FOUND check - # avoids hard-failing on those runners. + # ci.yml skips the ament_cmake_clang_format rosdep key in the build-and-test + # job (linters only run in the Jazzy quality job), so QUIET + FOUND check + # avoids hard-failing when the package is not installed. find_package(ament_cmake_clang_format QUIET) if(ament_cmake_clang_format_FOUND) file(GLOB_RECURSE _format_files diff --git a/src/ros2_medkit_serialization/CMakeLists.txt b/src/ros2_medkit_serialization/CMakeLists.txt index d1ef6660..96d4aa2d 100644 --- a/src/ros2_medkit_serialization/CMakeLists.txt +++ b/src/ros2_medkit_serialization/CMakeLists.txt @@ -138,7 +138,7 @@ if(BUILD_TESTING) # Configure clang-format manually for non-vendored files only. # ament_cmake_clang_format is intentionally only installed in the Jazzy - # quality job (ci.yml skips its rosdep key on Humble + Rolling), so use + # quality job (ci.yml skips its rosdep key in the build-and-test job), so use # QUIET + FOUND check instead of REQUIRED to gracefully degrade on the # build-and-test runners without breaking the build. find_package(ament_cmake_clang_format QUIET)