ci: put CI keychain first in codesign search list
Some checks failed
TestFlight / testflight (push) Failing after 19s
Some checks failed
TestFlight / testflight (push) Failing after 19s
codesign resolves signing identities through the user keychain search list (first match wins) and ignores --keychain for the lookup. This runner hosts another project whose keychain holds the same Apple Distribution identity, so when that keychain is locked, codesign fails with errSecInternalComponent no matter how correctly our own keychain is set up. Prepend the fresh CI keychain to the search list for the build and always delete it afterward, which restores the original list. Also drop the runner-diagnostics step, the GitHub-hosted Ruby PATH export, and the duplicate CODE_SIGN_IDENTITY param. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -9,15 +9,10 @@ on:
|
|||||||
jobs:
|
jobs:
|
||||||
testflight:
|
testflight:
|
||||||
runs-on: macos-arm64
|
runs-on: macos-arm64
|
||||||
defaults:
|
|
||||||
run:
|
|
||||||
shell: bash
|
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
with:
|
|
||||||
fetch-depth: 0
|
|
||||||
|
|
||||||
- name: Setup Ruby
|
- name: Setup Ruby
|
||||||
uses: ruby/setup-ruby@v1
|
uses: ruby/setup-ruby@v1
|
||||||
@@ -27,19 +22,7 @@ jobs:
|
|||||||
working-directory: ios
|
working-directory: ios
|
||||||
|
|
||||||
- name: Install XcodeGen
|
- name: Install XcodeGen
|
||||||
run: |
|
run: command -v xcodegen >/dev/null 2>&1 || brew install xcodegen
|
||||||
set -euo pipefail
|
|
||||||
if ! command -v xcodegen >/dev/null 2>&1; then
|
|
||||||
brew install xcodegen
|
|
||||||
fi
|
|
||||||
|
|
||||||
- name: Runner diagnostics
|
|
||||||
run: |
|
|
||||||
set -euo pipefail
|
|
||||||
whoami
|
|
||||||
printf 'HOME=%s\n' "$HOME"
|
|
||||||
security default-keychain -d user || true
|
|
||||||
security list-keychains -d user || true
|
|
||||||
|
|
||||||
- name: Upload to TestFlight
|
- name: Upload to TestFlight
|
||||||
working-directory: ios
|
working-directory: ios
|
||||||
@@ -53,7 +36,4 @@ jobs:
|
|||||||
SYBIL_BUILD_NUMBER: ${{ github.run_number }}
|
SYBIL_BUILD_NUMBER: ${{ github.run_number }}
|
||||||
FASTLANE_SKIP_UPDATE_CHECK: "1"
|
FASTLANE_SKIP_UPDATE_CHECK: "1"
|
||||||
FASTLANE_XCODEBUILD_SETTINGS_TIMEOUT: "120"
|
FASTLANE_XCODEBUILD_SETTINGS_TIMEOUT: "120"
|
||||||
run: |
|
run: bundle exec fastlane ios beta
|
||||||
export PATH="/Users/runner/hostedtoolcache/Ruby/3.1.7/arm64/bin:${PATH}"
|
|
||||||
ruby --version
|
|
||||||
bundle exec fastlane ios beta
|
|
||||||
|
|||||||
@@ -6,6 +6,9 @@ APP_IDENTIFIER = "net.buzzert.sybil2"
|
|||||||
SCHEME = "Sybil"
|
SCHEME = "Sybil"
|
||||||
TEAM_ID = "DQQH5H6GBD"
|
TEAM_ID = "DQQH5H6GBD"
|
||||||
PROFILE_NAME = "Sybil AppStore CI"
|
PROFILE_NAME = "Sybil AppStore CI"
|
||||||
|
CI_KEYCHAIN_NAME = "sybil_ci_keychain"
|
||||||
|
CI_KEYCHAIN_PASSWORD = "sybil-ci-keychain-password"
|
||||||
|
CI_KEYCHAIN_DB_PATH = File.expand_path("~/Library/Keychains/#{CI_KEYCHAIN_NAME}-db")
|
||||||
IOS_ROOT = File.expand_path("..", __dir__)
|
IOS_ROOT = File.expand_path("..", __dir__)
|
||||||
PROJECT_FILE = File.join(IOS_ROOT, "Sybil.xcodeproj")
|
PROJECT_FILE = File.join(IOS_ROOT, "Sybil.xcodeproj")
|
||||||
PROJECT_SPEC = File.join(IOS_ROOT, "project.yml")
|
PROJECT_SPEC = File.join(IOS_ROOT, "project.yml")
|
||||||
@@ -68,20 +71,33 @@ platform :ios do
|
|||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
# CI uses a throwaway keychain that is deleted after the lane exits.
|
# CI signs headlessly, so match needs a fresh unlocked keychain to import
|
||||||
|
# into. codesign resolves identities through the user keychain *search list*
|
||||||
|
# (first match wins; the --keychain flag does not restrict the lookup), and
|
||||||
|
# other projects' keychains on this runner hold the same identity but are
|
||||||
|
# usually locked — so ours must come first. delete_keychain in the beta
|
||||||
|
# lane's ensure removes both the keychain and its search-list entry, which
|
||||||
|
# also keeps our (later locked) copy from shadowing those other projects.
|
||||||
private_lane :prepare_ci_keychain do
|
private_lane :prepare_ci_keychain do
|
||||||
next nil unless ci?
|
next unless ci?
|
||||||
|
|
||||||
run_token = "#{Time.now.to_i}_#{Process.pid}"
|
delete_keychain(name: CI_KEYCHAIN_NAME) if File.file?(CI_KEYCHAIN_DB_PATH)
|
||||||
keychain_name = "fastlane_ci_#{run_token}"
|
create_keychain(
|
||||||
|
name: CI_KEYCHAIN_NAME,
|
||||||
setup_ci(
|
password: CI_KEYCHAIN_PASSWORD,
|
||||||
force: true,
|
unlock: true,
|
||||||
keychain_name: keychain_name,
|
timeout: 3600,
|
||||||
timeout: 7_200
|
add_to_search_list: false
|
||||||
)
|
)
|
||||||
|
|
||||||
keychain_name
|
others = sh("security list-keychains -d user", log: false)
|
||||||
|
.scan(/"([^"]+)"/)
|
||||||
|
.flatten
|
||||||
|
.reject { |path| path.include?(CI_KEYCHAIN_NAME) }
|
||||||
|
sh("security list-keychains -d user -s #{([CI_KEYCHAIN_DB_PATH] + others).shelljoin}")
|
||||||
|
|
||||||
|
ENV["MATCH_KEYCHAIN_NAME"] = CI_KEYCHAIN_NAME
|
||||||
|
ENV["MATCH_KEYCHAIN_PASSWORD"] = CI_KEYCHAIN_PASSWORD
|
||||||
end
|
end
|
||||||
|
|
||||||
private_lane :sync_signing do |options|
|
private_lane :sync_signing do |options|
|
||||||
@@ -106,10 +122,7 @@ platform :ios do
|
|||||||
|
|
||||||
desc "Build and upload to TestFlight"
|
desc "Build and upload to TestFlight"
|
||||||
lane :beta do
|
lane :beta do
|
||||||
ci_keychain_name = nil
|
prepare_ci_keychain
|
||||||
|
|
||||||
begin
|
|
||||||
ci_keychain_name = prepare_ci_keychain
|
|
||||||
|
|
||||||
api_key = app_store_api_key
|
api_key = app_store_api_key
|
||||||
|
|
||||||
@@ -122,13 +135,10 @@ platform :ios do
|
|||||||
|
|
||||||
sync_signing(api_key: api_key, readonly: true)
|
sync_signing(api_key: api_key, readonly: true)
|
||||||
|
|
||||||
sh("security find-identity -v -p codesigning") if ci_keychain_name
|
|
||||||
|
|
||||||
build_app(
|
build_app(
|
||||||
project: PROJECT_FILE,
|
project: PROJECT_FILE,
|
||||||
scheme: SCHEME,
|
scheme: SCHEME,
|
||||||
export_method: "app-store",
|
export_method: "app-store",
|
||||||
codesigning_identity: "Apple Distribution",
|
|
||||||
xcargs: [
|
xcargs: [
|
||||||
"DEVELOPMENT_TEAM=#{TEAM_ID.shellescape}",
|
"DEVELOPMENT_TEAM=#{TEAM_ID.shellescape}",
|
||||||
"CODE_SIGN_STYLE=Manual",
|
"CODE_SIGN_STYLE=Manual",
|
||||||
@@ -149,7 +159,6 @@ platform :ios do
|
|||||||
skip_waiting_for_build_processing: true
|
skip_waiting_for_build_processing: true
|
||||||
)
|
)
|
||||||
ensure
|
ensure
|
||||||
delete_keychain(name: ci_keychain_name) if ci_keychain_name
|
delete_keychain(name: CI_KEYCHAIN_NAME) if ci? && File.file?(CI_KEYCHAIN_DB_PATH)
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
Reference in New Issue
Block a user