diff --git a/.gitea/workflows/testflight.yml b/.gitea/workflows/testflight.yml index e5aaf44..d7ad90e 100644 --- a/.gitea/workflows/testflight.yml +++ b/.gitea/workflows/testflight.yml @@ -33,6 +33,25 @@ jobs: brew install xcodegen fi + - name: Prepare Runner Keychain + env: + HOME: /var/lib/act_runner + run: | + set -euo pipefail + mkdir -p "${HOME}/Library/Keychains" + + login_keychain="${HOME}/Library/Keychains/login.keychain" + if [ ! -f "${login_keychain}-db" ]; then + security create-keychain -p "" "${login_keychain}" + fi + + security unlock-keychain -p "" "${login_keychain}" 2>/dev/null || \ + security unlock-keychain -p "sybil-ci-keychain-password" "${login_keychain}" 2>/dev/null || true + security default-keychain -s "${login_keychain}" + security list-keychains -d user -s "${login_keychain}-db" + security delete-keychain "${HOME}/Library/Keychains/sybil_ci_keychain" >/dev/null 2>&1 || true + rm -f "${HOME}/Library/Keychains/sybil_ci_keychain" "${HOME}/Library/Keychains/sybil_ci_keychain-db" + - name: Upload to TestFlight working-directory: ios env: diff --git a/ios/fastlane/Fastfile b/ios/fastlane/Fastfile index 58ed55c..79f57d6 100644 --- a/ios/fastlane/Fastfile +++ b/ios/fastlane/Fastfile @@ -1,3 +1,4 @@ +require "fileutils" require "shellwords" default_platform(:ios) @@ -8,9 +9,12 @@ TEAM_ID = "DQQH5H6GBD" PROFILE_NAME = "Sybil AppStore CI" SIGNING_IDENTITY = "Apple Distribution: James Magahern (DQQH5H6GBD)" CI_KEYCHAIN_NAME = "sybil_ci_keychain" +CI_KEYCHAIN_PASSWORD = "" IOS_ROOT = File.expand_path("..", __dir__) PROJECT_FILE = File.join(IOS_ROOT, "Sybil.xcodeproj") PROJECT_SPEC = File.join(IOS_ROOT, "project.yml") +CI_KEYCHAIN_PATH = File.join(File.expand_path("~/Library/Keychains"), CI_KEYCHAIN_NAME) +CI_KEYCHAIN_DB_PATH = "#{CI_KEYCHAIN_PATH}-db" def present?(value) !value.to_s.strip.empty? @@ -35,7 +39,7 @@ def ci? end def ci_keychain_path - File.expand_path("~/Library/Keychains/#{CI_KEYCHAIN_NAME}-db") + File.file?(CI_KEYCHAIN_DB_PATH) ? CI_KEYCHAIN_DB_PATH : CI_KEYCHAIN_PATH end platform :ios do @@ -51,27 +55,40 @@ platform :ios do private_lane :setup_ci_signing do next unless ci? - setup_ci( - force: true, - keychain_name: CI_KEYCHAIN_NAME, - timeout: 3600 + FileUtils.mkdir_p(File.dirname(CI_KEYCHAIN_PATH)) + sh("security delete-keychain #{CI_KEYCHAIN_PATH.shellescape} || true", log: false) + FileUtils.rm_f(CI_KEYCHAIN_PATH) + FileUtils.rm_f(CI_KEYCHAIN_DB_PATH) + + create_keychain( + path: CI_KEYCHAIN_PATH, + password: CI_KEYCHAIN_PASSWORD, + default_keychain: true, + unlock: true, + timeout: 3600, + lock_when_sleeps: true, + add_to_search_list: true ) + + ENV["MATCH_KEYCHAIN_NAME"] = CI_KEYCHAIN_PATH + ENV["MATCH_KEYCHAIN_PASSWORD"] = CI_KEYCHAIN_PASSWORD + ENV["MATCH_READONLY"] = "true" end private_lane :cleanup_ci_signing do next unless ci? - next unless ENV["MATCH_KEYCHAIN_NAME"] == CI_KEYCHAIN_NAME - delete_keychain(name: CI_KEYCHAIN_NAME) + delete_keychain(keychain_path: ci_keychain_path) rescue => error UI.message("Unable to delete temporary CI keychain: #{error.message}") ensure ENV.delete("MATCH_KEYCHAIN_NAME") ENV.delete("MATCH_KEYCHAIN_PASSWORD") + ENV.delete("MATCH_READONLY") end private_lane :sync_signing do |options| - match( + match_options = { type: "appstore", readonly: options.fetch(:readonly), app_identifier: APP_IDENTIFIER, @@ -82,7 +99,11 @@ platform :ios do git_full_name: "Sybil Release Bot", git_user_email: "james.magahern@me.com", api_key: options.fetch(:api_key) - ) + } + match_options[:keychain_name] = ENV["MATCH_KEYCHAIN_NAME"] if present?(ENV["MATCH_KEYCHAIN_NAME"]) + match_options[:keychain_password] = ENV["MATCH_KEYCHAIN_PASSWORD"] if ENV.key?("MATCH_KEYCHAIN_PASSWORD") + + match(match_options) end private_lane :verify_ci_signing do