feat: update iOS CI/CD with FUTO build credential (#28146)
* update email * Update fastfile * use different apple id * debug build * build onlypull/26478/head
parent
b74cfd4424
commit
bc4abd18e4
|
|
@ -1,5 +1,5 @@
|
|||
app_identifier "app.alextran.immich" # The bundle identifier of your app
|
||||
apple_id "alex.tran1502@gmail.com" # Your Apple email address
|
||||
apple_id "altran@futo.org" # Your Apple email address
|
||||
|
||||
|
||||
# For more information about the Appfile, see:
|
||||
|
|
|
|||
|
|
@ -17,10 +17,11 @@ default_platform(:ios)
|
|||
|
||||
platform :ios do
|
||||
# Constants
|
||||
TEAM_ID = "2F67MQ8R79"
|
||||
CODE_SIGN_IDENTITY = "Apple Distribution: Hau Tran (#{TEAM_ID})"
|
||||
TEAM_ID = "2W7AC6T8T5"
|
||||
CODE_SIGN_IDENTITY = "Apple Distribution: FUTO Holdings, Inc. (#{TEAM_ID})"
|
||||
BASE_BUNDLE_ID = "app.alextran.immich"
|
||||
|
||||
DEV_BUNDLE_ID = "tech.futo.immich.testflight"
|
||||
|
||||
# Helper method to get App Store Connect API key
|
||||
def get_api_key
|
||||
app_store_connect_api_key(
|
||||
|
|
@ -44,47 +45,45 @@ def get_version_from_pubspec
|
|||
end
|
||||
|
||||
# Helper method to configure code signing for all targets
|
||||
def configure_code_signing(bundle_id_suffix: "", profile_name_main:, profile_name_share:, profile_name_widget:)
|
||||
bundle_suffix = bundle_id_suffix.empty? ? "" : ".#{bundle_id_suffix}"
|
||||
|
||||
def configure_code_signing(base_bundle_id:, profile_name_main:, profile_name_share:, profile_name_widget:)
|
||||
# Runner (main app)
|
||||
update_code_signing_settings(
|
||||
use_automatic_signing: false,
|
||||
path: "./Runner.xcodeproj",
|
||||
team_id: ENV["FASTLANE_TEAM_ID"] || TEAM_ID,
|
||||
code_sign_identity: CODE_SIGN_IDENTITY,
|
||||
bundle_identifier: "#{BASE_BUNDLE_ID}#{bundle_suffix}",
|
||||
bundle_identifier: base_bundle_id,
|
||||
profile_name: profile_name_main,
|
||||
targets: ["Runner"]
|
||||
)
|
||||
|
||||
|
||||
# ShareExtension
|
||||
update_code_signing_settings(
|
||||
use_automatic_signing: false,
|
||||
path: "./Runner.xcodeproj",
|
||||
team_id: ENV["FASTLANE_TEAM_ID"] || TEAM_ID,
|
||||
code_sign_identity: CODE_SIGN_IDENTITY,
|
||||
bundle_identifier: "#{BASE_BUNDLE_ID}#{bundle_suffix}.ShareExtension",
|
||||
bundle_identifier: "#{base_bundle_id}.ShareExtension",
|
||||
profile_name: profile_name_share,
|
||||
targets: ["ShareExtension"]
|
||||
)
|
||||
|
||||
|
||||
# WidgetExtension
|
||||
update_code_signing_settings(
|
||||
use_automatic_signing: false,
|
||||
path: "./Runner.xcodeproj",
|
||||
team_id: ENV["FASTLANE_TEAM_ID"] || TEAM_ID,
|
||||
code_sign_identity: CODE_SIGN_IDENTITY,
|
||||
bundle_identifier: "#{BASE_BUNDLE_ID}#{bundle_suffix}.Widget",
|
||||
bundle_identifier: "#{base_bundle_id}.Widget",
|
||||
profile_name: profile_name_widget,
|
||||
targets: ["WidgetExtension"]
|
||||
)
|
||||
end
|
||||
|
||||
|
||||
# Helper method to build and upload to TestFlight
|
||||
def build_and_upload(
|
||||
api_key:,
|
||||
bundle_id_suffix: "",
|
||||
base_bundle_id:,
|
||||
configuration: "Release",
|
||||
distribute_external: true,
|
||||
version_number: nil,
|
||||
|
|
@ -92,9 +91,8 @@ end
|
|||
profile_name_share:,
|
||||
profile_name_widget:
|
||||
)
|
||||
bundle_suffix = bundle_id_suffix.empty? ? "" : ".#{bundle_id_suffix}"
|
||||
app_identifier = "#{BASE_BUNDLE_ID}#{bundle_suffix}"
|
||||
|
||||
app_identifier = base_bundle_id
|
||||
|
||||
# Set version number if provided
|
||||
if version_number
|
||||
increment_version_number(version_number: version_number)
|
||||
|
|
@ -138,31 +136,31 @@ end
|
|||
desc "iOS Development Build to TestFlight (requires separate bundle ID)"
|
||||
lane :gha_testflight_dev do
|
||||
api_key = get_api_key
|
||||
|
||||
|
||||
# Download and install provisioning profiles from App Store Connect
|
||||
# Certificate is imported by GHA workflow into build.keychain
|
||||
# Capture profile names after each sigh call
|
||||
sigh(api_key: api_key, app_identifier: "#{BASE_BUNDLE_ID}.development", force: true)
|
||||
sigh(api_key: api_key, app_identifier: DEV_BUNDLE_ID, force: true)
|
||||
main_profile_name = lane_context[SharedValues::SIGH_NAME]
|
||||
|
||||
sigh(api_key: api_key, app_identifier: "#{BASE_BUNDLE_ID}.development.ShareExtension", force: true)
|
||||
|
||||
sigh(api_key: api_key, app_identifier: "#{DEV_BUNDLE_ID}.ShareExtension", force: true)
|
||||
share_profile_name = lane_context[SharedValues::SIGH_NAME]
|
||||
|
||||
sigh(api_key: api_key, app_identifier: "#{BASE_BUNDLE_ID}.development.Widget", force: true)
|
||||
|
||||
sigh(api_key: api_key, app_identifier: "#{DEV_BUNDLE_ID}.Widget", force: true)
|
||||
widget_profile_name = lane_context[SharedValues::SIGH_NAME]
|
||||
|
||||
|
||||
# Configure code signing for dev bundle IDs using the downloaded profile names
|
||||
configure_code_signing(
|
||||
bundle_id_suffix: "development",
|
||||
base_bundle_id: DEV_BUNDLE_ID,
|
||||
profile_name_main: main_profile_name,
|
||||
profile_name_share: share_profile_name,
|
||||
profile_name_widget: widget_profile_name
|
||||
)
|
||||
|
||||
|
||||
# Build and upload
|
||||
build_and_upload(
|
||||
api_key: api_key,
|
||||
bundle_id_suffix: "development",
|
||||
base_bundle_id: DEV_BUNDLE_ID,
|
||||
configuration: "Profile",
|
||||
distribute_external: false,
|
||||
profile_name_main: main_profile_name,
|
||||
|
|
@ -189,6 +187,7 @@ end
|
|||
|
||||
# Configure code signing for production bundle IDs
|
||||
configure_code_signing(
|
||||
base_bundle_id: BASE_BUNDLE_ID,
|
||||
profile_name_main: main_profile_name,
|
||||
profile_name_share: share_profile_name,
|
||||
profile_name_widget: widget_profile_name
|
||||
|
|
@ -197,6 +196,7 @@ end
|
|||
# Build and upload with version number
|
||||
build_and_upload(
|
||||
api_key: api_key,
|
||||
base_bundle_id: BASE_BUNDLE_ID,
|
||||
version_number: get_version_from_pubspec,
|
||||
distribute_external: false,
|
||||
profile_name_main: main_profile_name,
|
||||
|
|
@ -243,30 +243,30 @@ end
|
|||
|
||||
desc "iOS Build Only (no TestFlight upload)"
|
||||
lane :gha_build_only do
|
||||
# Use the same build process as production, just skip the upload
|
||||
# This ensures PR builds validate the same way as production builds
|
||||
|
||||
# Use the same build process as the dev TestFlight lane, just skip the upload
|
||||
# This ensures PR builds validate the same way as dev TestFlight builds
|
||||
|
||||
api_key = get_api_key
|
||||
|
||||
|
||||
# Download and install provisioning profiles from App Store Connect
|
||||
# Certificate is imported by GHA workflow into build.keychain
|
||||
sigh(api_key: api_key, app_identifier: "#{BASE_BUNDLE_ID}.development", force: true)
|
||||
sigh(api_key: api_key, app_identifier: DEV_BUNDLE_ID, force: true)
|
||||
main_profile_name = lane_context[SharedValues::SIGH_NAME]
|
||||
|
||||
sigh(api_key: api_key, app_identifier: "#{BASE_BUNDLE_ID}.development.ShareExtension", force: true)
|
||||
|
||||
sigh(api_key: api_key, app_identifier: "#{DEV_BUNDLE_ID}.ShareExtension", force: true)
|
||||
share_profile_name = lane_context[SharedValues::SIGH_NAME]
|
||||
|
||||
sigh(api_key: api_key, app_identifier: "#{BASE_BUNDLE_ID}.development.Widget", force: true)
|
||||
|
||||
sigh(api_key: api_key, app_identifier: "#{DEV_BUNDLE_ID}.Widget", force: true)
|
||||
widget_profile_name = lane_context[SharedValues::SIGH_NAME]
|
||||
|
||||
|
||||
# Configure code signing for dev bundle IDs
|
||||
configure_code_signing(
|
||||
bundle_id_suffix: "development",
|
||||
base_bundle_id: DEV_BUNDLE_ID,
|
||||
profile_name_main: main_profile_name,
|
||||
profile_name_share: share_profile_name,
|
||||
profile_name_widget: widget_profile_name
|
||||
)
|
||||
|
||||
|
||||
# Build the app (same as gha_testflight_dev but without upload)
|
||||
build_app(
|
||||
scheme: "Runner",
|
||||
|
|
@ -277,9 +277,9 @@ end
|
|||
xcargs: "-skipMacroValidation CODE_SIGN_IDENTITY='#{CODE_SIGN_IDENTITY}' CODE_SIGN_STYLE=Manual",
|
||||
export_options: {
|
||||
provisioningProfiles: {
|
||||
"#{BASE_BUNDLE_ID}.development" => main_profile_name,
|
||||
"#{BASE_BUNDLE_ID}.development.ShareExtension" => share_profile_name,
|
||||
"#{BASE_BUNDLE_ID}.development.Widget" => widget_profile_name
|
||||
DEV_BUNDLE_ID => main_profile_name,
|
||||
"#{DEV_BUNDLE_ID}.ShareExtension" => share_profile_name,
|
||||
"#{DEV_BUNDLE_ID}.Widget" => widget_profile_name
|
||||
},
|
||||
signingStyle: "manual",
|
||||
signingCertificate: CODE_SIGN_IDENTITY
|
||||
|
|
|
|||
Loading…
Reference in New Issue