iosgithub-actions

Errors when building xcframework


I'm trying to build an xcframework from a simple spm package. Consulted AI to get help with creating a workflow that I could trigger manually in order to create an xcframework and finally upload it to a public repo for consumption. I'm facing a couple of errors in this regard:

  1. The workflow randomly fails at times with errors such as
Ineligible destinations for the "FancyFramework" scheme:
 { platform:iOS, id:dvtdevice-DVTiPhonePlaceholder-iphoneos:placeholder, name:Any iOS Device, error:iOS 18.0 is not installed. To use with Xcode, first download and install the platform }
  1. When the workflow does manage to run, it eventually fails with error:
error: the path does not point to a valid debug symbols file: archives/FancyFramework-iOS.xcarchive/dSYMs/FancyFramework.framework.dSYM

My goal is to be able to build an xcframework that supports minimum iOS deployment target of 16.0 as well as add the dSYMs to the final framework because as per my understanding they'd help in debugging crash logs. Here's the Package.swift file contents:

// swift-tools-version: 5.7
// The swift-tools-version declares the minimum version of Swift required to build this package.

import PackageDescription

let package = Package(
    name: "FancyFramework",
    platforms: [
        .iOS(.v16),
    ],
    products: [
        .library(
            name: "FancyFramework",
            type: .dynamic,
            targets: ["FancyFramework"]),
    ],
    targets: [
        .target(
            name: "FancyFramework"),

    ]
)

Here's my workflow file (as given by copilot):

# .github/workflows/release.yml

name: Create XCFramework Release

on:
  workflow_dispatch:
    inputs:
      version:
        description: 'The version to release (e.g., 1.0.0)'
        required: true
        type: string

env:
  FRAMEWORK_NAME: FancyFramework
  GITHUB_USERNAME: fancy
  XCODE_VERSION: '16.0'
  IOS_DEPLOYMENT_TARGET: '16.0'

