Skip to content

CI: per-package lint/test/doc loops match (ament_cargo) but colcon prints (ros.ament_cargo), so they run on zero packages #682

Description

@espressolee

Summary

The per-package loops in rust-stable.yml, rust-minimal.yml and rust-win.yml select packages with awk '$3 == "(ament_cargo)"', but colcon list prints (ros.ament_cargo). The loops match nothing, so the fmt --check, clippy -D warnings, cargo test and rustdoc -D warnings steps report success while processing zero packages.

The selector has read (ament_cargo) in every revision of rust-stable.yml and rust-minimal.yml since 2024-11-15 (b4e975cd), and in rust-win.yml since it was added on 2025-06-03 (205b84be). CI has installed colcon-ros-cargo from unpinned git main throughout. colcon-ros-cargo #32 changed the type string on 2024-12-06, so with those two facts together the steps have selected zero packages since then.

The problem is the false green, not the diagnostics behind it. PRs merged with these workflows received passing lint, test and doc checks that had not run.

Why the string changed

colcon_ros/package_identification/ros.py sets desc.type = f'ros.{build_type}'. colcon-ros-cargo #32 removed its own identification extension and re-keyed its task entry points from ament_cargo to ros.ament_cargo. CI installs colcon-ros-cargo from git main (rust-stable.yml:83), so it runs the post-#32 code.

Evidence

Measured in a container matching the humble leg (ros:humble, colcon-ros-cargo at dc26ba5f), with the repo and every ros2_rust_humble.repos entry checked out:

$ colcon list
rclrs   src/ros2_rust/rclrs   (ros.ament_cargo)

(ament_cargo) appears on 0 lines. Same result with and without colcon-ros-cargo installed, since the type string comes from colcon_ros.

In the CI logs, the loop body's own echo "Running clippy in $path" never appears as runtime output. In run 33553913917 (main, 2026-09-01) and run 27496259196 (main, 2026-06-14), each of the humble, jazzy and kilted legs shows Running clippy in, Running cargo test in and Running rustdoc check in exactly once, inside the step's own script listing, and never again. As a positive control the same legs print 107, 114 and 118 runtime Compiling lines. (The rolling leg is continue-on-error and did not reach these steps in either run.)

Affected lines: rust-stable.yml:95,114,130,146, rust-minimal.yml:95,114,130,146, rust-win.yml:79. The same stale literal is in rust-win.yml; I have not run the Windows leg myself.

The staleness is also user-facing in docs/building.md:110-116, which tells a reader that seeing

rclrs   src/ros2_rust/rclrs   (ament_cargo)

means "the colcon-ros-cargo plugin works as expected". Someone following that today sees (ros.ament_cargo) and has reason to think their setup is broken when it is correct.

What turning them back on surfaces

Running the workflow's commands verbatim, including the per-package feature branches and the three package exclusions, in a fully built workspace on that container:

step packages red
clippy 9 4
cargo test 6 1
rustdoc 6 1

I did not run the fmt step (it needs the nightly toolchain).

Nearly all of it is style debt on rclrs. One item is worth a decision rather than a fix: clippy::let_underscore_future fires on six let _ = ... sites, four of them calls to ExecutorCommands::run, whose docstring tells callers to do exactly that ("You can safely discard the promise ... Use let _ = promise; to suppress the warning"). The returned Promise is a oneshot receiver for a task that run has already queued, so the lint is not reporting a dropped task, but -D warnings will reject the documented pattern. Either the docstring should suggest a different spelling or the lint needs an allow with that explanation.

One red I am not claiming: cargo test on rosidl_runtime_rs fails to link its test binary with cannot find -lrosidl_runtime_c. That may well be my container rather than the project, and CI is the place to find out.

Full diagnostic inventory (rclrs, Rust 1.85.0)

clippy, 137 diagnostics across 32 lint kinds on rclrs: 23 elidable lifetimes ('msg), 20 very-complex-type, 15 useless conversion, 14 needless deref, 11 needless borrow, 5 redundant pattern matching, 5 let_underscore_future (2 of them in test modules), 4 unit let-binding, 4 elidable lifetimes ('a), 4 doc list indentation, and 22 kinds with one or two hits each (among them two unannotated transmutes, an unsafe fn without a # Safety section, and a 9-argument function). Three other packages carry one clippy lint each (unwrap_or constructing a default, an unnecessary raw-pointer cast, and the sixth let_underscore_future in examples/rclrs/rust_pubsub).

let_underscore_future sites:

rclrs/src/action/action_server.rs:376   let _ = self.board.node.commands().run(f);
rclrs/src/action/action_server.rs:425
rclrs/src/node/node_options.rs:410
rclrs/src/subscription.rs:588           (test module)
rclrs/src/worker.rs:820                 (test module)
examples/rclrs/rust_pubsub/src/simple_subscriber.rs:36

rustdoc, 8 errors on rclrs: unresolved intra-doc links (crate::spin, crate::Node::create_action_client, NodeState::create_action_server, NodeState::create_action_goal_receiver) and public docs for begin / begin_cancelling linking to the private item CancellingGoal.

CI uses dtolnay/rust-toolchain@stable, so today's stable will report a different, probably larger, set than 1.85.0 does.

Proposed next step

I can open a PR that updates the nine selectors and the docs/building.md example. Because that will expose the failures above, I am raising it here first so you can decide whether the revived steps should start blocking or continue-on-error. Happy to take any part of the cleanup that would be useful.

Environment: ros:humble on arm64, Rust 1.85.0 (the version this repo's Dockerfile pins), clippy 0.1.85.

Assisted-by: Claude Code:claude-fable-5-1

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions