Compare commits

...

6 Commits

Author SHA1 Message Date
0ae551615f ios: use signing identity fingerprint in ci
Some checks failed
TestFlight Release / testflight (push) Failing after 16s
2026-06-25 22:10:06 -07:00
88bef50ae7 ios: create named ci keychain in home
Some checks failed
TestFlight Release / testflight (push) Failing after 15s
2026-06-25 22:07:12 -07:00
0d069b4233 ios: create ci keychain by name
Some checks failed
TestFlight Release / testflight (push) Failing after 11s
2026-06-25 22:05:47 -07:00
60bbe077e8 ios: pass signing keychain to xcode
Some checks failed
TestFlight Release / testflight (push) Failing after 18s
2026-06-25 22:02:19 -07:00
0b09d5425b ios: handle empty ci keychain list
Some checks failed
TestFlight Release / testflight (push) Failing after 15s
2026-06-25 21:58:01 -07:00
c9a3015e35 ios: parse ci profile without keychain
Some checks failed
TestFlight Release / testflight (push) Failing after 9s
2026-06-25 21:56:19 -07:00
4 changed files with 33 additions and 19 deletions

View File

@@ -90,19 +90,20 @@ jobs:
fi fi
developer_dir="$(xcode-select -p)" developer_dir="$(xcode-select -p)"
signing_dir="$(mktemp -d "${RUNNER_TEMP:-${TMPDIR:-/tmp}}/sybil-signing.XXXXXX")" signing_dir="$(mktemp -d "${RUNNER_TEMP:-${TMPDIR:-/tmp}}/sybil-signing.XXXXXX")"
keychain_path="${HOME}/Library/Keychains/${SIGNING_KEYCHAIN}-${GITHUB_RUN_ID:-$(uuidgen)}.keychain-db" mkdir -p "${HOME}/Library/Keychains"
keychain_name="${HOME}/Library/Keychains/${SIGNING_KEYCHAIN}-${GITHUB_RUN_ID:-$(uuidgen)}.keychain"
certificate_path="${signing_dir}/appstore-signing.p12" certificate_path="${signing_dir}/appstore-signing.p12"
wwdr_certificate_path="${signing_dir}/AppleWWDRCAG3.cer" wwdr_certificate_path="${signing_dir}/AppleWWDRCAG3.cer"
profile_path="${signing_dir}/Sybil_AppStore_CI.mobileprovision" profile_path="${signing_dir}/Sybil_AppStore_CI.mobileprovision"
profile_plist="${signing_dir}/profile.plist" profile_plist="${signing_dir}/profile.plist"
old_profile_dir="${HOME}/Library/MobileDevice/Provisioning Profiles" old_profile_dir="${HOME}/Library/MobileDevice/Provisioning Profiles"
xcode_profile_dir="${HOME}/Library/Developer/Xcode/UserData/Provisioning Profiles" xcode_profile_dir="${HOME}/Library/Developer/Xcode/UserData/Provisioning Profiles"
mkdir -p "${HOME}/Library/Keychains" "${old_profile_dir}" "${xcode_profile_dir}" mkdir -p "${old_profile_dir}" "${xcode_profile_dir}"
printf '%s' "${APPSTORE_CERTIFICATES_FILE_BASE64}" | base64 --decode > "${certificate_path}" printf '%s' "${APPSTORE_CERTIFICATES_FILE_BASE64}" | base64 --decode > "${certificate_path}"
printf '%s' "${APPSTORE_PROVISIONING_PROFILE_BASE64}" | base64 --decode > "${profile_path}" printf '%s' "${APPSTORE_PROVISIONING_PROFILE_BASE64}" | base64 --decode > "${profile_path}"
curl -fsSL https://www.apple.com/certificateauthority/AppleWWDRCAG3.cer -o "${wwdr_certificate_path}" curl -fsSL https://www.apple.com/certificateauthority/AppleWWDRCAG3.cer -o "${wwdr_certificate_path}"
security cms -D -i "${profile_path}" > "${profile_plist}" openssl smime -inform DER -verify -noverify -in "${profile_path}" -out "${profile_plist}" >/dev/null
profile_uuid="$(/usr/libexec/PlistBuddy -c 'Print UUID' "${profile_plist}")" profile_uuid="$(/usr/libexec/PlistBuddy -c 'Print UUID' "${profile_plist}")"
profile_name="$(/usr/libexec/PlistBuddy -c 'Print Name' "${profile_plist}")" profile_name="$(/usr/libexec/PlistBuddy -c 'Print Name' "${profile_plist}")"
old_profile_path="${old_profile_dir}/${profile_uuid}.mobileprovision" old_profile_path="${old_profile_dir}/${profile_uuid}.mobileprovision"
@@ -122,31 +123,37 @@ jobs:
base_keychains+=("${existing_keychain}") base_keychains+=("${existing_keychain}")
done < <(security list-keychains -d user | sed 's/[ "]//g') done < <(security list-keychains -d user | sed 's/[ "]//g')
security delete-keychain "${keychain_path}" >/dev/null 2>&1 || true security delete-keychain "${keychain_name}" >/dev/null 2>&1 || true
rm -f "${keychain_path}" rm -f "${HOME}/Library/Keychains/${keychain_name}-db"
security create-keychain -p "${keychain_password}" "${keychain_path}" security create-keychain -p "${keychain_password}" "${keychain_name}"
security set-keychain-settings -lut 21600 "${keychain_path}" security set-keychain-settings -lut 21600 "${keychain_name}"
security unlock-keychain -p "${keychain_password}" "${keychain_path}" security unlock-keychain -p "${keychain_password}" "${keychain_name}"
security import "${wwdr_certificate_path}" \ security import "${wwdr_certificate_path}" \
-k "${keychain_path}" \ -k "${keychain_name}" \
-T /usr/bin/codesign \ -T /usr/bin/codesign \
-T /usr/bin/security \ -T /usr/bin/security \
-T /usr/bin/xcodebuild -T /usr/bin/xcodebuild
security import "${certificate_path}" \ security import "${certificate_path}" \
-k "${keychain_path}" \ -k "${keychain_name}" \
-P "${APPSTORE_CERTIFICATES_PASSWORD}" \ -P "${APPSTORE_CERTIFICATES_PASSWORD}" \
-T /usr/bin/codesign \ -T /usr/bin/codesign \
-T /usr/bin/security \ -T /usr/bin/security \
-T /usr/bin/xcodebuild \ -T /usr/bin/xcodebuild \
-T "${developer_dir}/usr/bin/xcodebuild" -T "${developer_dir}/usr/bin/xcodebuild"
security set-key-partition-list -S apple-tool:,apple:,codesign: -s -k "${keychain_password}" "${keychain_path}" security set-key-partition-list -S apple-tool:,apple:,codesign: -s -k "${keychain_password}" "${keychain_name}"
security list-keychains -d user -s "${keychain_path}" "${base_keychains[@]}" if [[ "${#base_keychains[@]}" -gt 0 ]]; then
security default-keychain -d user -s "${keychain_path}" security list-keychains -d user -s "${keychain_name}" "${base_keychains[@]}"
else
security list-keychains -d user -s "${keychain_name}"
fi
security default-keychain -d user -s "${keychain_name}"
keychain_path="$(security list-keychains -d user | sed 's/[ "]//g' | head -n 1)"
security find-identity -v -p codesigning "${keychain_path}" security find-identity -v -p codesigning "${keychain_path}"
security find-identity -v -p codesigning security find-identity -v -p codesigning
echo "Installed ${profile_name} (${profile_uuid}) provisioning profile" echo "Installed ${profile_name} (${profile_uuid}) provisioning profile"
{ {
echo "SYBIL_SIGNING_KEYCHAIN_PATH=${keychain_path}" echo "SYBIL_SIGNING_KEYCHAIN_PATH=${keychain_path}"
echo "SYBIL_SIGNING_KEYCHAIN_NAME=${keychain_name}"
echo "SYBIL_SIGNING_KEYCHAIN_PASSWORD=${keychain_password}" echo "SYBIL_SIGNING_KEYCHAIN_PASSWORD=${keychain_password}"
echo "SYBIL_PREVIOUS_DEFAULT_KEYCHAIN=${previous_default_keychain}" echo "SYBIL_PREVIOUS_DEFAULT_KEYCHAIN=${previous_default_keychain}"
echo "SYBIL_PROVISIONING_PROFILE_UUID=${profile_uuid}" echo "SYBIL_PROVISIONING_PROFILE_UUID=${profile_uuid}"

View File

@@ -7,7 +7,8 @@ SYBIL_PROVIDER_PUBLIC_ID=c043d167-ad88-4036-84ea-76c223f1b1b2
SYBIL_PROVISIONING_PROFILE_SPECIFIER=Sybil AppStore CI SYBIL_PROVISIONING_PROFILE_SPECIFIER=Sybil AppStore CI
SYBIL_PROVISIONING_PROFILE_UUID= SYBIL_PROVISIONING_PROFILE_UUID=
SYBIL_CODE_SIGN_IDENTITY=Apple Distribution: James Magahern (DQQH5H6GBD) SYBIL_CODE_SIGN_IDENTITY=Apple Distribution: James Magahern (DQQH5H6GBD)
SYBIL_XCODE_CODE_SIGN_IDENTITY=Apple Distribution SYBIL_XCODE_CODE_SIGN_IDENTITY=6B74B268C4761720FB2051D01D8BB3E47B55D9F5
SYBIL_EXPORT_SIGNING_CERTIFICATE=Apple Distribution
SYBIL_SIGNING_CERTIFICATE_ID= SYBIL_SIGNING_CERTIFICATE_ID=
SYBIL_SIGNING_KEYCHAIN= SYBIL_SIGNING_KEYCHAIN=

View File

@@ -47,14 +47,17 @@ default.
Fastlane keeps two signing names separate. `SYBIL_CODE_SIGN_IDENTITY` is the Fastlane keeps two signing names separate. `SYBIL_CODE_SIGN_IDENTITY` is the
exact certificate common name used when exporting a local p12 for secrets, while exact certificate common name used when exporting a local p12 for secrets, while
`SYBIL_XCODE_CODE_SIGN_IDENTITY` defaults to the generic `Apple Distribution` `SYBIL_XCODE_CODE_SIGN_IDENTITY` defaults to the certificate SHA-1 fingerprint
selector that Xcode uses during archive/export. that Xcode uses during archive. `SYBIL_EXPORT_SIGNING_CERTIFICATE` defaults to
the generic `Apple Distribution` selector used in the export options.
The Release signing settings are also present in `Apps/Sybil/project.yml` so The Release signing settings are also present in `Apps/Sybil/project.yml` so
XcodeGen emits a manually signed App Store archive configuration. CI passes the XcodeGen emits a manually signed App Store archive configuration. CI passes the
installed provisioning profile UUID to Fastlane as installed provisioning profile UUID to Fastlane as
`SYBIL_PROVISIONING_PROFILE_UUID`; Fastlane writes that UUID into the generated `SYBIL_PROVISIONING_PROFILE_UUID`; Fastlane writes that UUID into the generated
project before archiving. project before archiving. CI also passes the temporary keychain path as
`CODE_SIGN_KEYCHAIN` so Xcode searches the disposable keychain for the imported
Distribution identity.
If the Apple team has reached the Distribution certificate limit, set If the Apple team has reached the Distribution certificate limit, set
`SYBIL_SIGNING_CERTIFICATE_ID` to the portal id for a certificate whose private `SYBIL_SIGNING_CERTIFICATE_ID` to the portal id for a certificate whose private

View File

@@ -20,7 +20,8 @@ APP_STORE_APPLE_ID = ENV.fetch("SYBIL_APP_STORE_APPLE_ID", "6759442828")
PROVIDER_PUBLIC_ID = ENV.fetch("SYBIL_PROVIDER_PUBLIC_ID", "c043d167-ad88-4036-84ea-76c223f1b1b2") PROVIDER_PUBLIC_ID = ENV.fetch("SYBIL_PROVIDER_PUBLIC_ID", "c043d167-ad88-4036-84ea-76c223f1b1b2")
PROFILE_SPECIFIER = ENV["SYBIL_PROVISIONING_PROFILE_SPECIFIER"].to_s.strip.empty? ? "Sybil AppStore CI" : ENV["SYBIL_PROVISIONING_PROFILE_SPECIFIER"] PROFILE_SPECIFIER = ENV["SYBIL_PROVISIONING_PROFILE_SPECIFIER"].to_s.strip.empty? ? "Sybil AppStore CI" : ENV["SYBIL_PROVISIONING_PROFILE_SPECIFIER"]
SIGNING_CERTIFICATE_NAME = ENV["SYBIL_CODE_SIGN_IDENTITY"].to_s.strip.empty? ? "Apple Distribution: James Magahern (DQQH5H6GBD)" : ENV["SYBIL_CODE_SIGN_IDENTITY"] SIGNING_CERTIFICATE_NAME = ENV["SYBIL_CODE_SIGN_IDENTITY"].to_s.strip.empty? ? "Apple Distribution: James Magahern (DQQH5H6GBD)" : ENV["SYBIL_CODE_SIGN_IDENTITY"]
XCODE_CODE_SIGN_IDENTITY = ENV["SYBIL_XCODE_CODE_SIGN_IDENTITY"].to_s.strip.empty? ? "Apple Distribution" : ENV["SYBIL_XCODE_CODE_SIGN_IDENTITY"] XCODE_CODE_SIGN_IDENTITY = ENV["SYBIL_XCODE_CODE_SIGN_IDENTITY"].to_s.strip.empty? ? "6B74B268C4761720FB2051D01D8BB3E47B55D9F5" : ENV["SYBIL_XCODE_CODE_SIGN_IDENTITY"]
EXPORT_SIGNING_CERTIFICATE = ENV["SYBIL_EXPORT_SIGNING_CERTIFICATE"].to_s.strip.empty? ? "Apple Distribution" : ENV["SYBIL_EXPORT_SIGNING_CERTIFICATE"]
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")
@@ -71,6 +72,7 @@ def apply_release_signing_settings
settings["PROVISIONING_PROFILE_SPECIFIER"] = PROFILE_SPECIFIER settings["PROVISIONING_PROFILE_SPECIFIER"] = PROFILE_SPECIFIER
settings["CODE_SIGN_IDENTITY"] = XCODE_CODE_SIGN_IDENTITY settings["CODE_SIGN_IDENTITY"] = XCODE_CODE_SIGN_IDENTITY
settings["CODE_SIGN_IDENTITY[sdk=iphoneos*]"] = XCODE_CODE_SIGN_IDENTITY settings["CODE_SIGN_IDENTITY[sdk=iphoneos*]"] = XCODE_CODE_SIGN_IDENTITY
settings["CODE_SIGN_KEYCHAIN"] = ENV["SYBIL_SIGNING_KEYCHAIN_PATH"] if present?(ENV["SYBIL_SIGNING_KEYCHAIN_PATH"])
if present?(ENV["SYBIL_PROVISIONING_PROFILE_UUID"]) if present?(ENV["SYBIL_PROVISIONING_PROFILE_UUID"])
settings["PROVISIONING_PROFILE"] = ENV["SYBIL_PROVISIONING_PROFILE_UUID"] settings["PROVISIONING_PROFILE"] = ENV["SYBIL_PROVISIONING_PROFILE_UUID"]
settings["PROVISIONING_PROFILE[sdk=iphoneos*]"] = ENV["SYBIL_PROVISIONING_PROFILE_UUID"] settings["PROVISIONING_PROFILE[sdk=iphoneos*]"] = ENV["SYBIL_PROVISIONING_PROFILE_UUID"]
@@ -435,6 +437,7 @@ platform :ios do
xcode_build_setting("CURRENT_PROJECT_VERSION", build_number) xcode_build_setting("CURRENT_PROJECT_VERSION", build_number)
] ]
if present?(ENV["SYBIL_SIGNING_KEYCHAIN_PATH"]) if present?(ENV["SYBIL_SIGNING_KEYCHAIN_PATH"])
xcode_args << xcode_build_setting("CODE_SIGN_KEYCHAIN", ENV.fetch("SYBIL_SIGNING_KEYCHAIN_PATH"))
xcode_args << xcode_build_setting("OTHER_CODE_SIGN_FLAGS", "--keychain #{ENV.fetch("SYBIL_SIGNING_KEYCHAIN_PATH")}") xcode_args << xcode_build_setting("OTHER_CODE_SIGN_FLAGS", "--keychain #{ENV.fetch("SYBIL_SIGNING_KEYCHAIN_PATH")}")
end end
xcode_args = xcode_args.join(" ") xcode_args = xcode_args.join(" ")
@@ -455,7 +458,7 @@ platform :ios do
provisioningProfiles: { provisioningProfiles: {
APP_IDENTIFIER => PROFILE_SPECIFIER APP_IDENTIFIER => PROFILE_SPECIFIER
}, },
signingCertificate: XCODE_CODE_SIGN_IDENTITY, signingCertificate: EXPORT_SIGNING_CERTIFICATE,
teamID: TEAM_ID, teamID: TEAM_ID,
manageAppVersionAndBuildNumber: false, manageAppVersionAndBuildNumber: false,
uploadSymbols: true, uploadSymbols: true,