From ea73f318f738bbb80eb96e802e7291c8fc29c801 Mon Sep 17 00:00:00 2001 From: Claude Date: Sat, 4 Jul 2026 17:00:52 +0000 Subject: [PATCH 1/6] build(ios): enable iOS bazel targets on Bazel 9 and mac CI rules_apple 4.5.3 / apple_support 2.7.0 (upgraded in #1163) support Bazel 9 (rules_apple#2863 was fixed by rules_apple#2868 and apple_support#497), so the Bazel 8 workarounds can go: - drop tags = ["manual"] and the stale Bazel 9 comments from the wordchains_ios targets; target_compatible_with already keeps them off Linux runs, and diff-build passes --skip_incompatible_explicit_targets - remove the USE_BAZEL_VERSION=8.2.1 pin from release-wordchains-ios - build the iOS app and run ios_unit_test with bazel in the test-ios macOS job, behind the existing wordchains path filter Co-Authored-By: Claude Fable 5 Claude-Session: https://claude.ai/code/session_01Jw99o89a2UYe9NKLE9zGUx --- .github/workflows/branch.yml | 20 +++++++++++++++++++ .github/workflows/release-wordchains-ios.yml | 4 ---- domains/games/apps/wordchains_ios/BUILD.bazel | 7 ------- 3 files changed, 20 insertions(+), 11 deletions(-) diff --git a/.github/workflows/branch.yml b/.github/workflows/branch.yml index 65593a58..4e763758 100644 --- a/.github/workflows/branch.yml +++ b/.github/workflows/branch.yml @@ -158,3 +158,23 @@ jobs: if: steps.filter.outputs.changed == 'true' working-directory: domains/games/apps/wordchains_ios run: swift test + + - uses: bazel-contrib/setup-bazel@0.18.0 + if: steps.filter.outputs.changed == 'true' + with: + bazelisk-cache: true + disk-cache: test-ios + repository-cache: true + + - name: Build iOS app with bazel + if: steps.filter.outputs.changed == 'true' + run: | + bazel build //domains/games/apps/wordchains_ios:WordChains \ + --ios_minimum_os=17.0 \ + --apple_platform_type=ios + + - name: Run iOS unit tests with bazel + if: steps.filter.outputs.changed == 'true' + run: | + bazel test //domains/games/apps/wordchains_ios:WordChainsTests \ + --ios_minimum_os=17.0 diff --git a/.github/workflows/release-wordchains-ios.yml b/.github/workflows/release-wordchains-ios.yml index 2b410b52..26dc61a5 100644 --- a/.github/workflows/release-wordchains-ios.yml +++ b/.github/workflows/release-wordchains-ios.yml @@ -143,11 +143,7 @@ jobs: disk-cache: release-wordchains-ios repository-cache: true - # rules_apple doesn't support Bazel 9 yet; pin to Bazel 8 LTS for iOS builds. - # Track: https://github.com/bazelbuild/rules_apple/issues - name: Build iOS app - env: - USE_BAZEL_VERSION: 8.2.1 run: | bazel build //domains/games/apps/wordchains_ios:WordChains \ --ios_minimum_os=17.0 \ diff --git a/domains/games/apps/wordchains_ios/BUILD.bazel b/domains/games/apps/wordchains_ios/BUILD.bazel index 50d0ea07..a915abc2 100644 --- a/domains/games/apps/wordchains_ios/BUILD.bazel +++ b/domains/games/apps/wordchains_ios/BUILD.bazel @@ -15,13 +15,9 @@ swift_library( ":word_graph_json", ], module_name = "WordChains", - tags = ["manual"], target_compatible_with = ["@platforms//os:macos"], ) -# Tagged manual: rules_apple doesn't support Bazel 9 yet. -# https://github.com/bazelbuild/rules_apple/issues/2863 -# Build with: USE_BAZEL_VERSION=8.2.1 bazel build //domains/games/apps/wordchains_ios:WordChains ios_application( name = "WordChains", bundle_id = "com.muchq.wordchains", @@ -34,7 +30,6 @@ ios_application( resources = [ ":word_graph_json", ] + glob(["Sources/Resources/**"]), - tags = ["manual"], target_compatible_with = ["@platforms//os:macos"], visibility = ["//visibility:public"], deps = [":WordChainsLib"], @@ -44,7 +39,6 @@ swift_library( name = "WordChainsTestLib", testonly = True, srcs = glob(["Tests/**/*.swift"]), - tags = ["manual"], target_compatible_with = ["@platforms//os:macos"], deps = [":WordChainsLib"], ) @@ -52,7 +46,6 @@ swift_library( ios_unit_test( name = "WordChainsTests", minimum_os_version = "17.0", - tags = ["manual"], target_compatible_with = ["@platforms//os:macos"], deps = [":WordChainsTestLib"], ) From 2575a93d458d3ac30aeadf75bb5b5ecd059f0073 Mon Sep 17 00:00:00 2001 From: Claude Date: Sat, 4 Jul 2026 17:06:23 +0000 Subject: [PATCH 2/6] fix(ios): constrain wordchains_ios targets to os:ios, not os:macos Under Bazel 9 the Apple rules transition to real target platforms (ios_sim_arm64, whose OS constraint is os:ios), so os:macos marked the ios_application incompatible with its own platform: target platform (@@apple_support+//platforms:ios_sim_arm64) didn't satisfy constraint @@platforms//os:osx The constraint only existed to keep Linux CI off these targets, and os:ios still does that (linux doesn't satisfy it) while matching the iOS transition. Bazel 8 didn't use real platforms for Apple builds, which is why os:macos used to pass. Co-Authored-By: Claude Fable 5 Claude-Session: https://claude.ai/code/session_01Jw99o89a2UYe9NKLE9zGUx --- domains/games/apps/wordchains_ios/BUILD.bazel | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/domains/games/apps/wordchains_ios/BUILD.bazel b/domains/games/apps/wordchains_ios/BUILD.bazel index a915abc2..bccbb5f7 100644 --- a/domains/games/apps/wordchains_ios/BUILD.bazel +++ b/domains/games/apps/wordchains_ios/BUILD.bazel @@ -15,7 +15,7 @@ swift_library( ":word_graph_json", ], module_name = "WordChains", - target_compatible_with = ["@platforms//os:macos"], + target_compatible_with = ["@platforms//os:ios"], ) ios_application( @@ -30,7 +30,7 @@ ios_application( resources = [ ":word_graph_json", ] + glob(["Sources/Resources/**"]), - target_compatible_with = ["@platforms//os:macos"], + target_compatible_with = ["@platforms//os:ios"], visibility = ["//visibility:public"], deps = [":WordChainsLib"], ) @@ -39,13 +39,13 @@ swift_library( name = "WordChainsTestLib", testonly = True, srcs = glob(["Tests/**/*.swift"]), - target_compatible_with = ["@platforms//os:macos"], + target_compatible_with = ["@platforms//os:ios"], deps = [":WordChainsLib"], ) ios_unit_test( name = "WordChainsTests", minimum_os_version = "17.0", - target_compatible_with = ["@platforms//os:macos"], + target_compatible_with = ["@platforms//os:ios"], deps = [":WordChainsTestLib"], ) From 47b738b362102380d76b689610f0a4e1e1056066 Mon Sep 17 00:00:00 2001 From: Claude Date: Sat, 4 Jul 2026 17:09:05 +0000 Subject: [PATCH 3/6] fix(ios): keep manual tag on Apple bundling targets for Linux CI MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The Apple bundling rules (ios_application, ios_unit_test) transition to an iOS target platform before target_compatible_with is evaluated, so os:ios is satisfied on Linux too and diff-build's --skip_incompatible_explicit_targets never kicks in — analysis fails resolving @bazel_tools//tools/cpp:toolchain_type for iOS instead: No matching toolchains found for types: @@bazel_tools//tools/cpp:toolchain_type Restore tags = ["manual"] on those two targets (diff-build queries exclude manual) with a comment explaining the real reason. The mac test-ios job and the release workflow request them by explicit label, which builds manual targets. The plain swift_library targets don't transition, so os:ios correctly skips them on Linux. Co-Authored-By: Claude Fable 5 Claude-Session: https://claude.ai/code/session_01Jw99o89a2UYe9NKLE9zGUx --- domains/games/apps/wordchains_ios/BUILD.bazel | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/domains/games/apps/wordchains_ios/BUILD.bazel b/domains/games/apps/wordchains_ios/BUILD.bazel index bccbb5f7..0cbe56e8 100644 --- a/domains/games/apps/wordchains_ios/BUILD.bazel +++ b/domains/games/apps/wordchains_ios/BUILD.bazel @@ -18,6 +18,11 @@ swift_library( target_compatible_with = ["@platforms//os:ios"], ) +# The Apple bundling rules transition to an iOS target platform before +# target_compatible_with is evaluated, so os:ios can't keep Linux CI off +# them — Linux analysis fails resolving an Apple C++ toolchain instead of +# skipping. Tag them manual; the test-ios job and the release workflow +# request them by explicit label, which builds manual targets. ios_application( name = "WordChains", bundle_id = "com.muchq.wordchains", @@ -30,6 +35,7 @@ ios_application( resources = [ ":word_graph_json", ] + glob(["Sources/Resources/**"]), + tags = ["manual"], target_compatible_with = ["@platforms//os:ios"], visibility = ["//visibility:public"], deps = [":WordChainsLib"], @@ -46,6 +52,7 @@ swift_library( ios_unit_test( name = "WordChainsTests", minimum_os_version = "17.0", + tags = ["manual"], target_compatible_with = ["@platforms//os:ios"], deps = [":WordChainsTestLib"], ) From 7ab78ede7e64bd610abeca50d371a55d59536d06 Mon Sep 17 00:00:00 2001 From: Claude Date: Sat, 4 Jul 2026 17:17:10 +0000 Subject: [PATCH 4/6] fix(ios): ios_unit_test is host-configured; constrain to os:macos ios_application transitions its own top-level platform to iOS, but ios_unit_test stays in the host configuration and only transitions its deps, so os:ios made it incompatible on the mac runner: target platform (@@platforms//host:host) didn't satisfy constraint @@platforms//os:ios The app build step passed on Bazel 9; this unblocks the test step. Co-Authored-By: Claude Fable 5 Claude-Session: https://claude.ai/code/session_01Jw99o89a2UYe9NKLE9zGUx --- domains/games/apps/wordchains_ios/BUILD.bazel | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/domains/games/apps/wordchains_ios/BUILD.bazel b/domains/games/apps/wordchains_ios/BUILD.bazel index 0cbe56e8..3da2bc08 100644 --- a/domains/games/apps/wordchains_ios/BUILD.bazel +++ b/domains/games/apps/wordchains_ios/BUILD.bazel @@ -49,10 +49,13 @@ swift_library( deps = [":WordChainsLib"], ) +# Unlike ios_application, the test rule stays in the host configuration +# (only its deps transition to iOS), so it must be compatible with the +# macOS host that runs the simulator. ios_unit_test( name = "WordChainsTests", minimum_os_version = "17.0", tags = ["manual"], - target_compatible_with = ["@platforms//os:ios"], + target_compatible_with = ["@platforms//os:macos"], deps = [":WordChainsTestLib"], ) From e4d1c4f76ba80f1c321c5b66c20f52b2c9b2d100 Mon Sep 17 00:00:00 2001 From: Claude Date: Sat, 4 Jul 2026 18:40:52 +0000 Subject: [PATCH 5/6] fix(ios): enable swift testability for bazel ios_unit_test in CI The repo builds with --compilation_mode=opt, where rules_swift disables -enable-testing by default (it is only on for dbg/fastbuild), so the @testable import in WordGraphTests failed with "module 'WordChains' was not compiled for testing". SwiftPM's swift test builds debug, which is why the existing test step never hit this. Pass --features=swift.enable_testing on the CI test invocation only, leaving the app and release builds without testability. Co-Authored-By: Claude Fable 5 Claude-Session: https://claude.ai/code/session_01Jw99o89a2UYe9NKLE9zGUx --- .github/workflows/branch.yml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.github/workflows/branch.yml b/.github/workflows/branch.yml index 4e763758..a546612c 100644 --- a/.github/workflows/branch.yml +++ b/.github/workflows/branch.yml @@ -173,8 +173,11 @@ jobs: --ios_minimum_os=17.0 \ --apple_platform_type=ios + # swift.enable_testing is needed for @testable imports because the repo + # builds -c opt, where rules_swift disables testability by default. - name: Run iOS unit tests with bazel if: steps.filter.outputs.changed == 'true' run: | bazel test //domains/games/apps/wordchains_ios:WordChainsTests \ - --ios_minimum_os=17.0 + --ios_minimum_os=17.0 \ + --features=swift.enable_testing From 4223590efbefc8fd0389f3cc64233ccdc1155d67 Mon Sep 17 00:00:00 2001 From: Claude Date: Sat, 4 Jul 2026 18:47:53 +0000 Subject: [PATCH 6/6] fix(ios): pin simulator device for bazel ios_unit_test The test bundle now builds and runs, but the default test runner created a "New-iPhone 6s Plus-26.5" simulator - an iPhone 6s Plus paired with the latest iOS 26.5 runtime, which that device type cannot run - and the tests exited with 15 before executing. Pass --ios_simulator_device="iPhone 16" so a valid device/runtime pair is used. Co-Authored-By: Claude Fable 5 Claude-Session: https://claude.ai/code/session_01Jw99o89a2UYe9NKLE9zGUx --- .github/workflows/branch.yml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/.github/workflows/branch.yml b/.github/workflows/branch.yml index a546612c..0df2bb04 100644 --- a/.github/workflows/branch.yml +++ b/.github/workflows/branch.yml @@ -175,9 +175,13 @@ jobs: # swift.enable_testing is needed for @testable imports because the repo # builds -c opt, where rules_swift disables testability by default. + # Without an explicit simulator device the test runner pairs an ancient + # device type (iPhone 6s Plus) with the latest iOS runtime and the + # simulator fails to boot. - name: Run iOS unit tests with bazel if: steps.filter.outputs.changed == 'true' run: | bazel test //domains/games/apps/wordchains_ios:WordChainsTests \ --ios_minimum_os=17.0 \ - --features=swift.enable_testing + --features=swift.enable_testing \ + --ios_simulator_device="iPhone 16"