diff --git a/Runnect-iOS/Runnect-iOS.xcodeproj/project.pbxproj b/Runnect-iOS/Runnect-iOS.xcodeproj/project.pbxproj index 24ee32de..01e97aab 100644 --- a/Runnect-iOS/Runnect-iOS.xcodeproj/project.pbxproj +++ b/Runnect-iOS/Runnect-iOS.xcodeproj/project.pbxproj @@ -1788,7 +1788,7 @@ CODE_SIGN_ENTITLEMENTS = "Runnect-iOS/Runnect-iOSDebug.entitlements"; CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 2026.0218.1812; + CURRENT_PROJECT_VERSION = 2026.0426.0008; DEVELOPMENT_TEAM = 8Q4H7X3Q58; GENERATE_INFOPLIST_FILE = NO; INFOPLIST_FILE = "Runnect-iOS/Info.plist"; @@ -1806,7 +1806,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 2.4.1; + MARKETING_VERSION = 2.5.0; PRODUCT_BUNDLE_IDENTIFIER = "com.runnect.Runnect-iOS"; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; @@ -1828,7 +1828,7 @@ CODE_SIGN_ENTITLEMENTS = "Runnect-iOS/Runnect-iOS.entitlements"; CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 2026.0218.1812; + CURRENT_PROJECT_VERSION = 2026.0426.0008; DEVELOPMENT_TEAM = 8Q4H7X3Q58; GENERATE_INFOPLIST_FILE = NO; INFOPLIST_FILE = "Runnect-iOS/Info.plist"; @@ -1846,7 +1846,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 2.4.1; + MARKETING_VERSION = 2.5.0; PRODUCT_BUNDLE_IDENTIFIER = "com.runnect.Runnect-iOS"; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; diff --git a/Runnect-iOS/Runnect-iOS/Info.plist b/Runnect-iOS/Runnect-iOS/Info.plist index 9bcbe37e..c6c5e9af 100644 --- a/Runnect-iOS/Runnect-iOS/Info.plist +++ b/Runnect-iOS/Runnect-iOS/Info.plist @@ -28,7 +28,7 @@ CFBundlePackageType $(PRODUCT_BUNDLE_PACKAGE_TYPE) CFBundleShortVersionString - 2.4.3 + 2.5.0 CFBundleURLTypes @@ -53,7 +53,7 @@ CFBundleVersion - 2026.0218.1812 + 2026.0426.0008 ITSAppUsesNonExemptEncryption LSApplicationQueriesSchemes diff --git a/Runnect-iOS/fastlane/Fastfile b/Runnect-iOS/fastlane/Fastfile index 73621d5d..32bb912f 100644 --- a/Runnect-iOS/fastlane/Fastfile +++ b/Runnect-iOS/fastlane/Fastfile @@ -122,46 +122,78 @@ platform :ios do ############# TestFlight ############# + desc "iOS 메인 앱 타겟에만 버전/빌드 적용 (워치 앱 미터치)" + # Xcodeproj gem은 entry를 ID 순으로 정렬하고 PlistBuddy는 키를 알파벳 순으로 재정렬해 + # diff에 의도하지 않은 noise가 다수 생기므로, 텍스트 치환으로 정확히 필요한 라인만 수정한다. + private_lane :set_ios_app_version do |options| + version = options[:version] + build_number = Time.new.strftime("%Y.%m%d.%H%M") + + # ── project.pbxproj: 메인 앱(com.runnect.Runnect-iOS) buildSettings 블록만 수정 ── + pbxproj_path = File.expand_path("../Runnect-iOS.xcodeproj/project.pbxproj", __dir__) + pbxproj = File.read(pbxproj_path) + modified_blocks = 0 + pbxproj.gsub!(/buildSettings = \{(?:[^{}]|\{[^{}]*\})*\};/m) do |block| + if block.include?(%q{PRODUCT_BUNDLE_IDENTIFIER = "com.runnect.Runnect-iOS";}) + new_block = block + new_block = new_block.sub(/MARKETING_VERSION = [^;]+;/, "MARKETING_VERSION = #{version};") if version + new_block = new_block.sub(/CURRENT_PROJECT_VERSION = [^;]+;/, "CURRENT_PROJECT_VERSION = #{build_number};") + modified_blocks += 1 if new_block != block + new_block + else + block + end + end + UI.user_error!("메인 앱 buildSettings 블록을 찾지 못함") if modified_blocks == 0 + File.write(pbxproj_path, pbxproj) + + # ── Info.plist: GENERATE_INFOPLIST_FILE = NO이므로 두 키만 텍스트 치환 (키 순서 보존) ── + # 워치 앱 Info.plist (RNWatch Watch App/Info.plist)는 미터치 + info_plist_path = File.expand_path("../Runnect-iOS/Info.plist", __dir__) + info_plist = File.read(info_plist_path) + info_plist.sub!(/(CFBundleShortVersionString<\/key>\s*)[^<]*(<\/string>)/, "\\1#{version}\\2") if version + info_plist.sub!(/(CFBundleVersion<\/key>\s*)[^<]*(<\/string>)/, "\\1#{build_number}\\2") + File.write(info_plist_path, info_plist) + + UI.success("iOS 메인 앱만 변경: version=#{version || '(유지)'} / build=#{build_number}") + end + desc "Push a new beta build to TestFlight" - desc "Usage: fastlane beta version:2.3.0" + desc "Usage: fastlane beta version:2.5.0" lane :beta do |options| start_time = Time.now version = options[:version] api_key_data = api_key - match( - type: "appstore", - app_identifier: ["com.runnect.Runnect-iOS", "com.runnect.Runnect-iOS.watchkitapp"], - readonly: false, - api_key: api_key_data + # 코드 서명: 자동 프로비저닝 (match 인증서 revoke됨) + update_code_signing_settings( + use_automatic_signing: true, + path: "./Runnect-iOS.xcodeproj", + team_id: "8Q4H7X3Q58" ) - if version - puts "버전 정보: #{version}" - set_version(version: version) - else - increment_build_number( - build_number: Time.new.strftime("%Y.%m%d.%H%M"), - xcodeproj: "./Runnect-iOS.xcodeproj" - ) - end + # iOS 메인 앱 타겟만 버전/빌드 적용 (워치 앱 1.0 유지) + set_ios_app_version(version: version) build_app( project: "Runnect-iOS.xcodeproj", scheme: "Runnect-iOS", configuration: "Release", - clean: true + clean: true, + export_method: "app-store", + export_xcargs: "-allowProvisioningUpdates" ) upload_to_testflight( api_key: api_key_data, + skip_submission: true, skip_waiting_for_build_processing: true ) end_time = Time.now elapsed_time = ((end_time - start_time) / 60).round(2) - puts "TestFlight 배포 완료! #{elapsed_time}분 소요" + UI.success("TestFlight 배포 완료! #{elapsed_time}분 소요") end ############# Metadata Only ############# diff --git a/Runnect-iOS/fastlane/README.md b/Runnect-iOS/fastlane/README.md index c5fc5e44..bf94b1a6 100644 --- a/Runnect-iOS/fastlane/README.md +++ b/Runnect-iOS/fastlane/README.md @@ -51,7 +51,7 @@ Usage: fastlane submit_review version:2.4.1 Push a new beta build to TestFlight -Usage: fastlane beta version:2.3.0 +Usage: fastlane beta version:2.5.0 ### ios update_metadata