Runner (self-hosted, macOS) as service fails code-signing step on xcode archive
Describe the bug
Runner fails xcode signing step while being run as a service via ./svh.sh start, however while using the runner via ./run.sh the job completes successfully
To Reproduce
- Create fresh ReactNative app
- Setup Fastlane (just ios, since android works fine). See example file below
- Setup workflow file. see example below
- Configure self-hosted runner on macOS
- Launch runner as service
./svc.sh install>./svc.sh start - Trigger a job for the runner
- Archive fails on codesigning step
Expected behavior Using runner as service should result in the same output as using the runner via the run command.
Runner Version and Platform
System
System: MacMini
Chip: Apple M2
Memory: 8GB
macOS: Sonoma 14.5
Runner
$ tar xzf ./actions-runner-osx-arm64-2.317.0.tar.gz
Gemfile
source 'https://rubygems.org'
# You may use http://rbenv.org/ or https://rvm.io/ to install and use this version
ruby ">= 2.7.7"
# Cocoapods 1.15 introduced a bug which break the build. We will remove the upper
# bound in the template on Cocoapods with next React Native release.
gem 'cocoapods', '>= 1.13', '< 1.15'
gem 'activesupport', '>= 6.1.7.5', '< 7.1.0'
gem "fastlane", "~> 2.222"
What's not working?
xcodebuild fails on signing step for the first native module of a RN app. There is not really an explanation on why. Here is a rundown of things I tried to fix the issue
Note: This whole time I was able to compile the app both in XCode and by manually executing the fastlane
1. Restarting mac mini (i know i know.. its a meme but you never know)
2. Switching between automatic and manual signing
Signing is the usual culprit when building iOS apps via CI but doing any changes had no effect on the archive error.
Initially I used automatic signing from XCode by enabling it in XCode on the project itself and in Gymfile via
xcargs("-allowProvisioningUpdates")
Next I tried switching over to manual signing using Match and modifying the fastlane configs accordingly, yet the app still won't build
3. Configure fastlane to use different keychain
I noticed in the docs for fastlane they recommend adding setup_ci setup_ci to resolve potentional keychain issues but this had no effect on the error either.
4. Upgraded Ruby
Initially I used the system provided Ruby but then I found a similar error online and someone mentioned that upgrading Ruby fixed it for them. So I ended up using Ruby 2.7.7 via rvm.
Job Log Output
Fastlane Output
Creating temporary keychain: "fastlane_tmp_keychain".
Found keychain '~/Library/Keychains/fastlane_tmp_keychain', creation skipped
If creating a new Keychain DB is required please set the `require_create` option true to cause the action to fail
$ security list-keychains -d user
▸ "/Users/adambeno/Library/Keychains/login.keychain-db"
▸ "/Users/adambeno/Library/Keychains/fastlane_tmp_keychain-db"
Found keychain '/Users/adambeno/Library/Keychains/fastlane_tmp_keychain-db' in list-keychains, adding to search list skipped
Enabling match readonly mode.
...
All required keys, certificates and provisioning profiles are installed 🙌
Setting Provisioning Profile type to 'app-store'
Cruising back to lane 'ios deploy' 🚘
...
Resolving Swift Package Manager dependencies...
$ xcodebuild -resolvePackageDependencies -workspace ./ios/REDACTED.xcworkspace -scheme REDACTED
▸ Command line invocation:
▸ /Applications/Xcode.app/Contents/Developer/usr/bin/xcodebuild -resolvePackageDependencies -workspace ./ios/REDACTED.xcworkspace -scheme REDACTED
▸ User defaults from command line:
▸ IDEPackageSupportUseBuiltinSCM = YES
▸ resolved source packages:
$ xcodebuild -showBuildSettings -workspace ./ios/REDACTED.xcworkspace -scheme REDACTED 2>&1
Command timed out after 3 seconds on try 1 of 4, trying again with a 6 second timeout...
Command timed out after 6 seconds on try 2 of 4, trying again with a 12 second timeout...
Detected provisioning profile mapping: {:"my.redacted.app"=>"match AppStore my.redacted.app"}
...
Command line invocation:
/Applications/Xcode.app/Contents/Developer/usr/bin/xcodebuild -workspace ./ios/REDACTED.xcworkspace -scheme REDACTED -sdk iphoneos17.5 -destination generic/platform=iOS -archivePath "/Users/adambeno/Library/Developer/Xcode/Archives/2024-07-28/app 2024-07-28 19.18.59.xcarchive" clean archive
User defaults from command line:
IDEArchivePathOverride = /Users/adambeno/Library/Developer/Xcode/Archives/2024-07-28/app 2024-07-28 19.18.59.xcarchive
IDEPackageSupportUseBuiltinSCM = YES
Build settings from command line:
SDKROOT = iphoneos17.5
** CLEAN SUCCEEDED **
Prepare packages
ComputeTargetDependencyGraph
note: Building targets in dependency order
note: Target dependency graph (173 targets)
...
ERROR HAPPENS HERE
mkdir -p /Users/adambeno/Library/Developer/Xcode/DerivedData/REDACTED-bjrkhordkwvgekgrnokrjfrpnvrj/Build/Intermediates.noindex/ArchiveIntermediates/REDACTED/BuildProductsPath/Release-iphoneos/REDACTED.app/Frameworks
rsync --delete -av --filter P .*.?????? --links --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "/Users/adambeno/Library/Developer/Xcode/DerivedData/REDACTED-bjrkhordkwvgekgrnokrjfrpnvrj/Build/Intermediates.noindex/ArchiveIntermediates/REDACTED/BuildProductsPath/Release-iphoneos/XCFrameworkIntermediates/ffmpeg-kit-ios-min-gpl/ffmpegkit.framework" "/Users/adambeno/Library/Developer/Xcode/DerivedData/REDACTED-bjrkhordkwvgekgrnokrjfrpnvrj/Build/Intermediates.noindex/ArchiveIntermediates/REDACTED/InstallationBuildProductsLocation/Applications/REDACTED.app/Frameworks"
building file list ... done
ffmpegkit.framework/
ffmpegkit.framework/Info.plist
ffmpegkit.framework/LICENSE
ffmpegkit.framework/SOURCE
ffmpegkit.framework/ffmpegkit
ffmpegkit.framework/strip-frameworks.sh
sent 595181 bytes received 136 bytes 1190634.00 bytes/sec
total size is 594685 speedup is 1.00
Code Signing /Users/adambeno/Library/Developer/Xcode/DerivedData/REDACTED-bjrkhordkwvgekgrnokrjfrpnvrj/Build/Intermediates.noindex/ArchiveIntermediates/REDACTED/InstallationBuildProductsLocation/Applications/REDACTED.app/Frameworks/ffmpegkit.framework with Identity Apple Distribution: REDACTED (REDACTED)
/usr/bin/codesign --force --sign 229CEREDACTEDCAC --preserve-metadata=identifier,entitlements '/Users/adambeno/Library/Developer/Xcode/DerivedData/REDACTED-bjrkhordkwvgekgrnokrjfrpnvrj/Build/Intermediates.noindex/ArchiveIntermediates/REDACTED/InstallationBuildProductsLocation/Applications/REDACTED.app/Frameworks/ffmpegkit.framework'
# THIS ??
/Users/adambeno/Library/Developer/Xcode/DerivedData/REDACTED-bjrkhordkwvgekgrnokrjfrpnvrj/Build/Intermediates.noindex/ArchiveIntermediates/REDACTED/InstallationBuildProductsLocation/Applications/REDACTED.app/Frameworks/ffmpegkit.framework: errSecInternalComponent
Command PhaseScriptExecution failed with a nonzero exit code
EOF
Configs
Workflow
name: Build and distribute the Android and iOS apps
on:
push:
branches:
- master
jobs:
build-ios:
runs-on: [self-hosted, macOS]
timeout-minutes: 20
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Set up Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
- name: Install NPM
run: npm ci
- name: Install bundle
run: bundle install
- name: Build app
run: bundle exec fastlane ios deploy
Fastfile
fastlane_require "dotenv"
before_all do
ensure_git_status_clean
update_fastlane
Dotenv.overload ".env"
end
platform :ios do
private_lane :signing do |options|
setup_ci(timeout: 0)
match(
type: options[:type],
readonly: is_ci
)
end
private_lane :appstore_connect do
app_store_connect_api_key(
key_id: ENV["APPSTORE_CONNECT_KEY_ID"],
issuer_id: ENV["APPSTORE_CONNECT_ISSUER"],
key_filepath: ENV["APPSTORE_CONNECT_KEY"],
duration: 1200, # optional (maximum 1200)
in_house: true # optional but may be required if using match/sigh
)
end
desc "Build new version of the app"
lane :build do
# Install pods
cocoapods(
podfile: "./ios",
clean_install: true
)
signing(type: "appstore")
# Build the .ipa from gymfile
gym
end
lane :deploy do
# Configure appstore connect API
appstore_connect
# Install pods
cocoapods(
podfile: "./ios",
clean_install: true
)
signing(type: "appstore")
# Build the app
gym
# Distribute app to TestFlight
pilot
end
end
Appfile
json_key_file("./service-account.json") # Path to the json secret file - Follow https://docs.fastlane.tools/actions/supply/#setup to get one
package_name("my.redacted.app") # e.g. com.krausefx.app
app_identifier("myredacted.app") # The bundle identifier of your app
apple_id("[email protected]") # Your Apple Developer Portal username
itc_team_id("REDACTED") # App Store Connect Team ID
team_id("REDACTED") # Developer Portal Team ID
# For more information about the Appfile, see:
# https://docs.fastlane.tools/advanced/#appfile
Gymfile
# For more information about this configuration visit
# https://docs.fastlane.tools/actions/gym/#gymfile
# In general, you can use the options available
# fastlane gym --help
# Remove the # in front of the line to enable the option
workspace("./ios/REDACTED.xcworkspace")
sdk("iphoneos17.5")
scheme("REDACTED")
clean(true)
export_method("app-store")
# Enable automatic signing via xcode
# xcargs("-allowProvisioningUpdates") // Switched over to manual signing
include_symbols(true)
include_bitcode(false)
output_directory("./fastlane/builds/")
output_name("app.ipa")
buildlog_path("./fastlane/logs/")
Conclusion
I intially thought it's the service being unable to reach the keychain but after setting up the setup_ci step in fastlane and it having access to the chain + being able to write the certs I really have no idea what could be causing this issue. Maybe it's just xcode being xcode again...
At least I can still use the pipeline with ./run.sh to keep my autobuilds going 🙏
I encountered the same issue, when i am using runner as service, i got error like this:
CodeSign /Users/administrator/path/to/target.appex (in target 'target' from project 'project' at path '/Users/administrator/path/to/project.xcodeproj')
cd xxx
Signing Identity: "Apple Development: xxx xx (XXXXXXX)"
Provisioning Profile: "iOS Team Provisioning Profile: com.xxx.xxx"
(xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx)
/usr/bin/codesign --force --sign XXXXXXXXXXXXXXXXXXXXX --entitlements /Users/administrator/xxxx.appex.xcent --generate-entitlement-der /Users/administrator/xxxx.appex
/Users/administrator/xxxx.appex: errSecInternalComponent
Command CodeSign failed with a nonzero exit code
But when i am using ./run.sh in terminal directly, everything is fine.
@Adam-Beno, I managed to code-signing when running runner as a service, i just tried unlocking login keychain (my signing key is on the login keychain) before running the xcodebuild cmd, and it works! Here's my code:
# ....
print("unlocking login keychain...")
# check if there is a file named login.keychain-password in the LOGIN_KEYCHAIN_PASSWORD_PATH
login_keychain_password_path = LOGIN_KEYCHAIN_PASSWORD_PATH.joinpath(
"login.keychain-password"
)
if login_keychain_password_path.exists():
keychain_password = login_keychain_password_path.read_text().strip()
if keychain_password:
print("unlocking login keychain with password...")
subprocess.run(
[
"security",
"unlock-keychain",
"-p",
keychain_password,
"login.keychain",
],
check=True,
)
else:
print("unlocking login keychain without password...")
subprocess.run(
[
"security",
"unlock-keychain",
"login.keychain",
],
check=True,
)
else:
print("login.keychain-password file not found, don't unlock login keychain")
## ....
print("cleaning...")
subprocess.run(
[
"xcodebuild",
"clean",
"-project",
XCODE_PROJECT_PATH,
"-scheme",
scheme,
"-derivedDataPath",
derived_data_path,
"-resultBundlePath",
xcode_result_bundle_path("build_clean"),
# *xcodebuild_authenticate_args,
],
check=True,
env=env,
)
print("archiving...")
subprocess.run(
[
"xcodebuild",
"archive",
"-project",
XCODE_PROJECT_PATH,
"-scheme",
scheme,
"-configuration",
build_configuration,
"-sdk",
"iphoneos",
"-destination",
"generic/platform=iOS",
"-archivePath",
archive_path,
"-derivedDataPath",
derived_data_path,
"-resultBundlePath",
xcode_result_bundle_path("build_archive"),
"-showBuildTimingSummary",
*xcodebuild_authenticate_args,
],
check=True,
env=env,
)
I encountered the same problem when using svc.sh to start runner.
After looking at the code of run.sh and svc.sh, I found that run.sh updates ca certificates, but svc.sh does not update.
In order to perform xcode compilation normally, you can only use run.sh to start runner.
@douba0 I don't know the exact reason, but if run.sh works well while svc.sh does not, setting SessionCreate to false in bin/actions.runner.plist.template like the following may be a solution.
<plist version="1.0">
...
<key>SessionCreate</key>
<false/>
</plist>
After reinstalling the service, the signing task in my workflow worked well.
Thanks so much, @paxbun.
Facing the same issue, changing SessionCreate to false didn't solve it for me. In the end the only thing I could come up with was to install the certs I needed on the machine directly and then take out the boilerplate github runner code to use the certs via the secrets. Not my ideal solution, but has at least unblocked me for now
@TingluoHuang I suggest this PR get reverted or we need to set the sessionCreate to false: https://github.com/actions/runner/pull/847 I spent 4-5 days debugging an installation on the latest macos 26 running the actions runners as a service and found that setting. Once we upgraded the OS from 15.7.1 to 26.1 we were no longer able to access the keychains as we used to while still having the sessionCreate true. I've tested both removing sessionCreate and setting it to false they seem to have the same result where the keychain is accessible. This is in an environment where we have the default Login and Local Items keychains both unlocked