ci: add per-plugin platform filter and release.sh override hooks#74
Merged
Merged
Conversation
Two opt-in extension points to the generic Build & Release workflow,
both fully backward compatible (every existing plugin keeps its current
behaviour because the new fields are absent).
1. supported_platforms (manifest.json)
When a plugin's manifest declares an array like
"supported_platforms": ["linux-x86_64", "linux-arm64", ...]
matrix entries whose canonical platform is not listed are skipped
from build, package, upload and release. Useful for plugins that do
not (yet) support every host (e.g. Python-embedding plugins blocked
on Windows ARM, or ROS-aware plugins that only ship for Linux).
The platform identifier is canonical "<os>-<arch>" using the same
normalization release_tools.py already applies elsewhere
(PLATFORM_ARCH_MAP / PLATFORM_OS_MAP) — aarch64 -> arm64,
x64 -> x86_64.
2. <plugin>/release.sh override
When a plugin ships an executable release.sh, the Build & Test step
runs it instead of the default ./build.sh + ctest flow. The script
takes responsibility for build, tests, and producing the artifacts
the rest of the pipeline expects under build/<plugin>/Release/.
Used by plugins whose build pipeline diverges from the conan + cmake
default (e.g. multi-distribution Docker builds).
The bulk of the resolution logic moves into a new release_tools.py
subcommand, resolve-build-scope, replacing the inline Python and bash
that previously lived in the workflow's "Resolve build scope" step. The
workflow step is now a thin wrapper that pipes the script's key=value
output into $GITHUB_OUTPUT.
3 tasks
pabloinigoblasco
added a commit
that referenced
this pull request
Apr 29, 2026
…anner The host plugin scanner (scanPluginDsos in pj_plugins/src/plugin_catalog.cpp) walks the extension directory recursively, dlopens every file with a DSO suffix, and probes each for the four standard plugin family symbols (PJ_get_data_source_vtable, PJ_get_message_parser_vtable, PJ_get_toolbox_vtable, PJ_get_dialog_vtable). Until this commit, every per-distro inner shipped under dist/<distro>/ exported two of those symbols (DataSource and Dialog) — so the host registered four phantom streamers (one per supported ROS distro) on top of the legitimate proxy entry point, and clicking on a distro that did not match the host's ROS install produced "undefined symbol" failures because the host loaded the inner directly with no rclcpp linkage available. Fix the symbol partition: - distro/src/data_stream_ros2.cpp: drop PJ_DATA_SOURCE_PLUGIN / PJ_DIALOG_PLUGIN macros (those name the standard symbols the scanner looks for) and emit two private getters instead — PJ_ros2_inner_get_data_source_vtable and PJ_ros2_inner_get_dialog_vtable. The inner still exports pj_plugin_abi_version (file-scope, weak), so the scanner's ABI check passes; manifest-family probing then fails cleanly and the inner is reported as a diagnostic, never as a plugin. - proxy/src/data_stream_ros2.cpp: add PJ_get_dialog_vtable next to the existing PJ_get_data_source_vtable, both backed by a single call_once that loads the inner once and caches both vtables. The inner is resolved via the new private symbol names. As a side-effect, fix the inner-path computation to match the actual on-disk layout (dist/<distro>/inner.so, not the older flat dist/inner.so). - docker/run-local.sh: drop the .pjmanifest.json sidecar from the bundle. plotjuggler_core's discovery is now embedded-manifest only (PR #74 in core); the sidecar is inspection-only and adds no value to the marketplace ZIP. - CMakeLists.txt: link the proxy against pj_dialog_protocol (header-only C ABI) so it can declare PJ_dialog_vtable_t. Net behavior: the marketplace extension exposes exactly one streamer ("ROS 2 Topic Subscriber") whose runtime distro selection is performed by the proxy. Hosts without ROS see a single broken plugin with a clear error message instead of four duplicates with cryptic dlopen failures.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Two opt-in extension points to the generic Build & Release workflow. Fully backward compatible — every existing plugin keeps its current behaviour because the new fields are absent.
Why
Plugins are diverging:
toolbox_reactive_scripts_editor) cannot build on Windows ARM64 today (transitivempdecimalrejection — see PR build: enable Windows ARM64 via local mpdecimal recipe override #73).data_stream_ros2) need a Docker-based multi-distribution build that doesn't fit the defaultconan + cmakematrix.We could special-case the workflow per plugin, but that doesn't scale. These hooks let each plugin opt into the deviation it needs without forking the release pipeline.
Hooks
1.
supported_platformsinmanifest.jsonMatrix entries whose canonical platform is not listed are skipped from build, package, upload and release. The platform identifier is canonical
<os>-<arch>using the same normalizationrelease_tools.pyalready applies (PLATFORM_ARCH_MAP/PLATFORM_OS_MAP) —aarch64→arm64,x64→x86_64.2.
<plugin>/release.shoverrideWhen a plugin ships an executable
release.sh, the Build & Test step runs it instead of the default./build.sh + ctest. The script owns build, tests, and producing artifacts underbuild/<plugin>/Release/for the rest of the pipeline.Cleanup
The bulk of the resolution logic moved into a new
release_tools.py resolve-build-scopesubcommand, replacing the inline Python and bash that previously lived in the workflow's Resolve build scope step. The step is now a thin wrapper:The workflow file ends up 41 lines shorter than before.
Test plan
supported_platforms, norelease.sh): every matrix entry runs as before.supported_platforms, only listed platforms produce artifacts; submit-to-registry sees only those.release.sh, Build & Test invokes it; subsequent steps consumebuild/<plugin>/Release/as today.Follow-ups
release_tools.py create-distribution-packagelearns a staging-dir mode so a plugin can hand it a pre-assembled tree (separate PR).data_stream_ros2/release.shlands in PR feat(data_stream_ros2): ROS 2 topic subscriber plugin with cross-distro Docker release pipeline #66 once both pieces above are in.