mirror of
https://github.com/introlab/rtabmap_ros.git
synced 2026-10-05 01:07:49 +08:00
Merge branch 'ros2' of github.com:introlab/rtabmap_ros into lyrical-devel
This commit is contained in:
@@ -0,0 +1,45 @@
|
||||
# lcov configuration for .github/workflows/coverage.yml.
|
||||
#
|
||||
# A copy of colcon-lcov-result 0.5.0's default (colcon_lcov_result/verb/configuration/lcovrc),
|
||||
# with branch coverage turned off below. The whole file is needed: --lcov-config-file
|
||||
# replaces the default rather than adding to it.
|
||||
#
|
||||
# Why no branch coverage: gcc emits a hidden "it threw" branch on nearly every line that
|
||||
# calls a function, and no test takes it. Each such line -- a declaration like
|
||||
# 'rtabmap::Transform t;' included -- then counts as a partial, and Codecov reports a
|
||||
# partial line as not covered. lcov's geninfo_no_exception_branch would drop those
|
||||
# branches, but not with the lcov 1.15 of Ubuntu 22.04 and gcc 11: its JSON reader
|
||||
# ignores the flag, and its text reader cannot read gcc 11's .gcno files. So only line
|
||||
# coverage is reported: a line is covered when a test ran it.
|
||||
|
||||
geninfo_auto_base=1
|
||||
|
||||
# Specify size of tabs
|
||||
genhtml_num_spaces = 2
|
||||
|
||||
# Include color legend in HTML output if non-zero
|
||||
genhtml_legend = 1
|
||||
|
||||
# Include function coverage data display
|
||||
genhtml_function_coverage = 1
|
||||
|
||||
# Include branch coverage data display
|
||||
genhtml_branch_coverage = 0
|
||||
|
||||
# Specify whether to capture coverage data for external source
|
||||
# files
|
||||
geninfo_external = 0
|
||||
|
||||
# Less verbose output
|
||||
lcov_quiet = 1
|
||||
|
||||
# Specify if function coverage data should be collected and
|
||||
# processed.
|
||||
lcov_function_coverage = 1
|
||||
|
||||
# Specify if branch coverage data should be collected and
|
||||
# processed.
|
||||
lcov_branch_coverage = 0
|
||||
|
||||
## Follow symlinks
|
||||
lcov_follow = 1
|
||||
@@ -0,0 +1,187 @@
|
||||
name: Coverage
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ ros2 ]
|
||||
pull_request:
|
||||
branches: [ ros2 ]
|
||||
workflow_dispatch:
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
|
||||
cancel-in-progress: ${{ github.event_name == 'pull_request' }}
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
id-token: write
|
||||
|
||||
jobs:
|
||||
coverage:
|
||||
name: Coverage (humble)
|
||||
runs-on: ubuntu-latest
|
||||
container:
|
||||
# RTAB-Map master, already built and installed on top of ROS Humble
|
||||
# (jammy = 22.04) -- the same base the repo's own docker/humble image
|
||||
# uses. Saves building the library here, and pins the coverage run to
|
||||
# RTAB-Map master rather than whatever the released binaries carry.
|
||||
image: introlab3it/rtabmap:jammy
|
||||
env:
|
||||
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
# The container runs as root, so no sudo (it is not installed).
|
||||
#
|
||||
# colcon lcov-result is not a built-in verb -- it comes from the
|
||||
# colcon-lcov-result package, which action-ros-ci calls but does not
|
||||
# install. ros2.yml gets it for free because it runs ros-tooling/setup-ros
|
||||
# first; this job calls action-ros-ci directly, so install it here.
|
||||
# Without it action-ros-ci logs "invalid choice: 'lcov-result'", ignores
|
||||
# the failure, and the job goes green having measured nothing.
|
||||
# Versions pinned to the ones setup-ros uses.
|
||||
- run: |
|
||||
export DEBIAN_FRONTEND=noninteractive
|
||||
apt-get update
|
||||
# lcov for genhtml (the browsable artifact below); colcon-lcov-result
|
||||
# shells out to it too.
|
||||
apt-get install -y lcov python3-pip
|
||||
pip3 install -U \
|
||||
colcon-lcov-result==0.5.0 \
|
||||
colcon-coveragepy-result==0.0.8
|
||||
colcon lcov-result --help > /dev/null
|
||||
# The image ships rosdep but has never initialized it -- the repo's
|
||||
# own docker/humble Dockerfile runs `rosdep init` for the same reason.
|
||||
# action-ros-ci only runs `rosdep update`, which fails with "no
|
||||
# sources directory exists" until this has happened once.
|
||||
rosdep init || true
|
||||
|
||||
# Only the packages that have tests. The others are still built when a
|
||||
# tested package depends on them (--packages-up-to), just not measured.
|
||||
- uses: ros-tooling/[email protected]
|
||||
with:
|
||||
package-name: rtabmap_conversions rtabmap_util rtabmap_sync rtabmap_odom rtabmap_slam rtabmap_python
|
||||
target-ros2-distro: humble
|
||||
# RTAB-Map is installed in the image, not as an apt package, so rosdep
|
||||
# cannot resolve the key and must not try.
|
||||
rosdep-skip-keys: rtabmap
|
||||
# The coverage-gcc mixin only adds --coverage; it sets no build type,
|
||||
# and neither action-ros-ci nor this repo's CMakeLists do. Without
|
||||
# this the build type is empty, which happens to mean -O0 but is not
|
||||
# guaranteed to stay that way -- and at -O2 inlining and dead-code
|
||||
# elimination make gcov's line attribution unreliable.
|
||||
extra-cmake-args: -DCMAKE_BUILD_TYPE=Debug
|
||||
colcon-defaults: |
|
||||
{
|
||||
"build": {
|
||||
"mixin": ["coverage-gcc"]
|
||||
},
|
||||
"test": {
|
||||
"pytest-with-coverage": true
|
||||
}
|
||||
}
|
||||
# Pinned so a change in the mixin repository cannot break this job.
|
||||
colcon-mixin-repository: https://raw.githubusercontent.com/colcon/colcon-mixin-repository/b8436aa16c0bdbc01081b12caa253cbf16e0fb82/index.yaml
|
||||
# Run the coverage passes ourselves, in the step below. The action's
|
||||
# own baseline pass is a bare `colcon lcov-result --initial` with no
|
||||
# package selection, so it walks every package in the workspace --
|
||||
# including the ones --packages-up-to never built -- and fails with
|
||||
# "cannot read .../build/rtabmap_viz".
|
||||
coverage-result: false
|
||||
|
||||
# Both passes restricted to the packages that were actually built.
|
||||
#
|
||||
# lcov captures each package's whole build directory, so more than this
|
||||
# repo's sources land in it. Filtered:
|
||||
# */test/* the test sources -- the instrument, not the subject. A line
|
||||
# there is uncovered only when the test skipped it, which says
|
||||
# nothing about the code under test, and they are near-fully
|
||||
# covered by construction.
|
||||
# /usr/*, /opt/* everything outside the workspace. RTAB-Map's own .cpp
|
||||
# files are never captured (the library is installed in the
|
||||
# image, not built here), but its inline and template code is
|
||||
# emitted into the objects of the packages that include it,
|
||||
# as are PCL, Eigen and the standard library.
|
||||
# *CompilerId*, */CMakeFiles/* CMake's compiler-probe translation
|
||||
# units. colcon-lcov-result tries to delete their .gcno files
|
||||
# but misses these, and they are recorded against a path that
|
||||
# does not exist -- which kills the genhtml pass colcon runs
|
||||
# at the end ("cannot read .../CMakeCCompilerId.c", exit 2).
|
||||
# Filters run before that pass, so dropping them here is
|
||||
# enough.
|
||||
# Quoting them matters: action-ros-ci injects filters unquoted, so the
|
||||
# shell can glob them away before colcon ever sees them.
|
||||
- name: Coverage report
|
||||
working-directory: ros_ws
|
||||
run: |
|
||||
# `.` not `source`: steps in this container run under sh (dash), where
|
||||
# `source` does not exist. GitHub picks sh whenever it cannot find
|
||||
# bash in the image's PATH, and says so in the log ("shell: sh -e").
|
||||
. /opt/ros/humble/setup.sh
|
||||
# C++ packages only -- rtabmap_python emits no .gcno for lcov to read,
|
||||
# and is measured by the coveragepy step below instead.
|
||||
PKGS="rtabmap_conversions rtabmap_util rtabmap_sync rtabmap_odom rtabmap_slam"
|
||||
# Baseline from the .gcno files. Without it a source file that no test
|
||||
# ever loaded is missing from the report altogether rather than
|
||||
# counted as 0%, which quietly inflates the result.
|
||||
# Line coverage only, no branch coverage: see the comment in .github/lcovrc.
|
||||
LCOVRC=src/rtabmap_ros/.github/lcovrc
|
||||
colcon lcov-result --initial --packages-select $PKGS --lcov-config-file $LCOVRC
|
||||
# The verb ends by running genhtml and returns *its* exit code, so a
|
||||
# cosmetic HTML hiccup fails the whole job even though the report was
|
||||
# written. The deliverable is total_coverage.info; the HTML is a
|
||||
# convenience. Tolerate the former, then gate on the latter.
|
||||
colcon lcov-result --packages-select $PKGS --lcov-config-file $LCOVRC --verbose \
|
||||
--filter '*/test/*' '/usr/*' '/opt/*' \
|
||||
'*CompilerId*' '*/CMakeFiles/*' || true
|
||||
test -s lcov/total_coverage.info
|
||||
|
||||
# Python coverage is a separate mechanism: the coverage-gcc mixin only adds
|
||||
# --coverage to the compiler, which does nothing for an ament_python package.
|
||||
# colcon test --pytest-with-coverage (set above) writes a Cobertura report into
|
||||
# the package's own build directory instead.
|
||||
#
|
||||
# Its paths are relative to the package rather than the repository, so
|
||||
# cv_compression.py arrives as "rtabmap_python/cv_compression.py" -- one level
|
||||
# short of where it really lives. Rewrite them here rather than leave Codecov to
|
||||
# guess, which it does by suffix and can get wrong.
|
||||
- name: Python coverage report
|
||||
working-directory: ros_ws
|
||||
run: |
|
||||
python3 - <<'EOF'
|
||||
import pathlib
|
||||
import xml.etree.ElementTree as ET
|
||||
p = pathlib.Path('build/rtabmap_python/coverage.xml')
|
||||
if not p.is_file():
|
||||
print('::warning::no python coverage produced for rtabmap_python')
|
||||
raise SystemExit(0)
|
||||
tree = ET.parse(p)
|
||||
root = tree.getroot()
|
||||
for source in root.iter('source'):
|
||||
source.text = '.'
|
||||
for cls in root.iter('class'):
|
||||
cls.set('filename', 'rtabmap_python/' + cls.get('filename'))
|
||||
tree.write(p, xml_declaration=True, encoding='utf-8')
|
||||
print('rewrote', p, 'to repository-relative paths')
|
||||
EOF
|
||||
|
||||
# colcon lcov-result runs genhtml itself, into the same lcov/ directory.
|
||||
- name: Upload HTML coverage artifact
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: coverage-html
|
||||
path: ros_ws/lcov
|
||||
retention-days: 14
|
||||
|
||||
- name: Upload to Codecov
|
||||
if: ${{ env.CODECOV_TOKEN != '' }}
|
||||
uses: codecov/codecov-action@v5
|
||||
with:
|
||||
files: ros_ws/lcov/total_coverage.info,ros_ws/build/rtabmap_python/coverage.xml
|
||||
# Upload ONLY the aggregated lcov file. By default the CLI also walks
|
||||
# the tree and runs gcov over every .gcno it finds, which re-adds the
|
||||
# test sources the --filter above just dropped.
|
||||
disable_search: true
|
||||
plugins: noop
|
||||
token: ${{ env.CODECOV_TOKEN }}
|
||||
fail_ci_if_error: false
|
||||
@@ -1,73 +1,62 @@
|
||||
name: docker
|
||||
name: docker-ros2
|
||||
|
||||
# ROS2 images: humble, jazzy, kilted and lyrical.
|
||||
#
|
||||
# The images built from this tree (docker/*/latest) compile the workspace, which
|
||||
# is far too slow to emulate, so every arch of those is built natively: amd64 on
|
||||
# an x86 runner, arm64 on a GitHub arm64 runner. Because a single Docker Hub tag
|
||||
# cannot hold two independently pushed architectures, each build pushes an
|
||||
# arch-suffixed tag (e.g. :humble-latest-amd64 / :humble-latest-arm64) and a
|
||||
# final job joins them into the real multi-arch tag (:humble-latest) with
|
||||
# `imagetools create`.
|
||||
#
|
||||
# The runner image only hosts the build; it does not have to match the Ubuntu
|
||||
# release inside the image, so ubuntu-26.04{,-arm} is used for all of them
|
||||
# (ubuntu-22.04{,-arm} and ubuntu-24.04{,-arm} also exist, if ever needed).
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ ros2 ]
|
||||
pull_request:
|
||||
branches: [ ros2 ]
|
||||
workflow_dispatch:
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
|
||||
cancel-in-progress: ${{ github.event_name == 'pull_request' }}
|
||||
|
||||
jobs:
|
||||
# Images built from this tree (docker/*/latest), the ones a change here can break.
|
||||
docker:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
# A manual dispatch is honored only on ros2, the only ref we push from.
|
||||
if: ${{ github.event_name != 'workflow_dispatch' || github.ref == 'refs/heads/ros2' }}
|
||||
runs-on: ${{ matrix.runner }}
|
||||
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
docker_tag: [humble, humble-latest, jazzy, jazzy-latest, kilted, kilted-latest, lyrical-latest]
|
||||
docker_tag: [humble-latest, jazzy-latest, kilted-latest, lyrical-latest]
|
||||
arch: [amd64, arm64]
|
||||
include:
|
||||
- docker_tag: humble
|
||||
docker_path: 'humble'
|
||||
docker_platforms: |
|
||||
linux/amd64
|
||||
- docker_tag: humble-latest
|
||||
docker_path: 'humble/latest'
|
||||
docker_platforms: |
|
||||
linux/amd64
|
||||
linux/arm64
|
||||
- docker_tag: jazzy
|
||||
docker_path: 'jazzy'
|
||||
docker_platforms: |
|
||||
linux/amd64
|
||||
linux/arm64
|
||||
- docker_tag: jazzy-latest
|
||||
docker_path: 'jazzy/latest'
|
||||
docker_platforms: |
|
||||
linux/amd64
|
||||
linux/arm64
|
||||
- docker_tag: kilted
|
||||
docker_path: 'kilted'
|
||||
docker_platforms: |
|
||||
linux/amd64
|
||||
linux/arm64
|
||||
- docker_tag: kilted-latest
|
||||
docker_path: 'kilted/latest'
|
||||
docker_platforms: |
|
||||
linux/amd64
|
||||
#Disabled till rtabmap_ros is released on lyrical
|
||||
#- docker_tag: lyrical
|
||||
# docker_path: 'lyrical'
|
||||
# docker_platforms: |
|
||||
# linux/amd64
|
||||
# linux/arm64
|
||||
- docker_tag: lyrical-latest
|
||||
docker_path: 'lyrical/latest'
|
||||
docker_platforms: |
|
||||
linux/amd64
|
||||
linux/arm64
|
||||
|
||||
- arch: amd64
|
||||
runner: ubuntu-26.04
|
||||
docker_platform: linux/amd64
|
||||
- arch: arm64
|
||||
runner: ubuntu-26.04-arm
|
||||
docker_platform: linux/arm64
|
||||
|
||||
steps:
|
||||
-
|
||||
name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
-
|
||||
name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@v3
|
||||
with:
|
||||
platforms: all
|
||||
-
|
||||
name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
@@ -86,9 +75,105 @@ jobs:
|
||||
with:
|
||||
context: .
|
||||
push: ${{ github.event_name != 'pull_request' }}
|
||||
platforms: ${{ github.event_name == 'pull_request' && 'linux/amd64' || matrix.docker_platforms }}
|
||||
platforms: ${{ matrix.docker_platform }}
|
||||
# Run the test suites inside the image being built. Nothing of them is kept, and
|
||||
# the build fails if one does, so no image is published from a tree that fails.
|
||||
build-args: |
|
||||
RUN_TESTS=1
|
||||
file: ./docker/${{ matrix.docker_path }}/Dockerfile
|
||||
tags: introlab3it/rtabmap_ros:${{ matrix.docker_tag }}-${{ matrix.arch }}
|
||||
no-cache: true
|
||||
cache-to: type=inline
|
||||
|
||||
docker_manifest:
|
||||
needs: docker
|
||||
# Nothing to join on pull requests, where the per-arch tags are never pushed.
|
||||
if: ${{ !cancelled() && !failure() && github.event_name != 'pull_request' && (github.event_name != 'workflow_dispatch' || github.ref == 'refs/heads/ros2') }}
|
||||
runs-on: ubuntu-26.04
|
||||
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
docker_tag: [humble-latest, jazzy-latest, kilted-latest, lyrical-latest]
|
||||
|
||||
steps:
|
||||
-
|
||||
name: Login to DockerHub
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||
-
|
||||
name: Create multi-arch manifest
|
||||
run: |
|
||||
docker buildx imagetools create \
|
||||
-t introlab3it/rtabmap_ros:${{ matrix.docker_tag }} \
|
||||
introlab3it/rtabmap_ros:${{ matrix.docker_tag }}-amd64 \
|
||||
introlab3it/rtabmap_ros:${{ matrix.docker_tag }}-arm64
|
||||
|
||||
# Images that install a released rtabmap_ros from apt (docker/<distro>): they hold
|
||||
# nothing from the tree under review, so building them on a pull request would only
|
||||
# report that the release still installs. Left to the pushes that publish them.
|
||||
#
|
||||
# This one is left on a single QEMU-emulated job, for simplicity: it only
|
||||
# apt-installs a released rtabmap_ros, so nothing is compiled under emulation,
|
||||
# and one build pushes the multi-arch tag straight away -- no per-arch tags and
|
||||
# no manifest job to join them.
|
||||
docker-released:
|
||||
if: ${{ github.event_name != 'pull_request' && (github.event_name != 'workflow_dispatch' || github.ref == 'refs/heads/ros2') }}
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
docker_tag: [humble, jazzy, kilted, lyrical]
|
||||
include:
|
||||
- docker_tag: humble
|
||||
docker_path: 'humble'
|
||||
docker_platforms: |
|
||||
linux/amd64
|
||||
- docker_tag: jazzy
|
||||
docker_path: 'jazzy'
|
||||
docker_platforms: |
|
||||
linux/amd64
|
||||
linux/arm64
|
||||
- docker_tag: kilted
|
||||
docker_path: 'kilted'
|
||||
docker_platforms: |
|
||||
linux/amd64
|
||||
linux/arm64
|
||||
- docker_tag: lyrical
|
||||
docker_path: 'lyrical'
|
||||
docker_platforms: |
|
||||
linux/amd64
|
||||
linux/arm64
|
||||
|
||||
steps:
|
||||
-
|
||||
name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
-
|
||||
name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@v3
|
||||
with:
|
||||
platforms: all
|
||||
-
|
||||
name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
-
|
||||
name: Login to DockerHub
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||
-
|
||||
name: Build and push
|
||||
uses: docker/build-push-action@v6
|
||||
with:
|
||||
context: .
|
||||
push: true
|
||||
platforms: ${{ matrix.docker_platforms }}
|
||||
file: ./docker/${{ matrix.docker_path }}/Dockerfile
|
||||
tags: introlab3it/rtabmap_ros:${{ matrix.docker_tag }}
|
||||
no-cache: true
|
||||
cache-to: type=inline
|
||||
|
||||
|
||||
@@ -4,9 +4,13 @@ on:
|
||||
push:
|
||||
branches:
|
||||
- 'master'
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
docker:
|
||||
# Built and pushed only from master (push or manual dispatch), since it
|
||||
# pushes the introlab3it/rtabmap_ros tags to Docker Hub.
|
||||
if: github.ref == 'refs/heads/master'
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
strategy:
|
||||
|
||||
@@ -6,6 +6,7 @@ on:
|
||||
branches: [ lyrical-devel ]
|
||||
pull_request:
|
||||
branches: [ lyrical-devel ]
|
||||
workflow_dispatch:
|
||||
|
||||
env:
|
||||
BUILD_TYPE: Release
|
||||
@@ -16,16 +17,16 @@ concurrency:
|
||||
|
||||
jobs:
|
||||
build:
|
||||
name: Build ros2 ${{ matrix.ros_distro }}
|
||||
name: Build ros2 ${{ matrix.ros_distro }}${{ matrix.ros2_testing && ' (ros-testing)' || '' }}
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix:
|
||||
ros_distro: [lyrical]
|
||||
ros2_testing: [false, true] # build with main and ros-testing apt repositories
|
||||
include:
|
||||
- ros_distro: lyrical
|
||||
skip_keys: '' # skip keys shoudl be empty when release on ROSDISTRO_devel branch, comment these keys in the appriopriate package.
|
||||
# rtabmap_costmap_plugins cannot be built, missing nav2 on lyrical, commented from rtabmap_ros package.
|
||||
# Make sure rosdistro doesn't declare rtabmap_costmap_plugins.
|
||||
# velodyne and grid_map_ros are not available on lyrical, they are commented in rtabmap_examples and rtabmap_util packages.
|
||||
packages: 'rtabmap_ros'
|
||||
fail-fast: false
|
||||
container:
|
||||
@@ -35,6 +36,7 @@ jobs:
|
||||
- uses: ros-tooling/[email protected]
|
||||
with:
|
||||
required-ros-distributions: ${{ matrix.ros_distro }}
|
||||
use-ros2-testing: ${{ matrix.ros2_testing }}
|
||||
- run: |
|
||||
DEBIAN_FRONTEND=noninteractive
|
||||
sudo apt update
|
||||
|
||||
Reference in New Issue
Block a user