Skip to content

ci(ios): package .app as .ipa before artifact upload#14441

Draft
farhangnaderi wants to merge 8 commits into
mavlink:masterfrom
farhangnaderi:fix/ios-ipa-packaging
Draft

ci(ios): package .app as .ipa before artifact upload#14441
farhangnaderi wants to merge 8 commits into
mavlink:masterfrom
farhangnaderi:fix/ios-ipa-packaging

Conversation

@farhangnaderi
Copy link
Copy Markdown
Contributor

@farhangnaderi farhangnaderi commented May 28, 2026

Description

GitHub Actions upload-artifact wraps directory inputs (like .app bundles) in a zip. This packages the .app as a proper .ipa first so the downloaded artifact has the correct iOS format. Am trying to produce artifacts here from CI to see if it fixes.

Type of Change

  • Bug fix (non-breaking change that fixes an issue)
  • New feature (non-breaking change that adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)
  • Documentation update
  • Refactoring (no functional changes)
  • CI/Build changes
  • Other

Testing

  • Tested locally
  • Added/updated unit tests
  • Tested with simulator (SITL)
  • Tested with hardware

Platforms Tested

  • Linux
  • Windows
  • macOS
  • Android
  • iOS

Related Issues


By submitting this pull request, I confirm that my contribution is made under the terms of the project's dual license (Apache 2.0 and GPL v3).

GitHub Actions upload-artifact wraps directory inputs in a zip, so
uploading QGroundControl.app directly produces a .zip download.
Package the .app into a proper IPA (Payload/App.app zipped) first so
the artifact is a single file with the correct iOS distribution format.
Copilot AI review requested due to automatic review settings May 28, 2026 23:01
@farhangnaderi farhangnaderi requested a review from HTRamsey as a code owner May 28, 2026 23:01
@github-actions github-actions Bot added github_actions Pull requests that update GitHub Actions code size/XS labels May 28, 2026
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Note

Copilot was unable to run its full agentic suite in this review.

Adds an explicit packaging step to produce an .ipa from the Release build output and updates the existing attest/upload step to publish the .ipa artifact.

Changes:

  • Add a “Package IPA” step for Release builds that zips the .app into an .ipa.
  • Switch the attest/upload inputs from .app to .ipa.

Comment thread .github/workflows/ios.yml
cd "$APP_DIR"
mkdir -p Payload
cp -r "${{ env.PACKAGE }}.app" Payload/
zip -r "${{ env.PACKAGE }}.ipa" Payload/
Comment thread .github/workflows/ios.yml
Comment on lines +88 to +92
run: |
APP_DIR="${{ runner.temp }}/build/${{ matrix.build_type }}"
cd "$APP_DIR"
mkdir -p Payload
cp -r "${{ env.PACKAGE }}.app" Payload/
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 28, 2026

Build Results

Platform Status

Platform Status Details
Linux Passed View
Windows Passed View
MacOS Passed View
Android Passed View

All builds passed.

Pre-commit

Check Status Details
pre-commit Failed (non-blocking) View

Pre-commit hooks: 2 passed, 42 failed, 7 skipped.

Test Results

linux-coverage: 88 passed, 0 skipped
Total: 88 passed, 0 skipped

Code Coverage

Coverage: 60.4%

No baseline available for comparison

Artifact Sizes

Artifact Size
QGroundControl 216.77 MB
QGroundControl-aarch64 176.66 MB
QGroundControl-installer-AMD64 134.67 MB
QGroundControl-installer-AMD64-ARM64 77.50 MB
QGroundControl-installer-ARM64 106.01 MB
QGroundControl-linux 186.86 MB
QGroundControl-mac 186.86 MB
QGroundControl-windows 186.87 MB
QGroundControl-x86_64 172.32 MB
No baseline available for comparison

Updated: 2026-05-29 19:28:15 UTC • Triggered by: Linux

