name: iOS

on:
  pull_request:
    branches:
      - 'master'
  push:
    branches:
      - 'master'

jobs:
  ios:
    name: Build iOS framework, app & run shared tests
    # The Kotlin/Native iOS targets (and the simulator test run / xcodebuild)
    # require a macOS host with Xcode, so this job runs on a macOS runner —
    # unlike the Android build/test jobs which run on ubuntu. The runner image
    # is pinned (rather than macos-latest) so the Xcode / Kotlin-Native
    # toolchain stays reproducible. macos-26 (Xcode 26) is required because
    # Compose Multiplatform 1.11's Kotlin/Native artifacts (ui-uikit) reference
    # symbols that only exist in the iOS 26 SDK (e.g. UIViewLayoutRegion and the
    # UIUtilities framework). Linking the simulator test executable against the
    # older iOS 18.5 SDK (Xcode 16.4 on macos-15) fails with
    # "Undefined symbols ... _OBJC_CLASS_$_UIViewLayoutRegion".
    runs-on: macos-26
    steps:
      - uses: actions/checkout@v4
        with:
          # fetch-depth: 0 brings the git tags so app/build.gradle.kts can
          # derive the version via `git describe --tags`.
          fetch-depth: 0
      - name: Select Xcode
        uses: maxim-lobanov/setup-xcode@v1
        with:
          xcode-version: '26.0'
      - name: Set up JDK 17
        uses: actions/setup-java@v4
        with:
          java-version: 17
          distribution: 'temurin'
      - name: Setup Gradle
        uses: gradle/actions/setup-gradle@v4
      - name: Compile shared common code
        run: ./gradlew :shared:compileKotlinMetadata --no-daemon
      - name: Link iOS framework (simulator)
        run: ./gradlew :shared:linkDebugFrameworkIosSimulatorArm64 --no-daemon
      - name: Link iOS framework (device)
        run: ./gradlew :shared:linkDebugFrameworkIosArm64 --no-daemon
      - name: Run shared tests on iOS simulator
        run: ./gradlew :shared:iosSimulatorArm64Test --no-daemon
      - name: Archive iOS test results
        if: always()
        uses: actions/upload-artifact@v4
        with:
          name: ios-test-results
          path: shared/build/test-results/iosSimulatorArm64Test/
      # The Xcode project is intentionally not committed (see iosApp/README.md);
      # it is generated from iosApp/project.yml with XcodeGen. The generated
      # project wires a Gradle run-script phase
      # (:shared:embedAndSignAppleFrameworkForXcode) that builds the shared
      # Kotlin/Native framework the app + widget link against.
      - name: Install XcodeGen
        run: brew install xcodegen
      - name: Generate Xcode project
        working-directory: iosApp
        # Run version.sh first so the git-derived MARKETING_VERSION /
        # CURRENT_PROJECT_VERSION are written to Version.local.xcconfig (included
        # by the committed Version.xcconfig) and stamped into the bundles,
        # mirroring the Android version derivation. fetch-depth: 0 above brings
        # the tags this needs.
        run: |
          ./version.sh
          xcodegen generate
      - name: Install iOS platform
        # The macos-26 image ships the iOS 26 SDK but not the iOS 26 platform
        # support (simulator runtime), so xcodebuild destinations fail with
        # "iOS 26.0 is not installed" until it is downloaded on demand.
        run: sudo xcodebuild -downloadPlatform iOS
      - name: Build iOS app (simulator, no code signing)
        # Pin a concrete named simulator device: on the arm64 runner it resolves
        # to a single architecture (a generic destination did not). No OS is
        # pinned, so an already-installed iPhone 17 runtime is used.
        run: |
          xcodebuild build \
            -project iosApp/StockTicker.xcodeproj \
            -scheme StocksWidget \
            -destination 'platform=iOS Simulator,name=iPhone 17' \
            CODE_SIGNING_ALLOWED=NO
