POSIX/SITL builds on macOS produce two classes of benign warnings that
clutter output and obscure real issues:
ranlib: warning: 'lib*.a(foo.o)' has no symbols
ld: warning: ignoring duplicate libraries: ...
The ranlib warnings come from sources wrapped in #if defined(CONFIG_*)
guards (i2c.cpp, spi.cpp, board_common.c, pab_manifest.c,
px4_log_history.cpp) and dummy.cpp placeholders, which legitimately
compile to empty object files on POSIX. GNU ranlib ignores this;
Apple's warns. The warning is emitted by 'ar qc' (which implicitly
builds a symbol table), not by ranlib itself, so overriding only
ARCHIVE_FINISH is insufficient. Use 'ar qcS' to skip the implicit
symbol table, then let ranlib -no_warning_for_no_symbols build it
quietly via ARCHIVE_FINISH.
The duplicate-library warnings come from CMake intentionally
re-emitting static libraries on the link line to resolve circular
dependencies between px4_layer, px4_work_queue, px4_daemon and
lockstep_scheduler. GNU ld silently dedupes; Apple's ld-prime
(Xcode 15+) warns. Pass -no_warn_duplicate_libraries to the linker.
Both fixes are Darwin-only and have no effect on Linux CI or NuttX
builds.
Signed-off-by: Ramon Roche <mrpollo@gmail.com>
Switch the Static Analysis workflow to two modes:
- Push to main: run the full "make clang-tidy" target as before.
- Pull request: build the clang compile database with
"make px4_sitl_default-clang", then call Tools/ci/run-clang-tidy-pr.py
(already in-tree) to compute the translation units actually affected
by the PR diff and run clang-tidy only on that subset. PRs that touch
no C++ files exit silently; the large majority of PRs will skip the
slow full analysis entirely.
Replace the inline ccache restore/config/save steps with the composite
actions from .github/actions/setup-ccache and .github/actions/save-ccache,
which use content-hash cache keys (prefix-ref-sha with ref and base_ref
fallbacks), compression, and compiler_check=content. Same 120M cap.
Add a second job, post_clang_tidy_comments, that runs on a GitHub-hosted
runner when the analysis job reports has_findings=true. It downloads the
compile_commands.json artifact produced by the analysis job, rewrites
the AWS RunsOn workspace prefix (/__w/PX4-Autopilot/PX4-Autopilot) to the
GitHub-hosted runner workspace so clang-tidy can chdir into the build
directory, runs clang-tidy-diff-18 to export fixes, and posts inline
review annotations via platisd/clang-tidy-pr-comments@v1.
Annotations are set to request changes (request_changes: true), so a PR
with new clang-tidy findings will be blocked until they are addressed or
waived. suggestions_per_comment is capped at 10. Annotations are gated
to same-repo PRs only; forks skip the annotation job because GITHUB_TOKEN
has no write access there.
The post_clang_tidy_comments job uses if: always() && ... so it runs
whether the analysis job succeeded or failed (findings still need to be
surfaced when the analysis exits non-zero).
Signed-off-by: Ramon Roche <mrpollo@gmail.com>
Standardize on the GitHub Container Registry copy of px4-dev:v1.17.0-rc2
across workflows still pulling the old dockerhub v1.16.0-rc1 image, and
move the workflows that were already on v1.17.0-beta1 from docker.io to
ghcr.io so the whole repo pulls from one registry at the same version.
Also modernize the "git ownership workaround" in the touched workflows
that still used `git config --global --add safe.directory "$GITHUB_WORKSPACE"`
to the `--system --add safe.directory '*'` form already in use by
clang-tidy, flash_analysis, failsafe_sim, itcm_check, and docs-orchestrator.
Updated workflows:
- checks.yml
- clang-tidy.yml (was on v1.17.0-beta1, now on rc2)
- docs-orchestrator.yml (was on v1.17.0-beta1, two jobs)
- ekf_functional_change_indicator.yml
- ekf_update_change_indicator.yml
- failsafe_sim.yml
- flash_analysis.yml
- itcm_check.yml
- nuttx_env_config.yml
Deliberately out of scope for this PR and deferred to focused follow-ups:
- fetch-depth: 0 to 1 (firmware builds and flash_analysis base-ref
checkout need git history)
- PX4_SBOM_DISABLE removal in checks.yml (behavioral change)
- fail-fast: false to true (behavioral change)
- codecov-action upgrade
No other workflows touched. compile_ubuntu.yml, ros_integration_tests.yml,
sitl_tests.yml, mavros_*_tests.yml, fuzzing.yml, build_deb_package.yml,
dev_container.yml all use different image families or serve different
purposes and are not part of this sweep.
Signed-off-by: Ramon Roche <mrpollo@gmail.com>
Add four reusable building blocks that upcoming CI optimization PRs will
consume. No existing workflow is modified; these files are dormant until
referenced.
- .github/actions/setup-ccache: restore ~/.ccache with content-hash keys,
write ccache.conf with compression and content-based compiler check
- .github/actions/save-ccache: print stats and save the cache under the
primary key produced by setup-ccache
- .github/actions/build-gazebo-sitl: build px4_sitl_default plus the
Gazebo Classic plugins with ccache stats between stages
- Tools/ci/run-clang-tidy-pr.py: compute the translation units affected
by a PR diff and invoke Tools/run-clang-tidy.py on that subset only,
exiting silently when no C++ files changed
Signed-off-by: Ramon Roche <mrpollo@gmail.com>
Split the maintainer role into two types to make it easier to grow the
bench without asking new contributors to commit to a specific component
up front. Code Owners keep their existing scoped responsibility for a
category, while Reviewers help across the project without ownership of
any specific area. Both are full maintainers, share the @PX4/dev-team
GitHub team, and have the same write access and voting rights.
Rename the Active Maintainers table to Code Owners with no change to
the current roster. Add an empty Reviewers table so future nominations
land in their own PRs. Update the contributor docs to describe the two
types, cover both in the recruitment and onboarding flow, and note the
promotion path from Reviewer to Code Owner.
Signed-off-by: Ramon Roche <mrpollo@gmail.com>
* offboard: report specific failures
Figuring out offboard failures is quite difficult because the user currently
gets a single, very generic error message that does not identify the actual
missing requirement.
This change aims to improve the user experience by:
- moving offboard failure reporting into OffboardChecks, where the exact cause is known
- reporting specific arming failures for missing local position, local velocity and attitude estimates
- keeping the generic offboard signal error only as a fallback for true signal-loss cases
- removing the duplicate offboard check from ModeChecks (as already invoked by HealthAndArmingChecks)
Signed-off-by: Onur Özkan <work@onurozkan.dev>
* offboard: handle attitude mode in offboard check
Signed-off-by: Onur Özkan <work@onurozkan.dev>
---------
Signed-off-by: Onur Özkan <work@onurozkan.dev>
The previous logic used GITHUB_HEAD_REF, which on a pull request is
the source (PR author's) branch name. For backport PRs (e.g.
mrpollo/backport-26781-1.17), no matching branch exists in
px4-ros2-interface-lib, so the script fell back to main and the
build broke from uORB message divergence.
Switch to GITHUB_BASE_REF, which on a PR is the branch the code is
being merged into (main or release/X.Y), and fall back to
GITHUB_REF_NAME for direct pushes. This always resolves to a real
branch in px4-ros2-interface-lib.
Signed-off-by: Ramon Roche <mrpollo@gmail.com>
Adds an explicit Citation section before Governance so researchers can
copy a canonical BibTeX entry without clicking through to Zenodo. Uses
the same author list and concept DOI as CITATION.cff so the citation
always resolves to the latest release. Follows the pattern used by
borglab/gtsam and huggingface/transformers.
Signed-off-by: Ramon Roche <mrpollo@gmail.com>
Split badges into two rows: release/DOI/Discord on top, and LF-ecosystem
health signals (OpenSSF Best Practices, LFX Health Score, Contributors,
Active Contributors) below. Removed the noisy "Build all targets" badge
and switched the Discord badge from the pixelated widget PNG to the
shields.io SVG endpoint so it renders crisply on HiDPI displays.
Signed-off-by: Ramon Roche <mrpollo@gmail.com>
Upgrades the project Code of Conduct from Contributor Covenant v1.4
(2016) to v2.1 (2021). v2.1 adds the Enforcement Guidelines section
(Correction / Warning / Temporary Ban / Permanent Ban) and modernizes
the language around inclusion and community leadership.
Replaces the personal reporting address (lorenz@px4.io) with an
institutional one (coc@dronecode.org) so Code of Conduct reports flow
to the Dronecode Foundation rather than a single maintainer's inbox.
Signed-off-by: Ramon Roche <mrpollo@gmail.com>
Add 'if: startsWith(runner.name, "runs-on--")' to the mirror swap step
in both workflows so fork users can see at a glance that the step only
fires on runs-on runners and is a no-op on standard GitHub-hosted
runners. The script keeps its internal RUNS_ON_AWS_REGION check as
defense in depth for callers outside these workflows.
Signed-off-by: Ramon Roche <mrpollo@gmail.com>
The mirror swap was duplicated across two workflows. Move it into
Tools/ci/use_aws_apt_mirror.sh and call the script from each workflow
after checkout but before any heavy apt work like Tools/setup/ubuntu.sh.
The script no-ops outside runs-on (RUNS_ON_AWS_REGION unset), so it is
safe to call from forks, self-hosted runners, or local container runs
without changing behavior there. The region is read from the runs-on
environment instead of being hardcoded, so future region changes only
need updating where the runner is provisioned.
The bootstrap 'apt install git' step keeps the default mirror because
git is one package and is unlikely to hit the dep11 desync issue that
broke ubuntu.sh.
Signed-off-by: Ramon Roche <mrpollo@gmail.com>
The compile_ubuntu workflow's apt operations talk directly to
archive.ubuntu.com, which round-robins across community mirrors that
occasionally serve out-of-sync index files mid-sync and break apt update
for everyone until the upstream catches up.
Apply the same mirror swap as build_deb_package.yml: rewrite the
container's apt sources to point at us-west-2.ec2.archive.ubuntu.com
before any apt operation runs, so both the inline 'apt update' and the
later Tools/setup/ubuntu.sh call benefit from the regional mirror.
Signed-off-by: Ramon Roche <mrpollo@gmail.com>
The SIH image is the canonical PX4 SITL container, so drop the redundant
-sih suffix and publish it as px4io/px4-sitl. Gazebo continues to publish
as px4io/px4-sitl-gazebo.
Decouples the published image name from the matrix.image identifier by
introducing a matrix.repo field, so renames like this don't require
touching the matrix logic.
This is a breaking change for anyone pulling px4io/px4-sitl-sih directly;
the old tags remain available but no new ones will be published under
that name.
Signed-off-by: Ramon Roche <mrpollo@gmail.com>
The default archive.ubuntu.com round-robin can serve out-of-sync index
files mid-sync, which makes apt-get update fail with 'File has unexpected
size' errors and breaks the deb build job for everyone until the upstream
mirror catches up.
Rewrite the container's apt sources to point at us-west-2.ec2.archive.
ubuntu.com instead. The EC2 archive mirrors are Canonical-operated,
region-local to the runs-on instances, and sync aggressively, eliminating
the round-robin lottery as a CI failure mode.
Signed-off-by: Ramon Roche <mrpollo@gmail.com>
The SIH container entrypoint resolves host.docker.internal via getent
hosts and feeds the first result to mavlink -t and uxrce_dds_client -h.
On Docker Desktop for Windows the lookup can return an IPv6 ULA first,
and both PX4 modules only parse IPv4, so they error out with
'invalid partner ip' and PX4 boots with no working MAVLink or DDS link.
Switch to getent ahostsv4, which only returns IPv4 records, so the IP
injected into the startup scripts is always parseable.
Signed-off-by: Ramon Roche <mrpollo@gmail.com>
The current workflow_dispatch path builds whatever HEAD of the dispatch ref
is, labels the resulting image with px4_version, and publishes. That's
fine for rebuilding current state but it cannot rebuild the exact commit
a release tag points to, because the dispatch loads the workflow file
from one ref and implicitly checks out the same ref for the build.
This matters for release recovery. When the v1.17.0-rc2 tag push failed
to publish containers back on 2026-03-13 (the v1 GHA cache protocol
removal in RunsOn v2.12.0), the tag was not re-pushed, so the only way
to publish rc2 containers now is via workflow_dispatch. Without this
change, a dispatch against release/1.17 builds release/1.17 HEAD and
labels it v1.17.0-rc2, which produces a container whose contents do not
match the rc2 tag's actual code. That is not a faithful recovery.
Add a build_ref input that controls only the checkout ref, defaulting
to empty which falls back to github.ref (preserving current behavior
for both push events and dispatches that omit the input). With this,
a release recovery looks like:
gh workflow run dev_container.yml --repo PX4/PX4-Autopilot \
--ref release/1.17 \
-f px4_version=v1.17.0-rc2 \
-f build_ref=v1.17.0-rc2 \
-f deploy_to_registry=true
The workflow loads from release/1.17 HEAD (which has the cache fix
from 39b0568 and the hardening from d74db56a), but the build uses
Tools/setup/Dockerfile from the rc2 tag. The published image has
rc2 contents under the rc2 label, as if the original tag push had
worked.
All three actions/checkout steps (setup, build, deploy) take the same
ref expression so every job sees a consistent workspace. Non-dispatch
events (push, PR) evaluate github.event.inputs.build_ref to empty and
fall back to github.ref exactly as before.
Signed-off-by: Ramon Roche <mrpollo@gmail.com>
Drops --upload from the ROS integration test runner so CI runs no
longer publish ULogs to the public logs.px4.io server on every run.
Failure debugging is unaffected: the existing Upload failed logs step
already captures logs as GitHub Actions artifacts on failure.
Signed-off-by: Ramon Roche <mrpollo@gmail.com>
Extract the repeated `offboard_control_mode_s` population logic into a shared
`fill_offboard_control_mode()` helper in MavlinkReceiver and, similar to
`fill_thrust()`, reuse it in both local and global position target handlers.
Reduces the code duplication without changing any behavior.
Signed-off-by: Onur Özkan <work@onurozkan.dev>
Three related fixes to prevent a repeat of the v1.17.0-rc2 incident, where a
post-push GHA cache-export 404 failed the arm64 build after both registry
pushes had already succeeded, fail-fast cancelled amd64, and the deploy job
was skipped, leaving the registries with only a partial arm64 publish and no
multi-arch manifest.
- Mark cache export as non-fatal via ignore-error=true on cache-to. A
successful registry push should never be undone by a cache-layer flake.
This alone would have let rc2 publish correctly.
- Decouple the deploy job from the build job's exit code. Change its if:
gate to !cancelled() + setup success only, and promote the existing
"Verify Images Exist Before Creating Manifest" step from a warning into
a hard precondition. Deploy now runs whenever both per-arch tags actually
exist in the registries, which is its real precondition, and fails loudly
if a tag is missing.
- Bump every action to the current major (runs-on/action v2,
actions/checkout v5, docker/login-action v4, docker/setup-buildx-action v4,
docker/build-push-action v7, docker/metadata-action v6). This gets the
workflow off Node 20 before GitHub's June 2 2026 forced runtime switch
and keeps runs-on/action on the same major as the runs-on platform.
Signed-off-by: Ramon Roche <mrpollo@gmail.com>