CI: use ubuntu arm runners instead of QEMU (#1771)

* CI: use ubuntu arm runners instead of QEMU

* removed focal deps docker image ci

* run tests in docker ci

* revert temporary test

* trigger ci jobs with modified files

* ldconfig

* arm64 ldconfig order

* No response filtering here: cv::goodFeaturesToTrack() already applies GFTT/QualityLevel, relative to the best corner's measure. Re-applying it as an absolute floor on KeyPoint::response double-filtered (~86% of keypoints ropped on OpenCV 4.5), and dropped *every* keypoint on OpenCV < 4.5, whose GFTTDetector leaves response at 0.

* fixing ExtractXYZCorrespondencesRANSAC ci error

* increased windows timeout (probably caused by gftt fix now extracting more features)
This commit is contained in:
matlabbe
2026-09-22 14:41:07 -07:00
committed by GitHub
parent 9ed83a71db
commit 16fb2f0541
30 changed files with 719 additions and 278 deletions
+93
View File
@@ -0,0 +1,93 @@
name: android
# Android build environments (docker/noble/android/rtabmap_apiXX).
# amd64 only, so a single native runner and no manifest juggling.
# Note: these build FROM introlab3it/rtabmap:android-noble-deps, which is not
# produced by any workflow; it is still built and pushed by hand.
on:
push:
branches:
- 'master'
paths: &android_paths
# What an Android build actually compiles: CMakeLists.txt adds only
# utilite, corelib and app under IF(ANDROID), and rtabmap.bash builds with
# WITH_OPENGV=OFF, BUILD_EXAMPLES=OFF, BUILD_TOOLS=OFF.
- 'CMakeLists.txt'
- 'Version.h.in'
- 'RTABMapConfig.cmake.in'
- 'cmake_uninstall.cmake.in'
- 'cmake_modules/**'
- 'utilite/**'
- 'corelib/**'
- 'app/**'
- 'docker/noble/android/**'
- '.github/workflows/android.yml'
pull_request:
branches:
- '**'
paths: *android_paths
workflow_dispatch:
concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: ${{ github.event_name == 'pull_request' }}
jobs:
docker:
# A manual dispatch is honored only on master, the only ref we push from.
if: ${{ github.event_name != 'workflow_dispatch' || github.ref == 'refs/heads/master' }}
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
docker_tag: [android23, android24, android26, android30]
include:
- docker_tag: android23
docker_tags: |
introlab3it/rtabmap:android23
introlab3it/rtabmap:tango
api_version: 23
- docker_tag: android24
docker_tags: |
introlab3it/rtabmap:android24
api_version: 24
- docker_tag: android26
docker_tags: |
introlab3it/rtabmap:android26
api_version: 26
- docker_tag: android30
docker_tags: |
introlab3it/rtabmap:android30
api_version: 30
steps:
-
name: Checkout
uses: actions/checkout@v4
-
name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
-
name: Login to DockerHub
# Only needed when pushing; skipped on pull requests (secrets are
# unavailable for fork PRs and we don't push there anyway).
if: github.event_name != 'pull_request'
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: ${{ github.event_name != 'pull_request' }}
platforms: linux/amd64
file: ./docker/noble/android/rtabmap_apiXX/Dockerfile
build-args: |
API_VERSION=${{ matrix.api_version }}
tags: ${{ matrix.docker_tags }}
cache-from: type=registry,ref=introlab3it/rtabmap:${{ matrix.docker_tag }}
cache-to: type=inline
+7
View File
@@ -4,9 +4,16 @@ on:
push:
branches:
- master
paths-ignore: &platform_only
- '.github/workflows/android.yml'
- '.github/workflows/ios.yml'
- 'app/android/**'
- 'app/ios/**'
- 'docker/noble/android/**'
pull_request:
branches:
- '**'
paths-ignore: *platform_only
workflow_dispatch:
env:
+7
View File
@@ -4,9 +4,16 @@ on:
push:
branches:
- master
paths-ignore: &platform_only
- '.github/workflows/android.yml'
- '.github/workflows/ios.yml'
- 'app/android/**'
- 'app/ios/**'
- 'docker/noble/android/**'
pull_request:
branches:
- '**'
paths-ignore: *platform_only
workflow_dispatch:
env:
+7
View File
@@ -4,9 +4,16 @@ on:
push:
branches:
- master
paths-ignore: &platform_only
- '.github/workflows/android.yml'
- '.github/workflows/ios.yml'
- 'app/android/**'
- 'app/ios/**'
- 'docker/noble/android/**'
pull_request:
branches:
- '**'
paths-ignore: *platform_only
workflow_dispatch:
env:
+7
View File
@@ -4,9 +4,16 @@ on:
push:
branches:
- master
paths-ignore: &platform_only
- '.github/workflows/android.yml'
- '.github/workflows/ios.yml'
- 'app/android/**'
- 'app/ios/**'
- 'docker/noble/android/**'
pull_request:
branches:
- '**'
paths-ignore: *platform_only
workflow_dispatch:
env:
+7
View File
@@ -4,9 +4,16 @@ on:
push:
branches:
- master
paths-ignore: &platform_only
- '.github/workflows/android.yml'
- '.github/workflows/ios.yml'
- 'app/android/**'
- 'app/ios/**'
- 'docker/noble/android/**'
pull_request:
branches:
- '**'
paths-ignore: *platform_only
workflow_dispatch:
concurrency:
+227
View File
@@ -0,0 +1,227 @@
name: docker-ros
# ROS images: focal/noetic (ROS1) and jammy/humble, noble/jazzy, noble-kilted,
# resolute (ROS2). Android images live in android.yml.
#
# Every arch is built natively: amd64 on an x86 runner, arm64 on a GitHub
# arm64 runner, so no QEMU emulation is involved. Because a single Docker Hub
# tag cannot hold two independently pushed architectures, each build pushes an
# arch-suffixed tag (e.g. :resolute-amd64 / :resolute-arm64) and a final job
# joins them into the real multi-arch tag (:resolute) 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).
# That is also why focal can sit in this matrix: a 20.04 userland runs fine on
# a newer host kernel, and ros:noetic-perception publishes a native arm64 image.
on:
push:
branches:
- 'master'
paths-ignore: &platform_only
- '.github/workflows/android.yml'
- '.github/workflows/ios.yml'
- 'app/android/**'
- 'app/ios/**'
- 'docker/noble/android/**'
pull_request:
branches:
- '**'
paths-ignore: *platform_only
workflow_dispatch:
concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: ${{ github.event_name == 'pull_request' }}
jobs:
docker_deps:
# The ###-deps images used to be too flaky to build here at all (seg faults,
# arm64 build timeouts under QEMU -- see
# https://github.com/introlab/rtabmap/issues/1454) and had to be built by
# hand from a 20.04 box with an upgraded qemu-user-static. Building each
# arch natively removes that cause.
# Skipped on pull requests; built and pushed only from master (push or
# manual dispatch), since it pushes the :*-deps tags to Docker Hub.
#
# focal is deliberately absent: its ROS1/noetic deps are frozen, so
# :focal-deps is built by hand on the rare occasion it changes. The focal
# runtime image below still builds here, FROM the published :focal-deps.
if: github.ref == 'refs/heads/master'
runs-on: ${{ matrix.runner }}
strategy:
fail-fast: false
matrix:
docker_dir: [jammy, noble, noble-kilted, resolute]
arch: [amd64, arm64]
include:
- 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 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_platform }}
file: ./docker/${{ matrix.docker_dir }}/deps/Dockerfile
tags: introlab3it/rtabmap:${{ matrix.docker_dir }}-deps-${{ matrix.arch }}
cache-from: type=registry,ref=introlab3it/rtabmap:${{ matrix.docker_dir }}-deps-${{ matrix.arch }}
cache-to: type=inline
docker_deps_manifest:
needs: docker_deps
# Same gate as docker_deps, so both are skipped together on pull requests
# (github.ref is refs/pull/<n>/merge there): the per-arch -deps tags this
# joins are only ever pushed from master.
if: ${{ !cancelled() && !failure() && github.ref == 'refs/heads/master' }}
runs-on: ubuntu-26.04
strategy:
fail-fast: false
matrix:
docker_dir: [jammy, noble, noble-kilted, resolute]
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:${{ matrix.docker_dir }}-deps \
introlab3it/rtabmap:${{ matrix.docker_dir }}-deps-amd64 \
introlab3it/rtabmap:${{ matrix.docker_dir }}-deps-arm64
docker:
needs: docker_deps_manifest
# Run even when the deps jobs are skipped (they are, on pull requests):
# the runtime Dockerfiles then pull the :*-deps manifest already on Docker Hub.
# A manual dispatch is honored only on master, the only ref we push from.
if: ${{ !cancelled() && !failure() && (github.event_name != 'workflow_dispatch' || github.ref == 'refs/heads/master') }}
runs-on: ${{ matrix.runner }}
strategy:
fail-fast: false
matrix:
docker_dir: [focal, jammy, noble, noble-kilted, resolute]
arch: [amd64, arm64]
include:
- 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 Docker Buildx
uses: docker/setup-buildx-action@v3
-
name: Login to DockerHub
# Only needed when pushing; skipped on pull requests (secrets are
# unavailable for fork PRs and we don't push there anyway).
if: github.event_name != 'pull_request'
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: ${{ github.event_name != 'pull_request' }}
platforms: ${{ matrix.docker_platform }}
file: ./docker/${{ matrix.docker_dir }}/Dockerfile
build-args: |
RUN_TESTS=1
tags: introlab3it/rtabmap:${{ matrix.docker_dir }}-${{ matrix.arch }}
cache-from: type=registry,ref=introlab3it/rtabmap:${{ matrix.docker_dir }}-${{ matrix.arch }}
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/master') }}
runs-on: ubuntu-26.04
strategy:
fail-fast: false
matrix:
docker_dir: [focal, jammy, noble, noble-kilted, resolute]
include:
- docker_dir: focal
docker_tags: |
introlab3it/rtabmap:focal
introlab3it/rtabmap:20.04
- docker_dir: jammy
docker_tags: |
introlab3it/rtabmap:jammy
introlab3it/rtabmap:22.04
- docker_dir: noble
docker_tags: |
introlab3it/rtabmap:noble
introlab3it/rtabmap:24.04
- docker_dir: noble-kilted
docker_tags: |
introlab3it/rtabmap:noble-kilted
# :latest tracks the newest ROS2 image (currently resolute, ROS2 lyrical
# on ubuntu 26.04) -- move it along with the next distro bump.
- docker_dir: resolute
docker_tags: |
introlab3it/rtabmap:resolute
introlab3it/rtabmap:26.04
introlab3it/rtabmap: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
env:
DOCKER_TAGS: ${{ matrix.docker_tags }}
run: |
tag_args=()
while read -r tag; do
if [ -n "$tag" ]; then
tag_args+=(-t "$tag")
fi
done <<< "$DOCKER_TAGS"
docker buildx imagetools create "${tag_args[@]}" \
introlab3it/rtabmap:${{ matrix.docker_dir }}-amd64 \
introlab3it/rtabmap:${{ matrix.docker_dir }}-arm64
-243
View File
@@ -1,243 +0,0 @@
name: docker
on:
push:
branches:
- 'master'
pull_request:
branches:
- '**'
workflow_dispatch:
concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: ${{ github.event_name == 'pull_request' }}
jobs:
docker_deps:
# Disabling ###-deps step from CI because it is too flaky (seg faults, arm64 build timeout...)
# Only way I was able to build all images is to do it from a ubuntu 20.04 computer with:
# $ sudo add-apt-repository ppa:canonical-server/server-backports
# $ sudo apt-get update
# $ sudo apt-get upgrade qemu-user-static
# $ docker run --rm --privileged multiarch/qemu-user-static --reset -p yes -c yes
# More info: https://github.com/introlab/rtabmap/issues/1454
# Skipped on pull requests; built and pushed only from master (push or
# manual dispatch), since it pushes the :*-deps tags to Docker Hub.
if: github.ref == 'refs/heads/master'
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
docker_tag: [focal-deps, jammy-deps, noble-deps, noble-kilted-deps, resolute-deps]
include:
- docker_tag: focal-deps
docker_tags: |
introlab3it/rtabmap:focal-deps
docker_platforms: |
linux/amd64
linux/arm64
docker_path: 'focal/deps'
- docker_tag: jammy-deps
docker_tags: |
introlab3it/rtabmap:jammy-deps
docker_platforms: |
linux/amd64
linux/arm64
docker_path: 'jammy/deps'
- docker_tag: noble-deps
docker_tags: |
introlab3it/rtabmap:noble-deps
docker_platforms: |
linux/amd64
linux/arm64
docker_path: 'noble/deps'
- docker_tag: noble-kilted-deps
docker_tags: |
introlab3it/rtabmap:noble-kilted-deps
docker_platforms: |
linux/amd64
linux/arm64
docker_path: 'noble-kilted/deps'
- docker_tag: resolute-deps
docker_tags: |
introlab3it/rtabmap:resolute-deps
docker_platforms: |
linux/amd64
linux/arm64
docker_path: 'resolute/deps'
steps:
-
name: Checkout
uses: actions/checkout@v2
-
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: ${{ matrix.docker_tags }}
cache-from: type=registry,ref=introlab3it/rtabmap:${{ matrix.docker_tag }}
cache-to: type=inline
docker:
needs: docker_deps
# Run even when docker_deps is skipped (it is, on pull requests).
# A manual dispatch is honored only on master, the only ref we push from.
if: ${{ !cancelled() && !failure() && (github.event_name != 'workflow_dispatch' || github.ref == 'refs/heads/master') }}
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
docker_tag: [bionic, focal, jammy, noble, noble-kilted, resolute, android23, android24, android26, android30]
include:
- docker_tag: bionic
docker_tags: |
introlab3it/rtabmap:bionic
introlab3it/rtabmap:18.04
docker_args: |
NOT_USED=0
docker_platforms: |
linux/amd64
linux/arm64
docker_path: 'bionic'
- docker_tag: focal
docker_tags: |
introlab3it/rtabmap:focal
introlab3it/rtabmap:20.04
introlab3it/rtabmap:latest
docker_args: |
NOT_USED=0
docker_platforms: |
linux/amd64
linux/arm64
docker_path: 'focal'
- docker_tag: jammy
docker_tags: |
introlab3it/rtabmap:jammy
introlab3it/rtabmap:22.04
docker_args: |
NOT_USED=0
docker_platforms: |
linux/amd64
linux/arm64
docker_path: 'jammy'
- docker_tag: noble
docker_tags: |
introlab3it/rtabmap:noble
introlab3it/rtabmap:24.04
docker_args: |
NOT_USED=0
docker_platforms: |
linux/amd64
linux/arm64
docker_path: 'noble'
- docker_tag: noble-kilted
docker_tags: |
introlab3it/rtabmap:noble-kilted
docker_args: |
NOT_USED=0
docker_platforms: |
linux/amd64
linux/arm64
docker_path: 'noble-kilted'
- docker_tag: resolute
docker_tags: |
introlab3it/rtabmap:resolute
introlab3it/rtabmap:26.04
docker_args: |
NOT_USED=0
docker_platforms: |
linux/amd64
linux/arm64
docker_path: 'resolute'
- docker_tag: android23
docker_tags: |
introlab3it/rtabmap:android23
introlab3it/rtabmap:tango
docker_args: |
API_VERSION=23
docker_platforms: |
linux/amd64
docker_path: 'noble/android/rtabmap_apiXX'
- docker_tag: android24
docker_tags: |
introlab3it/rtabmap:android24
docker_args: |
API_VERSION=24
docker_platforms: |
linux/amd64
docker_path: 'noble/android/rtabmap_apiXX'
- docker_tag: android26
docker_tags: |
introlab3it/rtabmap:android26
docker_args: |
API_VERSION=26
docker_platforms: |
linux/amd64
docker_path: 'noble/android/rtabmap_apiXX'
- docker_tag: android30
docker_tags: |
introlab3it/rtabmap:android30
docker_args: |
API_VERSION=30
docker_platforms: |
linux/amd64
docker_path: 'noble/android/rtabmap_apiXX'
steps:
-
name: Checkout
uses: actions/checkout@v2
-
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
# Only needed when pushing; skipped on pull requests (secrets are
# unavailable for fork PRs and we don't push there anyway).
if: github.event_name != 'pull_request'
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: ${{ github.event_name != 'pull_request' }}
platforms: ${{ github.event_name == 'pull_request' && 'linux/amd64' || matrix.docker_platforms }}
file: ./docker/${{ matrix.docker_path }}/Dockerfile
build-args: |
${{ matrix.docker_args }}
tags: ${{ matrix.docker_tags }}
cache-from: type=registry,ref=introlab3it/rtabmap:${{ matrix.docker_tag }}
cache-to: type=inline