From bb89c4f4de1c21f974f5842622bfc2ef674c5262 Mon Sep 17 00:00:00 2001 From: mirzemehdi Date: Sun, 16 Aug 2026 17:05:47 +0200 Subject: [PATCH] Fix the iOS signing configuration that six real builds exposed MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit PR #1 merged before the pipeline had been run end to end. Three problems remained on main, each fatal on its own: xcargs: '-allowProvisioningUpdates NO' — the flag takes no value, so xcodebuild read NO as a build action and refused to start. The lane took a bump_build option the workflow never declared as an input, so every tool-triggered dispatch was rejected with HTTP 422. Dropped: update-version owns the build number and keeps it in git where it is auditable. Signing could not go through xcargs at all, because those settings hit every target and the Swift Package dependencies reject a provisioning profile. It is now applied per target with update_code_signing_settings, and manually: on automatic Xcode looks for a Development profile while match installs an App Store one. DEVELOPMENT_TEAM comes from match, since the project sets none. Verified against a live Apple account up to and including the Kotlin/Native iOS compile; the remaining failure is in the test app's own source. --- .github/workflows/publish_ios_appstore.yml | 2 + MobileApp/fastlane/Fastfile | 50 +++++++++++++--------- 2 files changed, 31 insertions(+), 21 deletions(-) diff --git a/.github/workflows/publish_ios_appstore.yml b/.github/workflows/publish_ios_appstore.yml index 613a4c57..d5315c3a 100644 --- a/.github/workflows/publish_ios_appstore.yml +++ b/.github/workflows/publish_ios_appstore.yml @@ -1,5 +1,7 @@ name: Publish iOS App +# kappmaker-workflow-version: 3 + # Builds and ships the iOS app on a GitHub macOS runner, so no Mac is needed # locally. Signing certificates are created on the runner by fastlane `match` # from your App Store Connect API key — nothing has to be exported from a Mac. diff --git a/MobileApp/fastlane/Fastfile b/MobileApp/fastlane/Fastfile index a4c1b49b..4a9629a2 100644 --- a/MobileApp/fastlane/Fastfile +++ b/MobileApp/fastlane/Fastfile @@ -227,7 +227,6 @@ platform :ios do submit_for_review = options[:submit_for_review].to_s == "true" upload_metadata = options[:upload_metadata].to_s == "true" upload_screenshots = options[:upload_screenshots].to_s == "true" - bump_build = options[:bump_build].to_s != "false" api_key = app_store_connect_api_key( key_id: ENV.fetch("ASC_KEY_ID"), @@ -239,22 +238,6 @@ platform :ios do setup_ci if ENV["CI"] - # Apple rejects an already-seen build number, and CI builds from a clean - # checkout — so the number in git never advances on its own. Take whatever - # TestFlight has already seen and go one past it. This is the CI equivalent - # of running `kappmaker update-version` before publishing locally. - if bump_build - latest = latest_testflight_build_number( - api_key: api_key, - app_identifier: bundle_id, - initial_build_number: 0 - ) rescue 0 - increment_build_number( - build_number: latest.to_i + 1, - xcodeproj: "iosApp/iosApp.xcodeproj" - ) - UI.message("Build number set to #{latest.to_i + 1}") - end # readonly:false so the FIRST run can create and store the certificate. Later # runs find it already there and reuse it. @@ -267,6 +250,31 @@ platform :ios do keychain_password: ENV["MATCH_KEYCHAIN_PASSWORD"] ) + # match publishes what it installed through these env vars. + profile_name = ENV["sigh_#{bundle_id}_appstore_profile-name"] + team_id = ENV["sigh_#{bundle_id}_appstore_team-id"] + UI.user_error!("match did not install a profile for #{bundle_id}") if profile_name.to_s.empty? + + # Signing must be set on the APP TARGET, and nowhere else. + # + # Through xcargs the settings hit EVERY target, and the Swift Package + # dependencies (Firebase, GoogleUtilities, nanopb, promises...) reject a + # provisioning profile outright — "does not support provisioning profiles". + # This action edits the pbxproj for the named target only. + # + # It also has to be manual: left on automatic, Xcode hunts for an iOS App + # DEVELOPMENT profile and fails, because match installed an App Store one. + # The project ships no DEVELOPMENT_TEAM either, so team_id comes from match. + update_code_signing_settings( + path: "iosApp/iosApp.xcodeproj", + use_automatic_signing: false, + team_id: team_id, + code_sign_identity: "Apple Distribution", + profile_name: profile_name, + targets: ["iosApp"], + build_configurations: ["Release"] + ) + build_app( scheme: "iosApp", project: "iosApp/iosApp.xcodeproj", @@ -275,9 +283,10 @@ platform :ios do silent: false, output_name: "iosApp", output_directory: output_dir, - # Explicitly manual: match already installed the profile, and letting Xcode - # "help" here is what causes the certificate churn described above. - xcargs: "-allowProvisioningUpdates NO" + export_options: { + signingStyle: "manual", + provisioningProfiles: { bundle_id => profile_name } + } ) ipa_path = File.join(output_dir, "iosApp.ipa") @@ -309,5 +318,4 @@ platform :ios do UI.success("Uploaded to TestFlight.") end end - end