From 1e2159eefbe83685beff8f7002118e9577fa5d40 Mon Sep 17 00:00:00 2001 From: Tobias Fischer Date: Sat, 24 Oct 2026 23:42:42 +1000 Subject: [PATCH] rolling: septentrio_gnss_driver patch for 1.4.8-3; build-ci names unfinished builds - rolling's sync (#99) moved septentrio_gnss_driver to 1.4.8-3, whose typedefs.hpp uses __has_include instead of ROS2_VER_N520, so rolling's patch no longer applied ("could not find context"; rolling linux-aarch64 stopped). lyrical's patch, for 1.4.8-2, applies to it: rolling uses that one now. - build-ci (parallel builds): rattler-build's final error doesn't say which build it is from. On failure, build-ci now lists the recipes that started but wrote no package. Co-Authored-By: Claude Opus 5.5 --- .../patch/ros2-septentrio-gnss-driver.patch | 22 +++++++++---------- tools/robostack.py | 6 +++++ tools/tests/test_build_timings.py | 20 +++++++++++++++++ 3 files changed, 37 insertions(+), 11 deletions(-) diff --git a/distros/rolling/patch/ros2-septentrio-gnss-driver.patch b/distros/rolling/patch/ros2-septentrio-gnss-driver.patch index 0da08ebc9..0a257831e 100644 --- a/distros/rolling/patch/ros2-septentrio-gnss-driver.patch +++ b/distros/rolling/patch/ros2-septentrio-gnss-driver.patch @@ -1,5 +1,5 @@ diff --git a/CMakeLists.txt b/CMakeLists.txt -index 66dec47..0ad6caa 100644 +index bf6c60d..3668dd5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,8 +1,11 @@ @@ -17,18 +17,18 @@ index 66dec47..0ad6caa 100644 if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES) message(STATUS "Setting build type to Release as none was specified.") diff --git a/include/septentrio_gnss_driver/abstraction/typedefs.hpp b/include/septentrio_gnss_driver/abstraction/typedefs.hpp -index 69f7b2c..25ec2c7 100644 +index f05da0e..601a244 100644 --- a/include/septentrio_gnss_driver/abstraction/typedefs.hpp +++ b/include/septentrio_gnss_driver/abstraction/typedefs.hpp -@@ -40,9 +40,11 @@ - // tf2 includes - #ifdef ROS2_VER_N520 - #include -+#include - #include +@@ -43,6 +43,11 @@ #else #include -+#include - #include #endif - #ifdef ROS2_VER_N250 ++#if __has_include() ++#include ++#else ++#include ++#endif + #if __has_include() + #include + #else diff --git a/tools/robostack.py b/tools/robostack.py index c3886768b..78fc21676 100644 --- a/tools/robostack.py +++ b/tools/robostack.py @@ -126,6 +126,7 @@ def build_ci_parallel(distro: str, recipes: list[str], args: list[str], cwd: Pat (ros--) only repackage, but wait for others while building alongside: they are left out (build_timings gives them ALIAS_SECONDS).""" span: dict[str, list[str]] = {} # recipe -> [first, last] timestamp + finished: set[str] = set() def show(line: bytes) -> None: try: @@ -136,6 +137,8 @@ def show(line: bytes) -> None: # the build itself: rattler-build renders every recipe up front if name and any(s.get("name") == "Running build for" for s in spans): span.setdefault(name, [entry["timestamp"]] * 2)[1] = entry["timestamp"] + if str(entry["fields"].get("message", "")).startswith("Archive written to"): + finished.add(name) text = f"{entry['timestamp'][11:19]} [{name or '-'}] {entry['fields'].get('message', '')}\n" sys.stdout.write(text) except (ValueError, KeyError, AttributeError, TypeError): @@ -144,6 +147,9 @@ def show(line: bytes) -> None: args = [*args, "--parallel-builds", PARALLEL_BUILDS, "--log-style", "json"] rc = run_build(rattler_build(distro, args, skip_existing=False), cwd, show) + if rc != 0 and (unfinished := sorted(set(span) - finished)): + # rattler-build's final error doesn't say which of the parallel builds it is from + print(f"Started but not finished: {', '.join(unfinished)}", file=sys.stderr, flush=True) if rc == 0 and os.environ.get("GITHUB_ACTIONS"): import build_timings # for packing the build jobs by time from datetime import datetime diff --git a/tools/tests/test_build_timings.py b/tools/tests/test_build_timings.py index 9ae50042a..3ace74f16 100644 --- a/tools/tests/test_build_timings.py +++ b/tools/tests/test_build_timings.py @@ -156,3 +156,23 @@ def run_build(cmd, cwd, show=None): assert [(r, round(s, 2)) for r, s in noted] == [("ros2-a", 6.61), ("ros2-b", 12.39)] out = capsys.readouterr().out assert "07:00:01 [ros2-a] Fetching source" in out and "not json" in out + + +def test_build_ci_parallel_names_the_unfinished_builds(tmp_path, monkeypatch, capsys): + import robostack + + def line(t, recipe, message): + return (json.dumps({"timestamp": f"2026-10-24T07:00:{t:02d}.0Z", "fields": {"message": message}, + "spans": [{"recipe": recipe, "name": "Running build for"}]}) + "\n").encode() + + def run_build(cmd, cwd, show=None): + for entry in (line(1, "ros2-a-1.0-h0_1", "Fetching source"), line(2, "ros2-b-1.0-h0_1", "Applying patch"), + line(3, "ros2-a-1.0-h0_1", "Archive written to '/bld/ros2-a-1.0-h0_1.conda'"), + b"Error: x Patch application error\n"): + show(entry) + return 1 + + monkeypatch.setattr(robostack, "run_build", run_build) + monkeypatch.setattr(robostack, "rattler_build", lambda distro, args, skip_existing=True: ["rattler-build", *args]) + assert robostack.build_ci_parallel("rolling", ["ros2-a", "ros2-b"], ["--recipe", "a", "--recipe", "b"], tmp_path) == 1 + assert "Started but not finished: ros2-b" in capsys.readouterr().err