I've been struggling for about a week trying to write a Github action that builds and uploads an iOS ipa to App Store Connect.
I seem to be running into issues when trying create the ipa file itself. I've tried a number of variations of the following workflow yml:
name: Manual Workflow
on:
workflow_dispatch:
inputs:
job:
description: 'Select the job to run'
required: true
default: 'build_and_upload_to_google_play'
type: choice
options:
- build_and_upload_to_app_store_connect
jobs:
build_and_upload_to_app_store_connect:
if: ${{ github.event.inputs.job == 'build_and_upload_to_app_store_connect' }}
runs-on: macos-latest
steps:
- name: checkout repository
uses: actions/checkout@v3
- name: Install the Apple certificate and provisioning profile
env:
BUILD_CERTIFICATE_BASE64: ${{ secrets.DEVELOPMENT_CERTIFICATE_BASE64 }}
P12_PASSWORD: ${{ secrets.P12_PASSWORD }}
BUILD_PROVISION_PROFILE_BASE64: ${{ secrets.DEVELOPMENT_PROVISIONING_PROFILE_BASE64 }}
KEYCHAIN_PASSWORD: ${{ secrets.KEYCHAIN_PASSWORD }}
run: |
# create variables
CERTIFICATE_PATH=$RUNNER_TEMP/build_certificate.p12
PP_PATH=$RUNNER_TEMP/build_pp.mobileprovision
KEYCHAIN_PATH=$RUNNER_TEMP/app-signing.keychain-db
# import certificate and provisioning profile from secrets
echo -n "$BUILD_CERTIFICATE_BASE64" | base64 --decode -o $CERTIFICATE_PATH
echo -n "$BUILD_PROVISION_PROFILE_BASE64" | base64 --decode -o $PP_PATH
# create temporary keychain
security create-keychain -p "$KEYCHAIN_PASSWORD" $KEYCHAIN_PATH
security set-keychain-settings -lut 21600 $KEYCHAIN_PATH
security unlock-keychain -p "$KEYCHAIN_PASSWORD" $KEYCHAIN_PATH
# import certificate to keychain
security import $CERTIFICATE_PATH -P "$P12_PASSWORD" -A -t cert -f pkcs12 -k $KEYCHAIN_PATH
security list-keychain -d user -s $KEYCHAIN_PATH
# apply provisioning profile
mkdir -p ~/Library/MobileDevice/Provisioning\ Profiles
cp $PP_PATH ~/Library/MobileDevice/Provisioning\ Profiles
- name: build archive
run: |
xcodebuild -workspace ios/Runner.xcworkspace \
-scheme Runner \
-archivePath build/ios/archive/Runner.xcarchive \
-sdk iphoneos \
-configuration Debug \
-destination generic/platform=iOS \
clean archive
- name: export ipa
env:
EXPORT_OPTIONS_PLIST: ${{ secrets.EXPORT_OPTIONS_PLIST }}
run: |
EXPORT_OPTS_PATH=$RUNNER_TEMP/ExportOptions.plist
echo -n "$EXPORT_OPTIONS_PLIST" | base64 --decode -o $EXPORT_OPTS_PATH
xcodebuild -exportArchive -archivePath $RUNNER_TEMP/Runner.xcarchive -exportOptionsPlist $EXPORT_OPTS_PATH -exportPath $RUNNER_TEMP/build
No matter what I do, I am always seeing some variation of these error messages:
/Users/runner/work/my-project/my-project/ios/Runner.xcodeproj: error: No Accounts: Add a new account in Accounts settings. (in target 'Runner' from project 'Runner')
/Users/runner/work/my-project/my-project/ios/Runner.xcodeproj: error: No profiles for 'com.bundle.identifier' were found: Xcode couldn't find any iOS App Development provisioning profiles matching 'com.bundle.identifier'. (in target 'Runner' from project 'Runner')
Here's my ExportOptions.plist I got from a local archive:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" ".0.dtd">
<plist version="1.0">
<dict>
<key>destination</key>
<string>export</string>
<key>generateAppStoreInformation</key>
<false/>
<key>manageAppVersionAndBuildNumber</key>
<true/>
<key>method</key>
<string>app-store-connect</string>
<key>signingStyle</key>
<string>automatic</string>
<key>stripSwiftSymbols</key>
<true/>
<key>teamID</key>
<string>C5VQVD6UKF</string>
<key>testFlightInternalTestingOnly</key>
<false/>
<key>uploadSymbols</key>
<true/>
</dict>
</plist>
I have tried variations of "Automatically managed signing" on and off and have the same result either way. When "Automatically managed signing" has been off, I had assigned a Development provisioning profile to the debug and profile configs, and a Distribution provisioning profile to the release config.
I also have my development and distribution provisioning profiles signed with two different signing certificates.
I have also tried variations of installing both provisioning profiles and their associated certificates as well as installing each provisioning profile and their associated certificate individually.
I guess the questions I have are:
- Should my project be using "Automatically managed signing" if I want to build/upload an ipa in a CI/CD pipeline?
- If the answer to 1 is "no", am I correct in my assertion that the release build config should be signed with the Distribution provisioning profile and the other two with the Development provisioning profile?
- Did I make a mistake in signing my Distribution and Development provisioning profiles with two distinct signing certificates?
- What is the established approach for building an iOS ipa on a remote machine? Is there anything I am doing that is obviously wrong?
P.S.:
It's probably worth mentioning that I have tried using fastlane
and flutter build
instead of xcodebuild
directly, but have ultimately run into the "No Accounts" and "No profiles" errors no matter what I've tried.
I've been struggling for about a week trying to write a Github action that builds and uploads an iOS ipa to App Store Connect.
I seem to be running into issues when trying create the ipa file itself. I've tried a number of variations of the following workflow yml:
name: Manual Workflow
on:
workflow_dispatch:
inputs:
job:
description: 'Select the job to run'
required: true
default: 'build_and_upload_to_google_play'
type: choice
options:
- build_and_upload_to_app_store_connect
jobs:
build_and_upload_to_app_store_connect:
if: ${{ github.event.inputs.job == 'build_and_upload_to_app_store_connect' }}
runs-on: macos-latest
steps:
- name: checkout repository
uses: actions/checkout@v3
- name: Install the Apple certificate and provisioning profile
env:
BUILD_CERTIFICATE_BASE64: ${{ secrets.DEVELOPMENT_CERTIFICATE_BASE64 }}
P12_PASSWORD: ${{ secrets.P12_PASSWORD }}
BUILD_PROVISION_PROFILE_BASE64: ${{ secrets.DEVELOPMENT_PROVISIONING_PROFILE_BASE64 }}
KEYCHAIN_PASSWORD: ${{ secrets.KEYCHAIN_PASSWORD }}
run: |
# create variables
CERTIFICATE_PATH=$RUNNER_TEMP/build_certificate.p12
PP_PATH=$RUNNER_TEMP/build_pp.mobileprovision
KEYCHAIN_PATH=$RUNNER_TEMP/app-signing.keychain-db
# import certificate and provisioning profile from secrets
echo -n "$BUILD_CERTIFICATE_BASE64" | base64 --decode -o $CERTIFICATE_PATH
echo -n "$BUILD_PROVISION_PROFILE_BASE64" | base64 --decode -o $PP_PATH
# create temporary keychain
security create-keychain -p "$KEYCHAIN_PASSWORD" $KEYCHAIN_PATH
security set-keychain-settings -lut 21600 $KEYCHAIN_PATH
security unlock-keychain -p "$KEYCHAIN_PASSWORD" $KEYCHAIN_PATH
# import certificate to keychain
security import $CERTIFICATE_PATH -P "$P12_PASSWORD" -A -t cert -f pkcs12 -k $KEYCHAIN_PATH
security list-keychain -d user -s $KEYCHAIN_PATH
# apply provisioning profile
mkdir -p ~/Library/MobileDevice/Provisioning\ Profiles
cp $PP_PATH ~/Library/MobileDevice/Provisioning\ Profiles
- name: build archive
run: |
xcodebuild -workspace ios/Runner.xcworkspace \
-scheme Runner \
-archivePath build/ios/archive/Runner.xcarchive \
-sdk iphoneos \
-configuration Debug \
-destination generic/platform=iOS \
clean archive
- name: export ipa
env:
EXPORT_OPTIONS_PLIST: ${{ secrets.EXPORT_OPTIONS_PLIST }}
run: |
EXPORT_OPTS_PATH=$RUNNER_TEMP/ExportOptions.plist
echo -n "$EXPORT_OPTIONS_PLIST" | base64 --decode -o $EXPORT_OPTS_PATH
xcodebuild -exportArchive -archivePath $RUNNER_TEMP/Runner.xcarchive -exportOptionsPlist $EXPORT_OPTS_PATH -exportPath $RUNNER_TEMP/build
No matter what I do, I am always seeing some variation of these error messages:
/Users/runner/work/my-project/my-project/ios/Runner.xcodeproj: error: No Accounts: Add a new account in Accounts settings. (in target 'Runner' from project 'Runner')
/Users/runner/work/my-project/my-project/ios/Runner.xcodeproj: error: No profiles for 'com.bundle.identifier' were found: Xcode couldn't find any iOS App Development provisioning profiles matching 'com.bundle.identifier'. (in target 'Runner' from project 'Runner')
Here's my ExportOptions.plist I got from a local archive:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>destination</key>
<string>export</string>
<key>generateAppStoreInformation</key>
<false/>
<key>manageAppVersionAndBuildNumber</key>
<true/>
<key>method</key>
<string>app-store-connect</string>
<key>signingStyle</key>
<string>automatic</string>
<key>stripSwiftSymbols</key>
<true/>
<key>teamID</key>
<string>C5VQVD6UKF</string>
<key>testFlightInternalTestingOnly</key>
<false/>
<key>uploadSymbols</key>
<true/>
</dict>
</plist>
I have tried variations of "Automatically managed signing" on and off and have the same result either way. When "Automatically managed signing" has been off, I had assigned a Development provisioning profile to the debug and profile configs, and a Distribution provisioning profile to the release config.
I also have my development and distribution provisioning profiles signed with two different signing certificates.
I have also tried variations of installing both provisioning profiles and their associated certificates as well as installing each provisioning profile and their associated certificate individually.
I guess the questions I have are:
- Should my project be using "Automatically managed signing" if I want to build/upload an ipa in a CI/CD pipeline?
- If the answer to 1 is "no", am I correct in my assertion that the release build config should be signed with the Distribution provisioning profile and the other two with the Development provisioning profile?
- Did I make a mistake in signing my Distribution and Development provisioning profiles with two distinct signing certificates?
- What is the established approach for building an iOS ipa on a remote machine? Is there anything I am doing that is obviously wrong?
P.S.:
It's probably worth mentioning that I have tried using fastlane
and flutter build
instead of xcodebuild
directly, but have ultimately run into the "No Accounts" and "No profiles" errors no matter what I've tried.
1 Answer
Reset to default 0 +500You should specify the provisioning profiles you used in the Xcode project in the ExportOption.plist
:
Here is a minimal one:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>method</key>
<string>app-store</string>
<key>provisioningProfiles</key>
<dict>
<key>com.bundle.identifier</key>
<string>match AppStore com.bundle.identifier</string>
</dict>
<key>signingStyle</key>
<string>manual</string>
</dict>
</plist>
If you have multiple targets like app extensions, add them into the dict too.
ExportOption.plist
first. – Itachi Commented Mar 19 at 5:10