Xcode 14 beta code signing issues when SwiftPM targets include resources

Hello!

Our situation is the following:

  • We have an app which depends on an SPM library 1 which in turn depends on SPM library 2 with resources
  • We override codesigning settings by passing them directly to xcodebuild via arguments during archiving
  • Our setup used to archive successfully in Xcode 13.4. However, it fails in Xcode 14 beta 5.

Sample app with the simplified setup can be found here GitHub - dymv/SPMBundleSign

A series of errors that we're getting when trying to archive our app via CLI:

  • Running the same archive xcodebuild command that used to work in Xcode 13 causes this issue :arrow_down:
  • spm-bundle-sign-package_TargetWithResources requires a development team. Select a development team in the Signing & Capabilities editor.
    • Passing a development team via DEVELOPMENT_TEAM="1234567890" causes another issue :arrow_down:
  • spm-bundle-sign-package_TargetWithResources has conflicting provisioning settings. spm-bundle-sign-package_TargetWithResources is automatically signed for development, but a conflicting code signing identity Apple Distribution has been manually specified. Set the code signing identity value to "Apple Development" in the build settings editor, or switch to manual signing in the Signing & Capabilities editor.
    • Passing provisioning profile via PROVISIONING_PROFILE_SPECIFIER causes another issue :arrow_down:
  • spm-bundle-sign-package_TargetWithResources does not support provisioning profiles. spm-bundle-sign-package_TargetWithResources does not support provisioning profiles, but provisioning profile SPMBundleSign Distribution has been manually specified. Set the provisioning profile value to "Automatic" in the build settings editor.
    • AFAICS, the only way forward is to avoid any codesigning overrides via xcodebuild command. Are there any workarounds in case there's a requirement to provide such overrides via CLI?

Please help us understand if there's anything that we can do in Xcode 14 to support our app setup. Thank you!

9 Likes

Hello. We have the same issue but we are using Cocoapods instead of SPM.

If you try to run the app on a simulator it compiles correctly but when you try to run it on a device, then it fails.

Tested on Xcode 14 beta 4 and 5.

1 Like

For CocoaPods, see Xcode 14 build failed with manual code sign and app resource bundles · Issue #11402 · CocoaPods/CocoaPods · GitHub

Does passing CODE_SIGN_STYLE=Manual as well help?

2 Likes

Thank you so much for pointing out that to me!

1 Like

@paulb777 @NeoNacho Thank you so much for your responses folks!

Passing CODE_SIGN_STYLE=Manual alongside with DEVELOPMENT_TEAM and CODE_SIGN_IDENTITY worked for us.

We have a similar issue on an Azure Devops CI.

/usr/bin/xcodebuild -sdk iphoneos16.0 -configuration Release -workspace /Redacted/project.xcworkspace -scheme Redacted clean archive -archivePath /Redacted DEVELOPMENT_TEAM=Redacted -destination generic/platform=iOS CODE_SIGN_STYLE=Manual CODE_SIGN_IDENTITY=Redacted PROVISIONING_PROFILE=Redacted PROVISIONING_PROFILE_SPECIFIER=

As visible, we passed all the parameter.
However, the archive fails due to code signing packages include in the project.

/Users/runner/Library/Developer/Xcode/DerivedData/Redacted/SourcePackages/checkouts/TOCropViewController/Package.swift: error: TOCropViewController_TOCropViewController does not support provisioning profiles. TOCropViewController_TOCropViewController does not support provisioning profiles, but provisioning profile Redacted has been manually specified. Set the provisioning profile value to "Automatic" in the build settings editor. (in target 'TOCropViewController_TOCropViewController' from project 'TOCropViewController')

Any ideas?

BTW: Same situation as with @lflw. Everything is working with Xcode 13.4

FYI: I submitted a Radar. FB11402077

Apple closed my feedback with „Investigation complete - Works as currently designed“ and no further information. From our point of view, this is a pity and definitely a bug as everything was working with Xcode 13.4.1.

+1 on this fix and thank you! Our project uses a mix of Pods/SPM packages via fastlane to archive and we encountered this error. We had to pass these in via xcargs, along with the codesigning_identity parameter in fastlane gym:

codesigning_identity: "<REDACTED>", xcargs: "CODE_SIGN_STYLE=Manual DEVELOPMENT_TEAM=<REDACTED>"

1 Like

Hi, did you ever figure this out? I am experiencing the same thing...

Any updates on the issue? How this can be solved?
I am using SPM and I am receiving similar errors. What I've noticed is that those errors come from packages/local packages that have Resources - basically Xcode14/SPM tries to codesign resource package bundles, but this is not supported.

I am distributing the app through fastlane and am not able to resolve the issue. What I've tried already:

  • use automatic signing on CI side
  • use manual signing on CI side & pass code signing related env vars via build_app xcargs / codesigning_identity arguments

I submitted a TSI to Apple after closing of the feedback.
The answer was, that when passing PROVISIONING_PROFILE_SPECIFIER or PROVISIONING_PROFILE to xcodebuild, that setting is applied every target that subsequently built for Xcode 14 (as known...). The suggested approach was to set these vars not via xcodebuild, but instead setting them to each target individually. This led us to our solution:

We set the PROVISIONING_PROFILE_SPECIFIER etc. to custom vars, here MY_ PROVISIONING_PROFILE_SPECIFIER in build settings. Then we passed them via args. These are the corresponding lines from our Azure Devobs job.

    - task: InstallAppleCertificate@2
      displayName: 'Install Apple Certificates'
      inputs:
        certSecureFile: ${{ parameters.ADHOC_CERTIFICATE }}
        certPwd:  ${{ parameters.ADHOC_CERTIFICATE_PASSWORD }}
        keychain: 'temp'

    - task: InstallAppleProvisioningProfile@1
      displayName: 'Install Apple Provisioning Profile'
      inputs:
        provisioningProfileLocation: 'secureFiles'
        provProfileSecureFile: ${{ parameters.ADHOC_PROVISIONING_PROFILE }}

    - task: Bash@3
      displayName: 'Build exportOptions.plist file'
      inputs:
        targetType: 'inline'
        script: |
          /usr/libexec/PlistBuddy -c "Add :method string ad-hoc" $(system.defaultworkingdirectory)/export.plist
          /usr/libexec/PlistBuddy -c "Add :provisioningProfiles dict" $(system.defaultworkingdirectory)/export.plist
          /usr/libexec/PlistBuddy -c "Add :provisioningProfiles:${{ parameters.ADHOC_BUNDLE_ID }} string $(APPLE_PROV_PROFILE_UUID)" $(system.defaultworkingdirectory)/export.plist
          /usr/libexec/PlistBuddy -c "Add :signingCertificate string $(APPLE_CERTIFICATE_SIGNING_IDENTITY)" $(system.defaultworkingdirectory)/export.plist
          /usr/libexec/PlistBuddy -c "Add :signingStyle string manual" $(system.defaultworkingdirectory)/export.plist
          /usr/libexec/PlistBuddy -c "Add :teamID string ${{ parameters.ADHOC_TEAM_ID }}" $(system.defaultworkingdirectory)/export.plist

...

    - task: Xcode@5
      displayName: 'Build and Archive'
      inputs:
        # Currently, Xcode 13 is the default. Therefore, the version needs to be changed to Xcode 14.
        xcodeVersion: 'specifyPath'
        xcodeDeveloperDir: '/Applications/Xcode_14.0.app'
        # By default, 'packageApp: true' will already build and archive the app so don't do anything here.
        # https://developercommunity.visualstudio.com/content/problem/1222720/why-is-xcode-ado-task-building-our-ios-project-twi.html
        actions: 'clean'
        scheme: ${{ parameters.SCHEME }}
        sdk: ${{ parameters.SDK }}
        configuration: 'Release'
        xcWorkspacePath: '**/*.xcodeproj/project.xcworkspace'
        signingOption: 'default'
        packageApp: true
        archivePath: '$(system.defaultworkingdirectory)/build/${{ parameters.SCHEME }}.xcarchive'
        exportPath: '$(system.defaultworkingdirectory)/build'
        # At this point we deliberately do not use the parameters signingIdentity and provisioningProfileUuid. 
        # When we do use them, they are applied to the app and all Swift packages in the app (new since Xcode 14). However, these often do not support signing. 
        # The parameters passed here are only applied to the app itself (see build setting and project.yml).
        args: '-destination generic/platform=iOS -verbose MY_PROVISIONING_PROFILE_SPECIFIER=$(APPLE_PROV_PROFILE_UUID) MY_CODE_SIGN_IDENTITY="$(APPLE_CERTIFICATE_SIGNING_IDENTITY)" MY_DEVELOPMENT_TEAM=${{ parameters.ADHOC_TEAM_ID }}'
        exportOptions: 'plist'
        exportOptionsPlist: '$(system.defaultworkingdirectory)/export.plist'

Thanks @honkmaster !
Your response was super helpful! It helped me understand how xcodebuild works right now with the new Xcode14. I came up with a little different solution. Let me explain.

The issue with new Xcode14

The fastlane's build_app lane was configured in a way so it was taking the xcconfig file as a parameter.
The environment variables from xcconfig file were passed to the xcodebuild command that was invoked under the hood when the build_app lane was run.

Starting from Xcode14 when codesigning env variables (e.g. PROVISIONING_PROFILE_SPECIFIER, CODE_SIGN_IDENTITY) are passed as parameters to xcodebuild, that setting is applied to every target (even the target from SPM package) and this results in codesigning failure as not every SPM target supports codesigning.

Solution

The solution is to configure codesigning only for the app target. This can be done in Build Settings.
On the target level, we can assign codesigning related parameters:

  • PROVISIONING_PROFILE_SPECIFIER
  • CODE_SIGN_IDENTITY
  • CODE_SIGN_STYLE
  • DEVELOPMENT_TEAM
    Those parameters are taken from the xcconfig file, so from now xcconfig file will be only used for the target configuration.

On a fastlane side, we were previously passing xcconfig file as a parameter to build_app lane. This resulted in passing all the env vars that were inside xcconfig to the xcodebuild script. With that setting, xcodebuild was taking the codesign related env vars and it was applying those env vars to every target (not only the main app target) - we do not want such behaviour.
By getting rid of passing xcconfig, the xcodebuild applies codesigning parameters to only the app target and the app builds successfully.

1 Like

So one needs to pass xconfig file to xcodebuild in order to sign the target only?

The xcodebuild applies codesigning parameters to only the app target, because those parameters are only defined for that particular target in Build Settings. Like this:

I am not passing xcconfig to xcodebuild currently.

Thank you all for your contribution. I managed to solve my Xcode14.0 issue with azure's pipeline.

So here is what I did:

  1. I created the export plist file.
  2. I used 'default' for signing option in xcodebuild; the target's build settings are set to auto.
  3. I passed "CODE_SIGNING_REQUIRED=Yes CODE_SIGNING_ALLOWED=No" as argument to xcodebuild.
  4. profit!

To my understanding, in this way xcodebuild will skip signing the binaries when archiving, and then it will use the plist to sign the .ipa when exporting the archive.

Here's how the .yml looks like for exporting the archive:

- task: Bash@3
  displayName: 'Build export.plist file'
  inputs:
    targetType: 'inline'
    script:
      /usr/libexec/PlistBuddy -c "Add :method string app-store" $(Pipeline.Workspace)/export.plist &&
      /usr/libexec/PlistBuddy -c "Add :provisioningProfiles dict" $(Pipeline.Workspace)/export.plist &&
      /usr/libexec/PlistBuddy -c "Add :provisioningProfiles:$(appIdentifier) string $(APPLE_PROV_PROFILE_UUID)" $(Pipeline.Workspace)/export.plist &&
      /usr/libexec/PlistBuddy -c "Add :signingCertificate string $(APPLE_CERTIFICATE_SIGNING_IDENTITY)" $(Pipeline.Workspace)/export.plist &&
      /usr/libexec/PlistBuddy -c "Add :signingStyle string manual" $(Pipeline.Workspace)/export.plist &&
      /usr/libexec/PlistBuddy -c "Add :teamID string $(teamId)" $(Pipeline.Workspace)/export.plist &&
      /usr/libexec/PlistBuddy -c "Add :iCloudContainerEnvironment string Production" $(Pipeline.Workspace)/export.plist &&
      /usr/libexec/PlistBuddy -c "Add :stripSwiftSymbols bool true" $(Pipeline.Workspace)/export.plist &&
      /usr/libexec/PlistBuddy -c "Add :compileBitcode bool false" $(Pipeline.Workspace)/export.plist

- task: Xcode@5
  inputs:
    actions: 'clean'
    configuration: '$(configuration)'
    sdk: '$(sdk)'
    scheme: '$(scheme)'
    xcodeVersion: '14'
    signingOption: 'default'
    packageApp: true
    archivePath: '$(Pipeline.Workspace)/build/$(scheme).xcarchive'
    exportPath: '$(Build.ArtifactStagingDirectory)'
    exportOptions: 'plist'
    exportOptionsPlist: '$(Pipeline.Workspace)/export.plist'
    args: '-destination generic/platform=iOS -verbose CODE_SIGNING_REQUIRED=Yes CODE_SIGNING_ALLOWED=No'

2 Likes

The above solution worked for us also.

Thanks for your help! This fixed our issue as well. This is our working .yml file in azure devops.

steps:
- task: CmdLine@2
  inputs:
    script: |
      mkdir '$(build.artifactStagingDirectory)/Archive' && cd "$_"

      /usr/libexec/PlistBuddy -c "Clear dict" $(XCODE_EXPORT_OPTIONS_PLIST_FILE_NAME)
      /usr/libexec/PlistBuddy -c "Add method string $(METHOD)" $(XCODE_EXPORT_OPTIONS_PLIST_FILE_NAME)
      /usr/libexec/PlistBuddy -c "Add signingStyle string manual" $(XCODE_EXPORT_OPTIONS_PLIST_FILE_NAME)
      /usr/libexec/PlistBuddy -c "Add signingCertificate string $(CODE_SIGN_IDENTITY)" $(XCODE_EXPORT_OPTIONS_PLIST_FILE_NAME)
      /usr/libexec/PlistBuddy -c "Add provisioningProfiles dict" $(XCODE_EXPORT_OPTIONS_PLIST_FILE_NAME)
      /usr/libexec/PlistBuddy -c "Add provisioningProfiles:$(APP_BUNDLE_ID) string $(APP_PROVISIONING_ID)" $(XCODE_EXPORT_OPTIONS_PLIST_FILE_NAME)
      /usr/libexec/PlistBuddy -c "Add teamID string $(TEAM_ID)" $(XCODE_EXPORT_OPTIONS_PLIST_FILE_NAME)
      /usr/libexec/PlistBuddy -x -c "Print" $(XCODE_EXPORT_OPTIONS_PLIST_FILE_NAME)
  displayName: 'Generate export options'

- task: Xcode@5
  displayName: 'Xcode Clean Archive $(SCHEME)'
  inputs:
    actions: 'clean archive'
    sdk: 'iphoneos'
    configuration: $(CONFIGURATION)
    xcWorkspacePath: 'Product.xcworkspace'
    scheme: $(SCHEME)
    packageApp: true
    archivePath: '$(build.artifactStagingDirectory)/Archive/Product.xcarchive'
    exportOptions: plist
    exportOptionsPlist: '$(build.artifactStagingDirectory)/Archive/$(XCODE_EXPORT_OPTIONS_PLIST_FILE_NAME)'
    xcodeVersion: 'specifyPath'
    xcodeDeveloperDir: '/Applications/Xcode_14.0.app'
    useXcpretty: true
    xcprettyArgs: '--color'

Update: My previous code snippet did work for archiving, signing and exporting the .ipa to TestFlight. However, since our project uses some Apple services .i.e. push notification, associated domains ... etc, the entitlements were not signed when exporting the .ipa. So we received a warning email from Apple stating that the binary was registered for such services but was missing entitlements in the code signature!
The work around I did to fix the entitlements issue, was to archive the project in the same previous way, then sign the app with the required entitlements, and eventually export to an .ipa.
So my final .yml file looks like this:

# install certificate, provisioning profile, and create the export plist
# ...

# Build the archive
- task: Xcode@5
  displayName: 'Xcode archive'
  inputs:
    actions: 'archive'
    configuration: '$(configuration)'
    sdk: '$(sdk)'
    scheme: '$(scheme)'
    xcodeVersion: '14'
    signingOption: 'default'
    packageApp: false
    useXcpretty: false
    args: '-destination generic/platform=iOS -archivePath $(Pipeline.Workspace)/$(scheme).xcarchive -verbose CODE_SIGNING_REQUIRED=Yes CODE_SIGNING_ALLOWED=No'


# Sign the binaries with projects entitlements
- task: Bash@3
  displayName: 'Code signing'
  inputs:
    targetType: 'inline'
    script:
      codesign --entitlements $(Build.Repository.LocalPath)/$(entitlement) -f -s "$(APPLE_CERTIFICATE_SIGNING_IDENTITY)" $(Pipeline.Workspace)/$(scheme).xcarchive/$(app-path)


# Export an ipa from the signed archive
- task: Bash@3
  displayName: 'Xcode export'
  inputs:
    targetType: 'inline'
    script:
      /usr/bin/xcodebuild -exportArchive -archivePath $(Pipeline.Workspace)/$(scheme).xcarchive -exportPath $(Build.ArtifactStagingDirectory) -exportOptionsPlist $(Pipeline.Workspace)/$(export-options)

PS the app-path points to the MyApp.app inside the archive, and entitlement points to the entitlements file in the repo

2 Likes