CI: per-project path-filtered workflows + per-platform releases#296
Open
patrickrb wants to merge 8 commits into
Open
CI: per-project path-filtered workflows + per-platform releases#296patrickrb wants to merge 8 commits into
patrickrb wants to merge 8 commits into
Conversation
…eases The repo holds three FT8 clients sharing one C DSP core, but all CI was Android-only and fired on every push/PR with no path filtering — an iOS-only change ran the full Android NDK build, and iOS/desktop had no CI at all. Split into per-project pipelines that only run when their files (or the shared core at ft8af/app/src/main/cpp/**) change: - android.yml: renamed from build-release.yml, folds in static-analysis.yml as a job, adds a `detect` (dorny/paths-filter) gate and an always-run `android-gate` aggregator. All existing behavior (NDK retry, signing, tag derivation, GitHub Release, Play internal publish, play-publish concurrency) is preserved; job names test/instrumented/build are unchanged. - ios.yml (new): swift test on FT8AFKit + unsigned iOS-Simulator build (xcodegen generate -> xcodebuild) on macos-14; `ios-gate` aggregator. - desktop.yml (new): Tauri compile-check on Windows/macOS/Linux for PRs and non-release pushes; on main / desktop-v* tags builds native bundles on all three OSes and publishes a namespaced desktop-v* / desktop-dev-N release via tauri-action; `desktop-gate` aggregator. Behavior model: PRs run only the affected project's checks; dev pushes build only affected platform(s) as prereleases; main pushes / tags build everything (one release per platform). native-tests.yml stays always-on as the shared-core gate; main-gate.yml and the discord workflows are untouched. Because path-filtered jobs can be skipped, the *-gate jobs always run and are the intended required status checks (a skipped required check otherwise leaves branch protection stuck "pending"). Branch protection must be updated to require android-gate / ios-gate / desktop-gate instead of the inner jobs — documented in the PR. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## dev #296 +/- ##
============================================
+ Coverage 11.15% 11.18% +0.02%
Complexity 105 105
============================================
Files 81 81
Lines 11426 11430 +4
Branches 2051 2052 +1
============================================
+ Hits 1275 1278 +3
- Misses 10023 10024 +1
Partials 128 128 🚀 New features to boost your workflow:
|
There was a problem hiding this comment.
Pull request overview
This PR restructures CI for the repo’s multi-client layout by splitting Android/iOS/desktop into separate, path-filtered workflows (including the shared C DSP core) and introducing per-platform release behavior (Android v*, desktop desktop-v*, iOS verify-only).
Changes:
- Replaced the monolithic Android-only CI triggering with per-project change detection and “always-run” gate jobs intended for branch protection (
android-gate,ios-gate,desktop-gate). - Added new iOS workflow to run
swift testfor FT8AFKit and perform an unsigned iOS Simulator build on macOS. - Added new desktop workflow to compile-check on PRs and build/publish Tauri bundles on
mainpushes anddesktop-v*tags; removed standalonestatic-analysis.ymlby folding it intoandroid.yml.
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
.github/workflows/android.yml |
Adds Android path detection, folds static analysis into Android CI, and introduces android-gate as a branch-protection-friendly aggregator. |
.github/workflows/ios.yml |
Introduces path-filtered iOS verification (Swift package tests + simulator build) with an always-run ios-gate. |
.github/workflows/desktop.yml |
Introduces path-filtered desktop CI and release publishing via Tauri across Windows/macOS/Linux with an always-run desktop-gate. |
.github/workflows/static-analysis.yml |
Deleted in favor of embedding lint/detekt/ktlint into android.yml. |
Comments suppressed due to low confidence (1)
.github/workflows/android.yml:585
android-gatedoesn't depend ondetect, so ifdetectfails,test/buildcan be skipped and the gate still reports success. Sinceandroid-gateis intended to be the required check, it should fail on a failed/cancelleddetectas well.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
…uild Address Copilot review on PR #296: - android-gate / ios-gate / desktop-gate now depend on (and check) their detect/version prerequisites, not just the build/verify/test legs. A failed `detect` (or desktop `version`) skips the downstream jobs, and a skip alone was being read as "path-filtered, nothing to do" — letting a broken workflow report success on the required check. Each gate now fails if any prerequisite result is failure/cancelled; a genuine path-skip (detect succeeded, run=false) still passes. Also fix the iOS verify job, which failed to compile: ft8_lib's `fmtmsg` collided with the POSIX `fmtmsg(long, ...)` from <fmtmsg.h>, visible when the shared C core is built under the macOS/Apple SDK (FT8AFKit swift test). Rename the unused helper to ft8_fmtmsg (no call sites anywhere in the repo). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01CDu3dtuN89JsRqxFsq1ow9
…roject The ios.yml simulator-build leg failed with "future Xcode project file format (77)": XcodeGen 2.45.4 defaults the generated pbxproj to objectVersion 77 (Xcode 16-only), but the macos-14 runner's Xcode 15.4 — matching the project's pinned xcodeVersion 15.0 — can't read it. Pin objectVersion 56, which Xcode 15 opens and Xcode 16 still accepts. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01CDu3dtuN89JsRqxFsq1ow9
…en the project" This reverts commit 98aad14.
XcodeGen 2.45.x always emits the pbxproj in Xcode 16's object format
(objectVersion 77); Xcode 15.4 on the macos-14 runner can't open it
("future Xcode project file format (77)"). Pinning objectVersion via
project.yml had no effect (not an honored XcodeGen option), so build the
simulator leg on macos-15 / Xcode 16 instead. The iOS 17 deployment target
still builds under the newer toolchain.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CDu3dtuN89JsRqxFsq1ow9
The ubuntu desktop build failed in libudev-sys's build script: "Package libudev was not found in the pkg-config search path." The serialport crate (CAT rig control) needs libudev on Linux, which the apt step wasn't installing. Add libudev-dev alongside the existing Tauri/GTK system deps. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01CDu3dtuN89JsRqxFsq1ow9
With libudev-dev in place the Linux build now gets past serialport and fails next in alsa-sys: "Package alsa was not found in the pkg-config search path." The audio crate (cpal/rodio) needs ALSA on Linux. Add libasound2-dev to the apt step. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01CDu3dtuN89JsRqxFsq1ow9
The Linux desktop build hung indefinitely on "Install Linux dependencies" while the macOS/Windows builds finished in minutes. Two fixes: - ubuntu-latest is now Ubuntu 24.04, which dropped libappindicator3-dev. Switch to libayatana-appindicator3-dev (Tauri's current Linux prereq). - Harden apt against the classic CI hangs: DEBIAN_FRONTEND=noninteractive (suppress debconf prompts -y misses) and -o DPkg::Lock::Timeout=600 (wait up to 10 min for the dpkg lock instead of forever, then fail loudly). Also --no-install-recommends to keep the install lean. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
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.
Why
The repo holds three FT8 clients that share one C DSP core (
ft8af/app/src/main/cpp/), but all CI was Android-only and fired on every push/PR with no path filtering. An iOS-only change still ran the full Android NDK build, and iOS/desktop had no CI at all. Releases were Android-only.What changed
Split into per-project pipelines that only run when their files — or the shared C core — change:
android.yml(renamed frombuild-release.yml)ft8af/**or shared coreplay-publishconcurrency); job namestest/instrumented/buildunchanged.ios.yml(new)ios/**or shared coreswift teston FT8AFKit + unsigned iOS-Simulator build (xcodegen generate→xcodebuild) onmacos-14. No release (needs Apple signing).desktop.yml(new)desktop/**or shared coremain/desktop-v*builds native bundles on all three OSes and publishes a namespaceddesktop-v*/desktop-dev-Nrelease viatauri-action.native-tests.ymlstays always-on as the shared-core golden gate.main-gate.ymland the discord workflows are untouched.static-analysis.ymlwas deleted (merged intoandroid.yml).Behavior model
dev→ only affected platform(s) build + publish a prerelease (dev-N/desktop-dev-N).main→ all platforms build, one release each (v*Android+Play,desktop-v*); iOS = verify only.v*→ Android production release (unchanged). tagdesktop-v*→ desktop production release."Affected" = project's own paths or the shared C core changed.
Path-filtered jobs can be skipped, and a skipped required check leaves branch protection stuck "pending" (already noted in
native-tests.yml). Each workflow ends with an always-run aggregator that is the intended required check. In Settings → Branches →main(anddevif protected):android-gate,ios-gate,desktop-gateFT8 encode/hash golden vectors,enforce-source-is-devUnit tests & coverage/Build APK(now reached viaandroid-gate)Verification
actionlintclean on all workflows (locally).ios/-only change runs only iOS (android/desktop gates still green via all-skipped); adesktop/-only change runs only desktop; aft8af/app/src/main/cpp/**change runs all three.Notes / risks
v*tags (drives Play + version history); only desktop is namespaced — this is the "separate release per platform" layout requested.🤖 Generated with Claude Code