jobs:
  build_and_release:
    name: Build, Release, and Update Distribution Repo
    runs-on: macos-latest

    permissions:
      contents: write
    
    steps:
      - name: Checkout Source Code
        uses: actions/checkout@v3
      
      - name: Select Xcode ${{ env.XCODE_VERSION }}
        uses: maxim-lobanov/setup-xcode@v1
        with:
          xcode-version: ${{ env.XCODE_VERSION }}

      - name: List Available Destinations
        run: |
          xcodebuild -scheme ${{ env.FRAMEWORK_NAME }} -showdestinations

      - name: Build and Assemble XCFramework
        run: |
          # Define predictable paths
          ARCHIVE_PATH_IOS="archives/${{ env.FRAMEWORK_NAME }}-iOS.xcarchive"
          ARCHIVE_PATH_SIM="archives/${{ env.FRAMEWORK_NAME }}-iOS-Simulator.xcarchive"
          DERIVED_DATA_IOS="derived_data_ios"
          DERIVED_DATA_SIM="derived_data_sim"

          # --- Step 1: Build and Assemble for iOS ---
          echo "Archiving for iOS..."
          xcodebuild archive \
            -scheme ${{ env.FRAMEWORK_NAME }} \
            -destination "generic/platform=iOS" \
            -archivePath "$ARCHIVE_PATH_IOS" \
            -derivedDataPath "$DERIVED_DATA_IOS" \
            -sdk iphoneos \
            SKIP_INSTALL=NO \
            BUILD_LIBRARY_FOR_DISTRIBUTION=YES \
            DEBUG_INFORMATION_FORMAT=dwarf-with-dsym \
            ONLY_ACTIVE_ARCH=NO \
            IPHONEOS_DEPLOYMENT_TARGET=${{ env.IOS_DEPLOYMENT_TARGET }}
          
          echo "Copying Swift module for iOS..."
          mkdir -p "$ARCHIVE_PATH_IOS/Products/usr/local/lib/${{ env.FRAMEWORK_NAME }}.framework/Modules"
          cp -r "$DERIVED_DATA_IOS/Build/Intermediates.noindex/ArchiveIntermediates/${{ env.FRAMEWORK_NAME }}/BuildProductsPath/Release-iphoneos/${{ env.FRAMEWORK_NAME }}.swiftmodule" \
                "$ARCHIVE_PATH_IOS/Products/usr/local/lib/${{ env.FRAMEWORK_NAME }}.framework/Modules/"
          
          echo "Checking for dSYM files for iOS..."
          DSYM_SOURCE_IOS="$DERIVED_DATA_IOS/Build/Intermediates.noindex/ArchiveIntermediates/${{ env.FRAMEWORK_NAME }}/BuildProductsPath/Release-iphoneos/${{ env.FRAMEWORK_NAME }}.framework.dSYM"
          if [ -d "$DSYM_SOURCE_IOS" ]; then
            echo "dSYM found, copying for iOS..."
            mkdir -p "$ARCHIVE_PATH_IOS/dSYMs"
            cp -r "$DSYM_SOURCE_IOS" "$ARCHIVE_PATH_IOS/dSYMs/"
          else
            echo "Warning: dSYM not found at expected location for iOS"
            find "$DERIVED_DATA_IOS" -name "*.dSYM" -type d
          fi

          xcodebuild archive \
            -scheme ${{ env.FRAMEWORK_NAME }} \
            -destination "generic/platform=iOS Simulator" \
            -archivePath "$ARCHIVE_PATH_SIM" \
            -derivedDataPath "$DERIVED_DATA_SIM" \
            -sdk iphonesimulator \
            SKIP_INSTALL=NO \
            BUILD_LIBRARY_FOR_DISTRIBUTION=YES \
            DEBUG_INFORMATION_FORMAT=dwarf-with-dsym \
            ONLY_ACTIVE_ARCH=NO \
            IPHONEOS_DEPLOYMENT_TARGET=${{ env.IOS_DEPLOYMENT_TARGET }}
          
          echo "Copying Swift module for iOS Simulator..."
          mkdir -p "$ARCHIVE_PATH_SIM/Products/usr/local/lib/${{ env.FRAMEWORK_NAME }}.framework/Modules"
          cp -r "$DERIVED_DATA_SIM/Build/Intermediates.noindex/ArchiveIntermediates/${{ env.FRAMEWORK_NAME }}/BuildProductsPath/Release-iphonesimulator/${{ env.FRAMEWORK_NAME }}.swiftmodule" \
                "$ARCHIVE_PATH_SIM/Products/usr/local/lib/${{ env.FRAMEWORK_NAME }}.framework/Modules/"

          echo "Checking for dSYM files for iOS Simulator..."
          DSYM_SOURCE_SIM="$DERIVED_DATA_SIM/Build/Intermediates.noindex/ArchiveIntermediates/${{ env.FRAMEWORK_NAME }}/BuildProductsPath/Release-iphonesimulator/${{ env.FRAMEWORK_NAME }}.framework.dSYM"
          if [ -d "$DSYM_SOURCE_SIM" ]; then
            echo "dSYM found, copying for iOS Simulator..."
            mkdir -p "$ARCHIVE_PATH_SIM/dSYMs"
            cp -r "$DSYM_SOURCE_SIM" "$ARCHIVE_PATH_SIM/dSYMs/"
          else
            echo "Warning: dSYM not found at expected location for iOS Simulator"
            find "$DERIVED_DATA_SIM" -name "*.dSYM" -type d
          fi
          
          echo "Creating XCFramework..."
          
          # Check if dSYM files exist before including them
          XCFRAMEWORK_ARGS="-framework $ARCHIVE_PATH_IOS/Products/usr/local/lib/${{ env.FRAMEWORK_NAME }}.framework"
          
          if [ -d "$ARCHIVE_PATH_IOS/dSYMs/${{ env.FRAMEWORK_NAME }}.framework.dSYM" ]; then
            echo "Creating XCFramework with debug symbols..."
            XCFRAMEWORK_ARGS="$XCFRAMEWORK_ARGS -debug-symbols $ARCHIVE_PATH_IOS/dSYMs/${{ env.FRAMEWORK_NAME }}.framework.dSYM"
          fi
          
          XCFRAMEWORK_ARGS="$XCFRAMEWORK_ARGS -framework $ARCHIVE_PATH_SIM/Products/usr/local/lib/${{ env.FRAMEWORK_NAME }}.framework"
          
          if [ -d "$ARCHIVE_PATH_SIM/dSYMs/${{ env.FRAMEWORK_NAME }}.framework.dSYM" ]; then
            XCFRAMEWORK_ARGS="$XCFRAMEWORK_ARGS -debug-symbols $ARCHIVE_PATH_SIM/dSYMs/${{ env.FRAMEWORK_NAME }}.framework.dSYM"
          fi
          
          xcodebuild -create-xcframework \
            $XCFRAMEWORK_ARGS \
            -output "${{ env.FRAMEWORK_NAME }}.xcframework"

      # 5. Zip and Checksum the XCFramework
      - name: Zip and Checksum XCFramework
        run: |
          zip -r ${{ env.FRAMEWORK_NAME }}.xcframework.zip ${{ env.FRAMEWORK_NAME }}.xcframework
          echo "CHECKSUM=$(swift package compute-checksum ${{ env.FRAMEWORK_NAME }}.xcframework.zip)" >> $GITHUB_ENV

      # 6. Commit and Push the updated Package.swift FIRST
      - name: Commit and Push to Distribution Repo
        run: |
          git clone https://x-access-token:${{ secrets.DISTRIBUTION_REPO_TOKEN }}@github.com/${{ env.GITHUB_USERNAME }}/${{ env.FRAMEWORK_NAME }}.git dist-repo
          cd dist-repo
          NEW_URL="https://github.com/${{ env.GITHUB_USERNAME }}/${{ env.FRAMEWORK_NAME }}/releases/download/${{ inputs.version }}/${{ env.FRAMEWORK_NAME }}.xcframework.zip"
          sed -i '' "s|URL_PLACEHOLDER|${NEW_URL}|" Package.swift
          sed -i '' "s|CHECKSUM_PLACEHOLDER|${{ env.CHECKSUM }}|" Package.swift
          git config --global user.name 'github-actions[bot]'
          git config --global user.email 'github-actions[bot]@users.noreply.github.com'
          git add Package.swift
          git commit -m "Update to version ${{ inputs.version }}"
          git push

      # 7. Create the Git tag in THIS source repository for history
      - name: Create Git Tag in Source Repo
        run: |
          git tag ${{ inputs.version }}
          git push origin ${{ inputs.version }}

      # 8. Create the final Release on the PUBLIC repository
      - name: Create Release on Public Repo
        env:
          GH_TOKEN: ${{ secrets.DISTRIBUTION_REPO_TOKEN }}
        run: |
          gh release create ${{ inputs.version }} \
            --repo "${{ env.GITHUB_USERNAME }}/${{ env.FRAMEWORK_NAME }}" \
            --title "Release ${{ inputs.version }}" \
            --notes "Binary release for version ${{ inputs.version }}." \
            ${{ env.FRAMEWORK_NAME }}.xcframework.zip

Any help is appreciated.


Solution

  • Turns out it was a known issue. It worked by downloading iOS simulator platform before the build steps:

    
    - name: Download iOS Platform (CI Stability Fix)
            run: |
              xcodebuild -downloadPlatform iOS || echo "⚠️  Platform already installed or download failed, continuing..."