From 0d9ebbd6218c2701a2ca49cf2d7a14a7fd4df859 Mon Sep 17 00:00:00 2001 From: Daniel Arantes Loverde Date: Thu, 9 Jul 2026 17:17:07 -0300 Subject: [PATCH 1/2] =?UTF-8?q?[ci-bitrise]=20Revert=20to=20fastlane-drive?= =?UTF-8?q?n=20build=20=E2=80=94=20xcode-archive=20can't=20parse=20this=20?= =?UTF-8?q?project?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit xcode-archive@5 failed: 'unkown SDKROOT: auto'. Darwin/PediFoods.xcconfig sets SDKROOT = auto and SUPPORTED_PLATFORMS = iphoneos iphonesimulator macosx (Skip's multi-platform build target) — same root cause as the earlier PLATFORM_DISPLAY_NAME failure from manage-ios-code-signing. Both are Bitrise step-side project parsers that pre-guess a single platform before invoking xcodebuild, and neither understands this project's build shape. xcodebuild itself has no problem with SDKROOT = auto (confirmed via a local build). Only Bitrise's own step parsers choke on it. Going through fastlane's build_app instead sidesteps that parser entirely — it's the same approach the Darwin/fastlane/Fastfile already used before, restored here with the earlier apikey.json JSON-escaping and DEVELOPMENT_TEAM injection fixes kept. --- Darwin/fastlane/Fastfile | 33 +++++++++----- bitrise.yml | 98 ++++++++++++++++++++-------------------- 2 files changed, 69 insertions(+), 62 deletions(-) diff --git a/Darwin/fastlane/Fastfile b/Darwin/fastlane/Fastfile index 6fc2306..cfc6f8f 100644 --- a/Darwin/fastlane/Fastfile +++ b/Darwin/fastlane/Fastfile @@ -20,26 +20,35 @@ lane :assemble do |options| ) end -# ─── Upload IPA to TestFlight (Bitrise's xcode-archive step already built it) ── lane :beta do |options| + desc "Build and upload to TestFlight" + + get_provisioning_profile(api_key_path: "fastlane/apikey.json") + + assemble + upload_to_testflight( - ipa: ENV["BITRISE_IPA_PATH"], + api_key_path: "fastlane/apikey.json", skip_waiting_for_build_processing: true ) end -# ─── Push metadata + upload IPA to App Store (Bitrise already built it) ─────── lane :release do |options| - deliver( - ipa: ENV["BITRISE_IPA_PATH"], + desc "Build and release app" + + # see https://docs.fastlane.tools/uploading-app-privacy-details/ + #upload_app_privacy_details_to_app_store(json_path: "fastlane/app_privacy_details.json") + + # if you have an apikey.json file (https://developer.apple.com/documentation/appstoreconnectapi/creating-api-keys-for-app-store-connect-api), fastlane can automatically fetch certificates and the ASC authentication information + #get_certificates(api_key_path: "fastlane/apikey.json") + get_provisioning_profile(api_key_path: "fastlane/apikey.json") + + assemble + + upload_to_app_store( + api_key_path: "fastlane/apikey.json", app_rating_config_path: "fastlane/metadata/rating.json", - release_notes: { default: "Fixes and improvements." }, - skip_screenshots: false, - skip_metadata: false, - force: true, - submit_for_review: false, - automatic_release: false, - run_precheck_before_submit: false + release_notes: { default: "Fixes and improvements." } ) end diff --git a/bitrise.yml b/bitrise.yml index 1f066ef..98d3fc6 100644 --- a/bitrise.yml +++ b/bitrise.yml @@ -9,27 +9,25 @@ meta: app: envs: - - BITRISE_PROJECT_PATH: Darwin/PediFoods.xcodeproj - opts: - is_expand: false - - BITRISE_SCHEME: PediFoods App - opts: - is_expand: false - BITRISE_DISTRIBUTION_METHOD: app-store opts: is_expand: false - - APPLE_ID: developer@loverde.com.br # MANUAL (Bitrise Secrets tab — never commit these): # ASC_KEY_ID → App Store Connect API Key ID # ASC_ISSUER_ID → App Store Connect Issuer ID - # ASC_KEY_CONTENT → .p8 file content base64-encoded - # ITC_TEAM_ID → iTunes Connect Team ID (numeric) + # ASC_KEY_CONTENT → .p8 file content (raw, written verbatim into apikey.json) # DEVELOPMENT_TEAM → Apple Developer Team ID, written into # Darwin/fastlane/AppStore.xcconfig at build time - # (Darwin/PediFoods.xcconfig leaves it blank on - # purpose — this project has no VERSIONING_SYSTEM / - # hardcoded team like LC Wallet, so it's injected - # here instead) + # (Darwin/PediFoods.xcconfig leaves it blank on purpose) + # + # NOTE: this project builds via fastlane's build_app (gym), not Bitrise's + # own xcode-archive/manage-ios-code-signing steps. Darwin/PediFoods.xcconfig + # sets SDKROOT = auto and SUPPORTED_PLATFORMS = iphoneos iphonesimulator + # macosx (Skip's multi-platform build), and Bitrise's own steps pre-parse + # the project to guess a single platform before invoking xcodebuild — that + # parser doesn't understand SDKROOT = auto and fails outright. xcodebuild + # itself handles it fine; only Bitrise's step-side parser chokes, so we + # go through fastlane directly instead. # ─── WORKFLOWS ──────────────────────────────────────────────────────────────── workflows: @@ -45,52 +43,46 @@ workflows: - content: | cd $BITRISE_SOURCE_DIR # CURRENT_PROJECT_VERSION lives in Skip.env — shared by both - # Darwin/PediFoods.xcconfig and Android/settings.gradle.kts. - # No VERSIONING_SYSTEM is set on the target, so agvtool - # (which LC Wallet uses) does not apply to this project. + # Darwin/PediFoods.xcconfig and Android/settings.gradle.kts, + # not a standard Xcode "Apple Generic Versioning" setting, + # so agvtool does not apply here. sed -i '' "s/CURRENT_PROJECT_VERSION = .*/CURRENT_PROJECT_VERSION = $BITRISE_BUILD_NUMBER/" Skip.env - script@1: - title: Write code signing team + title: Write code signing team and App Store Connect API key inputs: - content: | echo "DEVELOPMENT_TEAM = $DEVELOPMENT_TEAM" >> "$BITRISE_SOURCE_DIR/Darwin/fastlane/AppStore.xcconfig" - - xcode-archive@5: + # ASC_KEY_CONTENT is the raw multi-line .p8 PEM content — build + # the JSON with Ruby's encoder so its embedded newlines get + # escaped correctly instead of breaking the JSON string. + export APIKEY_PATH="$BITRISE_SOURCE_DIR/Darwin/fastlane/apikey.json" + ruby -rjson -e ' + File.write(ENV["APIKEY_PATH"], JSON.generate({ + "key_id" => ENV["ASC_KEY_ID"], + "issuer_id" => ENV["ASC_ISSUER_ID"], + "key" => ENV["ASC_KEY_CONTENT"], + "in_house" => false + })) + ' + - fastlane@3: inputs: - - project_path: $BITRISE_PROJECT_PATH - - scheme: $BITRISE_SCHEME - - distribution_method: $BITRISE_DISTRIBUTION_METHOD - - automatic_code_signing: api-key - - register_test_devices: "no" - - deploy-to-itunesconnect-deliver@2: - inputs: - - itunescon_user: $APPLE_ID - - api_key_path: "" - - api_issuer: $ASC_ISSUER_ID - - submit_for_review: "no" - - skip_metadata: "yes" - - skip_screenshots: "yes" + - lane: beta + - work_dir: $BITRISE_SOURCE_DIR/Darwin # ── Full release → App Store ─────────────────────────────────────────────── release: - description: Build, sign, push metadata, upload binary to App Store - envs: - - ASC_KEY_ID: $ASC_KEY_ID - - ASC_ISSUER_ID: $ASC_ISSUER_ID - - ASC_KEY_CONTENT: $ASC_KEY_CONTENT - - ITC_TEAM_ID: $ITC_TEAM_ID + description: Build, sign, and upload to App Store steps: - git-clone@8: {} - script@1: - title: Verify ASC secrets + title: Verify secrets inputs: - content: | - if [ -z "$ASC_KEY_ID" ]; then - echo "ERROR: ASC_KEY_ID is empty" + if [ -z "$ASC_KEY_ID" ] || [ -z "$DEVELOPMENT_TEAM" ]; then + echo "ERROR: ASC_KEY_ID / ASC_ISSUER_ID / ASC_KEY_CONTENT / DEVELOPMENT_TEAM must be set in Bitrise Secrets" exit 1 fi echo "ASC_KEY_ID is set (length: ${#ASC_KEY_ID})" - echo "ASC_ISSUER_ID is set (length: ${#ASC_ISSUER_ID})" - echo "ASC_KEY_CONTENT is set (length: ${#ASC_KEY_CONTENT})" echo "DEVELOPMENT_TEAM is set (length: ${#DEVELOPMENT_TEAM})" - script@1: title: Set build number @@ -99,23 +91,29 @@ workflows: cd $BITRISE_SOURCE_DIR sed -i '' "s/CURRENT_PROJECT_VERSION = .*/CURRENT_PROJECT_VERSION = $BITRISE_BUILD_NUMBER/" Skip.env - script@1: - title: Write code signing team + title: Write code signing team and App Store Connect API key inputs: - content: | echo "DEVELOPMENT_TEAM = $DEVELOPMENT_TEAM" >> "$BITRISE_SOURCE_DIR/Darwin/fastlane/AppStore.xcconfig" - - xcode-archive@5: - inputs: - - project_path: $BITRISE_PROJECT_PATH - - scheme: $BITRISE_SCHEME - - distribution_method: $BITRISE_DISTRIBUTION_METHOD - - automatic_code_signing: api-key + # ASC_KEY_CONTENT is the raw multi-line .p8 PEM content — build + # the JSON with Ruby's encoder so its embedded newlines get + # escaped correctly instead of breaking the JSON string. + export APIKEY_PATH="$BITRISE_SOURCE_DIR/Darwin/fastlane/apikey.json" + ruby -rjson -e ' + File.write(ENV["APIKEY_PATH"], JSON.generate({ + "key_id" => ENV["ASC_KEY_ID"], + "issuer_id" => ENV["ASC_ISSUER_ID"], + "key" => ENV["ASC_KEY_CONTENT"], + "in_house" => false + })) + ' - fastlane@3: inputs: - lane: release - work_dir: $BITRISE_SOURCE_DIR/Darwin - deploy-to-bitrise-io@2: {} -# ─── TRIGGER MAP ────────────────────────────────────────────────────────────── +# ─── TRIGGER MAP ──────────────────────────────────────────────────────────────── trigger_map: - push_branch: develop workflow: beta From f94bf26bdcdb9ea5ed56356e0521caa66af3b883 Mon Sep 17 00:00:00 2001 From: Daniel Arantes Loverde Date: Thu, 9 Jul 2026 17:23:13 -0300 Subject: [PATCH 2/2] Update bitrise.yml --- bitrise.yml | 183 ++++++++++++++++++++++++++++++++++------------------ 1 file changed, 122 insertions(+), 61 deletions(-) diff --git a/bitrise.yml b/bitrise.yml index 98d3fc6..0a2b9d9 100644 --- a/bitrise.yml +++ b/bitrise.yml @@ -9,29 +9,91 @@ meta: app: envs: + - TEST_SHARD_COUNT: 2 + - BITRISE_PROJECT_PATH: PediFoods.xcodeproj + opts: + is_expand: false + - BITRISE_SCHEME: PediFoods App + opts: + is_expand: false - BITRISE_DISTRIBUTION_METHOD: app-store opts: is_expand: false + - APPLE_ID: developer@loverde.com.br # MANUAL (Bitrise Secrets tab — never commit these): # ASC_KEY_ID → App Store Connect API Key ID # ASC_ISSUER_ID → App Store Connect Issuer ID - # ASC_KEY_CONTENT → .p8 file content (raw, written verbatim into apikey.json) - # DEVELOPMENT_TEAM → Apple Developer Team ID, written into - # Darwin/fastlane/AppStore.xcconfig at build time - # (Darwin/PediFoods.xcconfig leaves it blank on purpose) - # - # NOTE: this project builds via fastlane's build_app (gym), not Bitrise's - # own xcode-archive/manage-ios-code-signing steps. Darwin/PediFoods.xcconfig - # sets SDKROOT = auto and SUPPORTED_PLATFORMS = iphoneos iphonesimulator - # macosx (Skip's multi-platform build), and Bitrise's own steps pre-parse - # the project to guess a single platform before invoking xcodebuild — that - # parser doesn't understand SDKROOT = auto and fails outright. xcodebuild - # itself handles it fine; only Bitrise's step-side parser chokes, so we - # go through fastlane directly instead. + # ASC_KEY_CONTENT → .p8 file content base64-encoded + # ITC_TEAM_ID → iTunes Connect Team ID (numeric) + +# ─── PIPELINES ──────────────────────────────────────────────────────────────── +pipelines: + run_tests: + workflows: + build_for_testing: {} + test_without_building: + depends_on: + - build_for_testing + parallel: "$TEST_SHARD_COUNT" # ─── WORKFLOWS ──────────────────────────────────────────────────────────────── workflows: + # ── Parallel test pipeline: step 1 — build only ─────────────────────────── + build_for_testing: + description: Build app for testing (no run) — used by run_tests pipeline + steps: + - git-clone@8: {} + - xcode-build-for-test@3: + inputs: + - project_path: $BITRISE_PROJECT_PATH + - scheme: $BITRISE_SCHEME + - simulator_device: iPhone 16 + - simulator_os_version: latest + - output_tool: xcpretty + - deploy-to-bitrise-io@2: + inputs: + - pipeline_intermediate_files: "$BITRISE_TEST_BUNDLE_ZIP_PATH:BITRISE_TEST_BUNDLE_ZIP_PATH" + + # ── Parallel test pipeline: step 2 — run shards ─────────────────────────── + test_without_building: + description: Run test shards in parallel — depends on build_for_testing + steps: + - pull-intermediate-files@1: + inputs: + - artifact_sources: build_for_testing + - xcode-test-without-building@0: + inputs: + - xctestrun: $BITRISE_TEST_BUNDLE_ZIP_PATH + - destination: platform=iOS Simulator,name=iPhone 16,OS=latest + - test_shard_index: $BITRISE_IO_PARALLEL_INDEX + - total_number_of_shards: $TEST_SHARD_COUNT + - generate_code_coverage_files: "yes" + + # ── Metadata push (no build) ─────────────────────────────────────────────── + metadata: + description: Push App Store metadata and screenshots for all languages + steps: + - git-clone@8: {} + - fastlane@3: + inputs: + - lane: metadata + - work_dir: $BITRISE_SOURCE_DIR + + # ── Simple single-machine test (non-parallel) ────────────────────────────── + test: + description: Run unit tests (single machine, for PR checks) + steps: + - git-clone@8: {} + - xcode-test@5: + inputs: + - project_path: $BITRISE_PROJECT_PATH + - scheme: $BITRISE_SCHEME + - simulator_device: iPhone 16 + - simulator_os_version: latest + - should_build_before_test: "yes" + - generate_code_coverage_files: "yes" + # ── Beta → TestFlight ────────────────────────────────────────────────────── beta: description: Build, sign, and upload to TestFlight @@ -42,80 +104,79 @@ workflows: inputs: - content: | cd $BITRISE_SOURCE_DIR - # CURRENT_PROJECT_VERSION lives in Skip.env — shared by both - # Darwin/PediFoods.xcconfig and Android/settings.gradle.kts, - # not a standard Xcode "Apple Generic Versioning" setting, - # so agvtool does not apply here. - sed -i '' "s/CURRENT_PROJECT_VERSION = .*/CURRENT_PROJECT_VERSION = $BITRISE_BUILD_NUMBER/" Skip.env - - script@1: - title: Write code signing team and App Store Connect API key + agvtool new-version -all $BITRISE_BUILD_NUMBER + - manage-ios-code-signing@2: inputs: - - content: | - echo "DEVELOPMENT_TEAM = $DEVELOPMENT_TEAM" >> "$BITRISE_SOURCE_DIR/Darwin/fastlane/AppStore.xcconfig" - # ASC_KEY_CONTENT is the raw multi-line .p8 PEM content — build - # the JSON with Ruby's encoder so its embedded newlines get - # escaped correctly instead of breaking the JSON string. - export APIKEY_PATH="$BITRISE_SOURCE_DIR/Darwin/fastlane/apikey.json" - ruby -rjson -e ' - File.write(ENV["APIKEY_PATH"], JSON.generate({ - "key_id" => ENV["ASC_KEY_ID"], - "issuer_id" => ENV["ASC_ISSUER_ID"], - "key" => ENV["ASC_KEY_CONTENT"], - "in_house" => false - })) - ' - - fastlane@3: + - distribution_method: app-store + - project_path: $BITRISE_PROJECT_PATH + - scheme: $BITRISE_SCHEME + # MANUAL: Upload .p12 cert + .mobileprovision in + # Bitrise → Code Signing tab BEFORE running this workflow + - xcode-archive@5: inputs: - - lane: beta - - work_dir: $BITRISE_SOURCE_DIR/Darwin + - project_path: $BITRISE_PROJECT_PATH + - scheme: $BITRISE_SCHEME + - distribution_method: $BITRISE_DISTRIBUTION_METHOD + - automatic_code_signing: api-key + - register_test_devices: "no" + - deploy-to-itunesconnect-deliver@2: + inputs: + - itunescon_user: $APPLE_ID + - api_key_path: "" + - api_issuer: $ASC_ISSUER_ID + - submit_for_review: "no" + - skip_metadata: "yes" + - skip_screenshots: "yes" # ── Full release → App Store ─────────────────────────────────────────────── release: - description: Build, sign, and upload to App Store + description: Build, sign, push metadata+screenshots, upload binary to App Store + envs: + - ASC_KEY_ID: $ASC_KEY_ID + - ASC_ISSUER_ID: $ASC_ISSUER_ID + - ASC_KEY_CONTENT: $ASC_KEY_CONTENT + - ITC_TEAM_ID: $ITC_TEAM_ID steps: - git-clone@8: {} - script@1: - title: Verify secrets + title: Verify ASC secrets inputs: - content: | - if [ -z "$ASC_KEY_ID" ] || [ -z "$DEVELOPMENT_TEAM" ]; then - echo "ERROR: ASC_KEY_ID / ASC_ISSUER_ID / ASC_KEY_CONTENT / DEVELOPMENT_TEAM must be set in Bitrise Secrets" + if [ -z "$ASC_KEY_ID" ]; then + echo "ERROR: ASC_KEY_ID is empty" exit 1 fi echo "ASC_KEY_ID is set (length: ${#ASC_KEY_ID})" - echo "DEVELOPMENT_TEAM is set (length: ${#DEVELOPMENT_TEAM})" + echo "ASC_ISSUER_ID is set (length: ${#ASC_ISSUER_ID})" + echo "ASC_KEY_CONTENT is set (length: ${#ASC_KEY_CONTENT})" - script@1: title: Set build number inputs: - content: | cd $BITRISE_SOURCE_DIR - sed -i '' "s/CURRENT_PROJECT_VERSION = .*/CURRENT_PROJECT_VERSION = $BITRISE_BUILD_NUMBER/" Skip.env - - script@1: - title: Write code signing team and App Store Connect API key + agvtool new-version -all $BITRISE_BUILD_NUMBER + - manage-ios-code-signing@2: inputs: - - content: | - echo "DEVELOPMENT_TEAM = $DEVELOPMENT_TEAM" >> "$BITRISE_SOURCE_DIR/Darwin/fastlane/AppStore.xcconfig" - # ASC_KEY_CONTENT is the raw multi-line .p8 PEM content — build - # the JSON with Ruby's encoder so its embedded newlines get - # escaped correctly instead of breaking the JSON string. - export APIKEY_PATH="$BITRISE_SOURCE_DIR/Darwin/fastlane/apikey.json" - ruby -rjson -e ' - File.write(ENV["APIKEY_PATH"], JSON.generate({ - "key_id" => ENV["ASC_KEY_ID"], - "issuer_id" => ENV["ASC_ISSUER_ID"], - "key" => ENV["ASC_KEY_CONTENT"], - "in_house" => false - })) - ' + - distribution_method: app-store + - project_path: $BITRISE_PROJECT_PATH + - scheme: $BITRISE_SCHEME + - xcode-archive@5: + inputs: + - project_path: $BITRISE_PROJECT_PATH + - scheme: $BITRISE_SCHEME + - distribution_method: $BITRISE_DISTRIBUTION_METHOD + - automatic_code_signing: api-key - fastlane@3: inputs: - lane: release - - work_dir: $BITRISE_SOURCE_DIR/Darwin + - work_dir: $BITRISE_SOURCE_DIR - deploy-to-bitrise-io@2: {} -# ─── TRIGGER MAP ──────────────────────────────────────────────────────────────── +# ─── TRIGGER MAP ────────────────────────────────────────────────────────────── trigger_map: - push_branch: develop workflow: beta - push_branch: main workflow: release + - pull_request_source_branch: feature/* + workflow: test