I'm currently using a macos GitHub runner from their virtual environments for CI/CD for my iOS application. This works very well.
To sign the app, the Apple certificate and provisioning profile is set on the GitHub runner with the credentials stored in GitHub secrets in a step in the workflow file:
- name: Install the Apple certificate and provisioning profile
env:
BUILD_CERTIFICATE_BASE64: ${{ secrets.IOS_ENTERPRISE_CERTIFICATE_BASE64 }}
P12_PASSWORD: ${{ secrets.IOS_ENTERPRISE_CERTIFICATE_PASSWORD }}
BUILD_PROVISION_PROFILE_BASE64: ${{ secrets.IOS__PROVISION_PROFILE_BASE64 }}
KEYCHAIN_PASSWORD: ${{ secrets.IOS_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
This code is exactly copied from the GitHub documentation from here:
They iOS build itself is done with the lane build_ios_app
with fastlane.
Because the GitHub runners are very expensive, I want to switch to a self-hosted runner with a MacMini M1.
But here is the problem:
The MacMini is set up with a admin user called runner
and installed the action-runner script according to documentation from GitHub.
The MacMini was completely new installed with no certificate or profiles in the keychain.
But the build always fails with the following error:
** ARCHIVE FAILED **
The following build commands failed:
CodeSign /Users/runner/actions-runner/_work/{someFolder}/{someFolder}/iosApp/Build/DerivedData/Build/Intermediates.noindex/ArchiveIntermediates/iosApp/InstallationBuildProductsLocation/Applications/iosApp.app (in target 'iosApp' from project 'iosApp')
(1 failure)
[12:31:13]: Exit status: 65
+---------------+------------------------------+
| Build environment |
+---------------+------------------------------+
| xcode_path | /Applications/Xcode_14.2.app |
| gym_version | 2.212.1 |
| export_method | enterprise |
| sdk | iPhoneOS16.2.sdk |
+---------------+------------------------------+
[12:31:13]: ▸ Warning: unable to build chain to self-signed root for signer "iPhone Distribution: {MyName}"
[12:31:13]: ▸ /Users/runner/actions-runner/_work/{someFolder}/{someFolder}/iosApp/Build/DerivedData/Build/Intermediates.noindex/ArchiveIntermediates/iosApp/InstallationBuildProductsLocation/Applications/iosApp.app: errSecInternalComponent
[12:31:13]: ▸ Command CodeSign failed with a nonzero exit code
I don't get why it's running perfectly on GitHub runner environment, but NOT in my self-hosted runner environment.
Solution (which worked for me)
The issue was, that the MacMini machine was missing the Apple Worldwide Developer Relations Certification Authority
certificate in the keychain.
Actually this will automatically be installed by Xcode, but for some reason this was not the case on my machine.
Important is, that the certificate will be imported to the system keychain.
The certificate can be downloaded here:
https://www.apple.com/certificateauthority/
To find the correct certificate matching your iOS Distribution certificate you have to check the information of your iOS Distribution certificate:
For me it was the Authority G3. Download and import the correct one from the Apple PKI (link above) to your system keychain:
Now all my failed runs with CodeSign
was gone.