@@ -22,6 +22,25 @@ TEAM_ID = "654C9Y2C3F"
2222OUTPUT_DIR = "#{ ROOT_DIR } /src-tauri/gen/apple/build"
2323IPA_PATH = "#{ OUTPUT_DIR } /Lunch.ipa"
2424
25+ # Fix Tauri iOS project issue where Externals folder in sources causes
26+ # "Multiple commands produce libapp.a" error (both debug and release copied)
27+ # See: https://github.com/tauri-apps/tauri/issues/13578
28+ def fix_tauri_project_yml
29+ project_yml_path = "#{ ROOT_DIR } /src-tauri/gen/apple/project.yml"
30+ return unless File . exist? ( project_yml_path )
31+
32+ content = File . read ( project_yml_path )
33+ # Remove "- path: Externals" from sources to prevent duplicate libapp.a
34+ # libapp.a is already linked via dependencies, no need to copy as resource
35+ if content . include? ( "- path: Externals" )
36+ content . gsub! ( /^\s *- path: Externals\n / , "" )
37+ File . write ( project_yml_path , content )
38+ UI . message ( "Fixed project.yml: removed Externals from sources" )
39+ # Regenerate Xcode project with xcodegen
40+ sh ( "cd #{ ROOT_DIR } /src-tauri/gen/apple && xcodegen generate" )
41+ end
42+ end
43+
2544# App Store Connect API Key configuration
2645# Set these environment variables:
2746# - APP_STORE_CONNECT_API_KEY_KEY_ID: API Key ID
@@ -121,6 +140,60 @@ platform :ios do
121140 )
122141 end
123142
143+ desc "Build only (no upload) - for testing"
144+ lane :build_only do
145+ configure_minio
146+ match ( type : "appstore" , readonly : true )
147+
148+ # Fix Tauri project.yml to prevent duplicate libapp.a error
149+ fix_tauri_project_yml
150+
151+ # Configure Xcode project signing before Tauri build
152+ update_code_signing_settings (
153+ use_automatic_signing : false ,
154+ path : XCODEPROJ ,
155+ team_id : TEAM_ID ,
156+ bundle_identifier : APP_IDENTIFIER ,
157+ profile_name : "match AppStore #{ APP_IDENTIFIER } " ,
158+ code_sign_identity : "Apple Distribution"
159+ )
160+
161+ # TODO: move to separate xml file
162+ # Write custom ExportOptions.plist for app-store export
163+ export_options_path = "#{ ROOT_DIR } /src-tauri/gen/apple/ExportOptions.plist"
164+ File . write ( export_options_path , <<~PLIST )
165+ <?xml version="1.0" encoding="UTF-8"?>
166+ <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
167+ <plist version="1.0">
168+ <dict>
169+ <key>method</key>
170+ <string>app-store</string>
171+ <key>teamID</key>
172+ <string>#{ TEAM_ID } </string>
173+ <key>signingStyle</key>
174+ <string>manual</string>
175+ <key>provisioningProfiles</key>
176+ <dict>
177+ <key>#{ APP_IDENTIFIER } </key>
178+ <string>match AppStore #{ APP_IDENTIFIER } </string>
179+ </dict>
180+ <key>uploadSymbols</key>
181+ <false/>
182+ </dict>
183+ </plist>
184+ PLIST
185+
186+ # Build using Tauri
187+ sh ( "cd #{ ROOT_DIR } /src-tauri && npx tauri ios build --export-method app-store-connect" )
188+
189+ # Find the built IPA
190+ tauri_ipa = "#{ ROOT_DIR } /src-tauri/gen/apple/build/arm64/Lunch.ipa"
191+ FileUtils . mkdir_p ( OUTPUT_DIR )
192+ FileUtils . cp ( tauri_ipa , IPA_PATH ) if File . exist? ( tauri_ipa )
193+
194+ UI . success ( "Build complete! IPA at: #{ IPA_PATH } " )
195+ end
196+
124197 desc "Build and upload to TestFlight"
125198 lane :beta do
126199 configure_minio
@@ -142,6 +215,9 @@ platform :ios do
142215 sh ( "cd #{ ROOT_DIR } /src-tauri && npx tauri ios init" )
143216 end
144217
218+ # Fix Tauri project.yml to prevent duplicate libapp.a error
219+ fix_tauri_project_yml
220+
145221 # Configure Xcode project signing before Tauri build
146222 update_code_signing_settings (
147223 use_automatic_signing : false ,
@@ -216,6 +292,9 @@ platform :ios do
216292 sh ( "cd #{ ROOT_DIR } /src-tauri && npx tauri ios init" )
217293 end
218294
295+ # Fix Tauri project.yml to prevent duplicate libapp.a error
296+ fix_tauri_project_yml
297+
219298 # Configure Xcode project signing before Tauri build
220299 update_code_signing_settings (
221300 use_automatic_signing : false ,
0 commit comments