MACOSX_BUNDLE_INFO_PLIST was unconditionally set to the macOS plist.
The iOS override only set XCODE_ATTRIBUTE_INFOPLIST_FILE, which is
Xcode-generator-only. With Ninja, the bundle got the macOS Info.plist
(LSMinimumSystemVersion instead of LSRequiresIPhoneOS), causing
sideloading tools to reject it as an invalid iOS app.
@github-actions github-actions Bot added the CMake label May 28, 2026
@codecov
Copy link
Copy Markdown

codecov Bot commented May 29, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 26.45%. Comparing base (f29efd3) to head (2f5bedc).
⚠️ Report is 35 commits behind head on master.

❌ Your project check has failed because the head coverage (26.45%) is below the target coverage (30.00%). You can increase the head coverage or adjust the target coverage.

Additional details and impacted files

Impacted file tree graph

@@            Coverage Diff             @@
##           master   #14441      +/-   ##
==========================================
+ Coverage   25.47%   26.45%   +0.98%     
==========================================
  Files         769      767       -2     
  Lines       65912    66285     +373     
  Branches    30495    30667     +172     
==========================================
+ Hits        16788    17538     +750     
+ Misses      37285    36304     -981     
- Partials    11839    12443     +604     
Flag Coverage Δ
unittests 26.45% <ø> (+0.98%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

Files with missing lines Coverage Δ
.../VideoManager/VideoReceiver/GStreamer/GStreamer.cc 13.98% <ø> (ø)

... and 133 files with indirect coverage changes


Continue to review full report in Codecov by Sentry.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update fe39391...2f5bedc. Read the comment docs.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

iOS-Info.plist uses Xcode build variables (e.g. $(EXECUTABLE_NAME))
that Xcode substitutes at build time but Ninja leaves as literal strings,
causing sideloading tools to fail finding the executable.

Add iOSBundleInfo.plist.in using CMake-style ${VAR} substitution for
Ninja builds. Xcode generator continues using iOS-Info.plist via
XCODE_ATTRIBUTE_INFOPLIST_FILE unchanged.
With Ninja generator, Xcode's automatic 'Embed Frameworks' build phase
doesn't run, so FFmpeg xcframeworks are not copied into the app bundle.
The binary's rpath contains the CI runner's absolute Qt path which
doesn't exist on device, causing a DYLD crash at launch.

Add a POST_BUILD command to copy xcframeworks from Qt's ffmpeg directory
into the app bundle's Frameworks/ directory, and set BUILD_RPATH to
@executable_path/Frameworks so dyld resolves them correctly on device.
GStreamerMobile is a project-built SHARED framework. With Ninja
generator, it is not automatically copied into the app bundle.
Add a POST_BUILD command in FindGStreamerMobile to copy it into
QGroundControl.app/Frameworks/ on iOS non-Xcode builds.
The previous attempt added add_custom_command in FindGStreamerMobile.cmake,
but that runs before add_subdirectory(src) creates the GStreamerMobile
target so CMake silently ignored it.

Use cmake_language(DEFER DIRECTORY root ...) in Apple.cmake so the
post-build copy is registered after all subdirectories are processed
and the GStreamerMobile target exists. Use TARGET_FILE_DIR instead of
TARGET_BUNDLE_DIR for the framework source path as it reliably resolves
to the .framework directory on iOS.
@farhangnaderi farhangnaderi marked this pull request as draft May 29, 2026 09:36
gst_ffmpeg_cfg_init hits a g_assert failure when the GStreamer libav
plugin initializes on iOS, aborting the app at launch. iOS has hardware
video decoding via applemedia, so libav/FFmpeg software decoding via
GStreamer is not needed.

Guard GST_PLUGIN_STATIC_DECLARE/REGISTER(libav) with Q_OS_IOS in
GStreamer.cc, and remove libav from the iOS GStreamer plugin list in
FindQGCGStreamer.cmake so it is not linked into gstreamer_mobile.
applemedia directly interfaces with Apple media APIs that change
between iOS versions. On iOS 26 it appears to corrupt the GStreamer
element factory registry, causing a SIGSEGV in analyze_new_pad via
gst_element_factory_get_metadata with a bad pointer. Remove it to
use software decoding path instead.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

CMake github_actions Pull requests that update GitHub Actions code Platform: iOS size/S Video

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants