Fix: SPM Target Does Not Support Provisioning Profiles in Azure DevOps Xcode Archive

Fix: SPM Target Does Not Support Provisioning Profiles in Azure DevOps Xcode Archive

Written by

in

Quick answer: The Azure DevOps Xcode@5 task applies manual provisioning settings to all targets including SPM dependencies like GoogleUtilities, which don’t support provisioning profiles. Fix it by setting signingOption: 'default' in the Xcode task and removing manual signingIdentity and provisioningProfileUuid inputs. Ensure the Runner app target has correct signing configured in Xcode.

Why this happens

When you migrate a Flutter iOS project from CocoaPods to Swift Package Manager (SPM), external dependencies like GoogleUtilities become SPM package targets. These SPM targets are built as part of the archive process but do not support manual provisioning profiles — they expect automatic signing.

The Azure DevOps Xcode@5 task, when configured with signingOption: 'manual', applies the specified provisioning profile and signing identity to every target in the workspace, including SPM package targets. Since SPM targets like GoogleUtilities_GoogleUtilities-Environment cannot accept a provisioning profile, the archive fails with:

error: GoogleUtilities_GoogleUtilities-Environment does not support provisioning profiles.
Set the provisioning profile value to "Automatic" in the build settings editor.

This works locally in Xcode because Xcode’s automatic signing handles SPM targets correctly. The pipeline fails because the task forces manual signing onto targets that reject it.

How to fix it

1. Switch the Xcode task to default signing

Edit your Azure DevOps pipeline YAML. In the Xcode@5 task that runs the archive, change signingOption to default and remove the manual signing inputs.

- task: Xcode@5
  displayName: 'Archive iOS App'
  inputs:
    actions: 'archive'
    configuration: '$(BUILD_CONFIGURATION)'
    scheme: '$(IOS_SCHEME)'
    sdk: 'iphoneos'
    xcWorkspacePath: 'ios/Runner.xcworkspace'
    signingOption: 'default'  # <-- change from 'manual'
    # Remove these lines:
    # signingIdentity: 'Apple Distribution'
    # provisioningProfileUuid: '$(installProfile.provisioningProfileUuid)'
    packageApp: true
    exportPath: '$(Build.ArtifactStagingDirectory)/ipa'
    exportOptions: 'plist'
    exportOptionsPlist: 'ios/ExportOptions.plist'

With signingOption: 'default', Xcode uses the signing configuration defined in the project (Runner target) and lets SPM targets fall back to automatic signing.

2. Verify Runner target signing in Xcode

Open ios/Runner.xcworkspace in Xcode and confirm:

  • Runner target → Signing & Capabilities
  • Automatically manage signing is enabled (or if manual, the correct Team, Provisioning Profile, and Signing Certificate are selected)
  • The provisioning profile matches the one installed by the InstallAppleCertificate@2 / InstallAppleProvisioningProfile@1 tasks
  • Build Settings → Code Signing
  • CODE_SIGN_STYLE = Automatic (or Manual with correct profile)
  • PROVISIONING_PROFILE_SPECIFIER matches your profile name if manual

Commit these settings so the pipeline uses them.

3. (Optional) Use separate archive and export steps

If you need fine-grained control, split archive and export:

- task: Xcode@5
  displayName: 'Archive'
  inputs:
    actions: 'archive'
    configuration: '$(BUILD_CONFIGURATION)'
    scheme: '$(IOS_SCHEME)'
    sdk: 'iphoneos'
    xcWorkspacePath: 'ios/Runner.xcworkspace'
    signingOption: 'default'
    archivePath: '$(Build.ArtifactStagingDirectory)/Runner.xcarchive'

- task: Xcode@5
  displayName: 'Export IPA'
  inputs:
    actions: 'export'
    archivePath: '$(Build.ArtifactStagingDirectory)/Runner.xcarchive'
    exportPath: '$(Build.ArtifactStagingDirectory)/ipa'
    exportOptions: 'plist'
    exportOptionsPlist: 'ios/ExportOptions.plist'

The export step only needs the export options plist (which references the provisioning profile by name), not manual signing inputs.

How to prevent it

  • Keep signingOption: 'default' for any Xcode task that builds/archives a workspace containing SPM dependencies.
  • Define signing in Xcode project settings, not in the pipeline task, so SPM targets inherit automatic signing.
  • Use ExportOptions.plist for distribution profile selection during export, not the archive task.
  • Test pipeline changes on a feature branch before merging to dev/main.

FAQ

Why does archiving work locally in Xcode but fail in Azure DevOps?

Xcode’s GUI uses automatic signing for SPM targets by default. The Azure DevOps Xcode@5 task with signingOption: 'manual' forcibly applies the same provisioning profile to every target, which SPM targets reject.

Can I keep manual signing for the Runner target only?

Yes. Set signingOption: 'default' in the task and configure the Runner target’s signing (manual or automatic) in Xcode. The task will respect the project-level settings.

What if I have multiple targets needing different profiles?

Microsoft’s documentation recommends separate build tasks per target. For Flutter, the Runner target is the only one you sign; SPM targets must use automatic signing. Use default signing and let Xcode handle the rest.

Sources & credits

Parts of this guide are adapted from content licensed under CC BY-SA 4.0; this article is shared under the same license.