From 41598dbbe05721756330d6ef056464399d85945d Mon Sep 17 00:00:00 2001 From: rory Date: Fri, 6 Sep 2024 16:38:17 -0700 Subject: [PATCH 01/20] Separate build and upload lanes for Android --- fastlane/Fastfile | 61 +++++++++++++++++++---------------------------- 1 file changed, 25 insertions(+), 36 deletions(-) diff --git a/fastlane/Fastfile b/fastlane/Fastfile index 2560e48728c5..c2ddda08d075 100644 --- a/fastlane/Fastfile +++ b/fastlane/Fastfile @@ -18,6 +18,17 @@ opt_out_usage platform :android do desc "Generate a new local APK for e2e testing" + desc "Generate a new local APK" + lane :build do + ENV["ENVFILE"]=".env.production" + gradle( + project_dir: './android', + task: 'assemble', + flavor: 'Production', + build_type: 'Release', + ) + end + lane :build_e2e do ENV["ENVFILE"]="tests/e2e/.env.e2e" ENV["ENTRY_FILE"]="src/libs/E2E/reactNativeLaunchingTest.ts" @@ -44,66 +55,45 @@ platform :android do ) end - desc "Generate a new local APK" - lane :build do - ENV["ENVFILE"]=".env.production" - + desc "Build AdHoc testing build" + lane :build_adhoc do + ENV["ENVFILE"]=".env.adhoc" gradle( project_dir: './android', task: 'assemble', - flavor: 'Production', + flavor: 'Adhoc', build_type: 'Release', ) end - desc "Build app for testing" - lane :build_internal do - ENV["ENVFILE"]=".env.adhoc" - - gradle( - project_dir: './android', - task: 'assemble', - flavor: 'Adhoc', - build_type: 'Release', - ) - + desc "Upload build to S3" + lane :upload_s3 do aws_s3( access_key: ENV['S3_ACCESS_KEY'], secret_access_key: ENV['S3_SECRET_ACCESS_KEY'], bucket: ENV['S3_BUCKET'], region: ENV['S3_REGION'], - apk: lane_context[SharedValues::GRADLE_APK_OUTPUT_PATH], app_directory: "android/#{ENV['PULL_REQUEST_NUMBER']}", ) - sh("echo '{\"apk_path\": \"#{lane_context[SharedValues::S3_APK_OUTPUT_PATH]}\",\"html_path\": \"#{lane_context[SharedValues::S3_HTML_OUTPUT_PATH]}\"}' > ../android_paths.json") end - desc "Build and upload app to Google Play" - lane :beta do - ENV["ENVFILE"]=".env.production" + desc "Upload app to Google Play for internal testing" + lane :upload_google_play_internal do # Google is very unreliable, so we retry a few times ENV["SUPPLY_UPLOAD_MAX_RETRIES"]="5" - - gradle( - project_dir: './android', - task: 'bundle', - flavor: 'Production', - build_type: 'Release', - ) - upload_to_play_store( - package_name: "com.expensify.chat", - json_key: './android/app/android-fastlane-json-key.json', - aab: './android/app/build/outputs/bundle/productionRelease/app-production-release.aab', - track: 'internal', - rollout: '1.0' + package_name: "com.expensify.chat", + json_key: './android/app/android-fastlane-json-key.json', + aab: './android/app/build/outputs/bundle/productionRelease/app-production-release.aab', + track: 'internal', + rollout: '1.0' ) end desc "Deploy app to Google Play production" - lane :production do + lane :upload_google_play_production do # Google is very unreliable, so we retry a few times ENV["SUPPLY_UPLOAD_MAX_RETRIES"]="5" google_play_track_version_codes( @@ -111,7 +101,6 @@ platform :android do json_key: './android/app/android-fastlane-json-key.json', track: 'internal' ) - upload_to_play_store( package_name: "com.expensify.chat", json_key: './android/app/android-fastlane-json-key.json', From 52f45d31c6a11e9dd2be7b4645cd03f1f8af7958 Mon Sep 17 00:00:00 2001 From: rory Date: Fri, 6 Sep 2024 16:48:20 -0700 Subject: [PATCH 02/20] Update deploy.yml android deploy job --- .github/workflows/deploy.yml | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index f2a3f96b8f67..ee6d92ccdd8e 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -99,10 +99,13 @@ jobs: - name: Set version in ENV run: echo "VERSION_CODE=$(grep -o 'versionCode\s\+[0-9]\+' android/app/build.gradle | awk '{ print $2 }')" >> "$GITHUB_ENV" - - name: Run Fastlane - run: bundle exec fastlane android ${{ fromJSON(env.SHOULD_DEPLOY_PRODUCTION) && 'production' || 'beta' }} + - name: Build Android app + if: fromJSON(env.SHOULD_DEPLOY_PRODUCTION) + run: bundle exec fastlane android build + + - name: Upload Android app to Google Play + run: bundle exec fastlane android ${{ fromJSON(env.SHOULD_DEPLOY_PRODUCTION) && 'upload_google_play_production' || 'upload_google_play_internal' }} env: - RUBYOPT: '-rostruct' MYAPP_UPLOAD_STORE_PASSWORD: ${{ secrets.MYAPP_UPLOAD_STORE_PASSWORD }} MYAPP_UPLOAD_KEY_PASSWORD: ${{ secrets.MYAPP_UPLOAD_KEY_PASSWORD }} VERSION: ${{ env.VERSION_CODE }} From 1c1937b30925631c001eac3d2358c6d7faff08f9 Mon Sep 17 00:00:00 2001 From: rory Date: Fri, 6 Sep 2024 16:56:25 -0700 Subject: [PATCH 03/20] Update testBuild.yml Android fastlane steps --- .github/workflows/deploy.yml | 5 +++-- .github/workflows/testBuild.yml | 17 +++++++++++------ 2 files changed, 14 insertions(+), 8 deletions(-) diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index ee6d92ccdd8e..cfeae9587794 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -102,12 +102,13 @@ jobs: - name: Build Android app if: fromJSON(env.SHOULD_DEPLOY_PRODUCTION) run: bundle exec fastlane android build + env: + MYAPP_UPLOAD_STORE_PASSWORD: ${{ secrets.MYAPP_UPLOAD_STORE_PASSWORD }} + MYAPP_UPLOAD_KEY_PASSWORD: ${{ secrets.MYAPP_UPLOAD_KEY_PASSWORD }} - name: Upload Android app to Google Play run: bundle exec fastlane android ${{ fromJSON(env.SHOULD_DEPLOY_PRODUCTION) && 'upload_google_play_production' || 'upload_google_play_internal' }} env: - MYAPP_UPLOAD_STORE_PASSWORD: ${{ secrets.MYAPP_UPLOAD_STORE_PASSWORD }} - MYAPP_UPLOAD_KEY_PASSWORD: ${{ secrets.MYAPP_UPLOAD_KEY_PASSWORD }} VERSION: ${{ env.VERSION_CODE }} - name: Upload Android build to Browser Stack diff --git a/.github/workflows/testBuild.yml b/.github/workflows/testBuild.yml index 21f7fcedfe85..93105d023c3f 100644 --- a/.github/workflows/testBuild.yml +++ b/.github/workflows/testBuild.yml @@ -10,6 +10,9 @@ on: types: [opened, synchronize, labeled] branches: ['*ci-test/**'] +env: + RUBYOPT: '-rostruct' + jobs: validateActor: runs-on: ubuntu-latest @@ -111,17 +114,19 @@ jobs: - name: Configure MapBox SDK run: ./scripts/setup-mapbox-sdk.sh ${{ secrets.MAPBOX_SDK_DOWNLOAD_TOKEN }} - - name: Run Fastlane beta test - id: runFastlaneBetaTest - run: bundle exec fastlane android build_internal + - name: Run AdHoc build + run: bundle exec fastlane android build_adhoc + env: + MYAPP_UPLOAD_STORE_PASSWORD: ${{ secrets.MYAPP_UPLOAD_STORE_PASSWORD }} + MYAPP_UPLOAD_KEY_PASSWORD: ${{ secrets.MYAPP_UPLOAD_KEY_PASSWORD }} + + - name: Upload AdHoc build to S3 + run: bundle exec fastlane upload_s3 env: - RUBYOPT: '-rostruct' S3_ACCESS_KEY: ${{ secrets.AWS_ACCESS_KEY_ID }} S3_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} S3_BUCKET: ad-hoc-expensify-cash S3_REGION: us-east-1 - MYAPP_UPLOAD_STORE_PASSWORD: ${{ secrets.MYAPP_UPLOAD_STORE_PASSWORD }} - MYAPP_UPLOAD_KEY_PASSWORD: ${{ secrets.MYAPP_UPLOAD_KEY_PASSWORD }} - name: Upload Artifact uses: actions/upload-artifact@v4 From aa4bb199c790009dc1450120370b882a926b6729 Mon Sep 17 00:00:00 2001 From: rory Date: Fri, 6 Sep 2024 16:58:14 -0700 Subject: [PATCH 04/20] Move -rostruct to workflow level --- .github/workflows/deploy.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index cfeae9587794..2e527c357756 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -6,6 +6,7 @@ on: env: SHOULD_DEPLOY_PRODUCTION: ${{ github.ref == 'refs/heads/production' }} + RUBYOPT: '-rostruct' concurrency: group: ${{ github.workflow }}-${{ github.ref }} From 152758a6709f82596d4e75574182f43109e7d2cf Mon Sep 17 00:00:00 2001 From: rory Date: Fri, 6 Sep 2024 16:59:56 -0700 Subject: [PATCH 05/20] Move RUBYOPT to Android job level --- .github/workflows/deploy.yml | 3 ++- .github/workflows/testBuild.yml | 4 +--- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index 2e527c357756..16d9d7dc53bd 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -6,7 +6,6 @@ on: env: SHOULD_DEPLOY_PRODUCTION: ${{ github.ref == 'refs/heads/production' }} - RUBYOPT: '-rostruct' concurrency: group: ${{ github.workflow }}-${{ github.ref }} @@ -66,6 +65,8 @@ jobs: needs: validateActor if: ${{ fromJSON(needs.validateActor.outputs.IS_DEPLOYER) }} runs-on: ubuntu-latest-xl + env: + RUBYOPT: '-rostruct' steps: - name: Checkout uses: actions/checkout@v4 diff --git a/.github/workflows/testBuild.yml b/.github/workflows/testBuild.yml index 93105d023c3f..1d523eb87e7a 100644 --- a/.github/workflows/testBuild.yml +++ b/.github/workflows/testBuild.yml @@ -10,9 +10,6 @@ on: types: [opened, synchronize, labeled] branches: ['*ci-test/**'] -env: - RUBYOPT: '-rostruct' - jobs: validateActor: runs-on: ubuntu-latest @@ -68,6 +65,7 @@ jobs: runs-on: ubuntu-latest-xl env: PULL_REQUEST_NUMBER: ${{ github.event.number || github.event.inputs.PULL_REQUEST_NUMBER }} + RUBYOPT: '-rostruct' steps: - name: Checkout uses: actions/checkout@v4 From 433c222be30aa1ab7c69195c6897e234059b4aa9 Mon Sep 17 00:00:00 2001 From: rory Date: Fri, 6 Sep 2024 17:25:41 -0700 Subject: [PATCH 06/20] DRY up code to setup iOS signing certificate --- fastlane/Fastfile | 56 +++++++++++++++++++---------------------------- 1 file changed, 22 insertions(+), 34 deletions(-) diff --git a/fastlane/Fastfile b/fastlane/Fastfile index c2ddda08d075..e979b6e3b48f 100644 --- a/fastlane/Fastfile +++ b/fastlane/Fastfile @@ -118,6 +118,26 @@ platform :android do end end +def setupIOSSigningCertificate() + require 'securerandom' + keychain_password = SecureRandom.uuid + + create_keychain( + name: "ios-build.keychain", + password: keychain_password, + default_keychain: "true", + unlock: "true", + timeout: "3600", + add_to_search_list: "true" + ) + + import_certificate( + certificate_path: "./ios/Certificates.p12", + keychain_name: "ios-build.keychain", + keychain_password: keychain_password + ) +end + platform :ios do desc "Generate a local iOS production build" lane :build do @@ -131,25 +151,9 @@ platform :ios do desc "Build app for testing" lane :build_internal do - require 'securerandom' ENV["ENVFILE"]=".env.adhoc" - keychain_password = SecureRandom.uuid - - create_keychain( - name: "ios-build.keychain", - password: keychain_password, - default_keychain: "true", - unlock: "true", - timeout: "3600", - add_to_search_list: "true" - ) - - import_certificate( - certificate_path: "./ios/Certificates.p12", - keychain_name: "ios-build.keychain", - keychain_password: keychain_password - ) + setupIOSSigningCertificate() install_provisioning_profile( path: "./ios/NewApp_AdHoc.mobileprovision" @@ -189,25 +193,9 @@ platform :ios do desc "Build and upload app to TestFlight" lane :beta do - require 'securerandom' ENV["ENVFILE"]=".env.production" - keychain_password = SecureRandom.uuid - - create_keychain( - name: "ios-build.keychain", - password: keychain_password, - default_keychain: "true", - unlock: "true", - timeout: "3600", - add_to_search_list: "true" - ) - - import_certificate( - certificate_path: "./ios/Certificates.p12", - keychain_name: "ios-build.keychain", - keychain_password: keychain_password - ) + setupIOSSigningCertificate() install_provisioning_profile( path: "./ios/NewApp_AppStore.mobileprovision" From 6bbfcdaffe6bf8e054e012e4d96bd0fc81d7c2ed Mon Sep 17 00:00:00 2001 From: rory Date: Fri, 6 Sep 2024 18:04:36 -0700 Subject: [PATCH 07/20] Separate build and upload lanes for ios --- fastlane/Fastfile | 123 +++++++++++++++++++++++----------------------- package.json | 2 +- 2 files changed, 63 insertions(+), 62 deletions(-) diff --git a/fastlane/Fastfile b/fastlane/Fastfile index e979b6e3b48f..57a82cfaf419 100644 --- a/fastlane/Fastfile +++ b/fastlane/Fastfile @@ -139,85 +139,88 @@ def setupIOSSigningCertificate() end platform :ios do - desc "Generate a local iOS production build" + desc "Build an iOS production build" lane :build do ENV["ENVFILE"]=".env.production" + setupIOSSigningCertificate() + + install_provisioning_profile( + path: "./ios/NewApp_AppStore.mobileprovision" + ) + + install_provisioning_profile( + path: "./ios/NewApp_AppStore_Notification_Service.mobileprovision" + ) + + build_app( + workspace: "./ios/NewExpensify.xcworkspace", + scheme: "New Expensify", + output_name: "New Expensify.ipa", + export_options: { + provisioningProfiles: { + "com.chat.expensify.chat" => "(NewApp) AppStore", + "com.chat.expensify.chat.NotificationServiceExtension" => "(NewApp) AppStore: Notification Service", + }, + manageAppVersionAndBuildNumber: false + } + ) + end + + desc "Build an unsigned iOS production build" + lane :build_unsigned do + ENV["ENVFILE"]=".env.production" build_app( workspace: "./ios/NewExpensify.xcworkspace", scheme: "New Expensify" ) end - desc "Build app for testing" - lane :build_internal do + desc "Build AdHoc app for testing" + lane :build_adhoc do ENV["ENVFILE"]=".env.adhoc" setupIOSSigningCertificate() install_provisioning_profile( - path: "./ios/NewApp_AdHoc.mobileprovision" + path: "./ios/NewApp_AdHoc.mobileprovision" ) install_provisioning_profile( - path: "./ios/NewApp_AdHoc_Notification_Service.mobileprovision" + path: "./ios/NewApp_AdHoc_Notification_Service.mobileprovision" ) build_app( - workspace: "./ios/NewExpensify.xcworkspace", - skip_profile_detection: true, - scheme: "New Expensify AdHoc", - export_method: "ad-hoc", - export_options: { - method: "ad-hoc", - provisioningProfiles: { - "com.expensify.chat.adhoc" => "(NewApp) AdHoc", - "com.expensify.chat.adhoc.NotificationServiceExtension" => "(NewApp) AdHoc: Notification Service", - }, - manageAppVersionAndBuildNumber: false - } + workspace: "./ios/NewExpensify.xcworkspace", + skip_profile_detection: true, + scheme: "New Expensify AdHoc", + export_method: "ad-hoc", + export_options: { + method: "ad-hoc", + provisioningProfiles: { + "com.expensify.chat.adhoc" => "(NewApp) AdHoc", + "com.expensify.chat.adhoc.NotificationServiceExtension" => "(NewApp) AdHoc: Notification Service", + }, + manageAppVersionAndBuildNumber: false + } ) + end + desc "Upload app to S3" + lane :upload_s3 do aws_s3( access_key: ENV['S3_ACCESS_KEY'], secret_access_key: ENV['S3_SECRET_ACCESS_KEY'], bucket: ENV['S3_BUCKET'], region: ENV['S3_REGION'], - ipa: lane_context[SharedValues::IPA_OUTPUT_PATH], app_directory: "ios/#{ENV['PULL_REQUEST_NUMBER']}", ) - sh("echo '{\"ipa_path\": \"#{lane_context[SharedValues::S3_IPA_OUTPUT_PATH]}\",\"html_path\": \"#{lane_context[SharedValues::S3_HTML_OUTPUT_PATH]}\"}' > ../ios_paths.json") end - desc "Build and upload app to TestFlight" - lane :beta do - ENV["ENVFILE"]=".env.production" - - setupIOSSigningCertificate() - - install_provisioning_profile( - path: "./ios/NewApp_AppStore.mobileprovision" - ) - - install_provisioning_profile( - path: "./ios/NewApp_AppStore_Notification_Service.mobileprovision" - ) - - build_app( - workspace: "./ios/NewExpensify.xcworkspace", - scheme: "New Expensify", - output_name: "New Expensify.ipa", - export_options: { - provisioningProfiles: { - "com.chat.expensify.chat" => "(NewApp) AppStore", - "com.chat.expensify.chat.NotificationServiceExtension" => "(NewApp) AppStore: Notification Service", - }, - manageAppVersionAndBuildNumber: false - } - ) - + desc "Upload app to TestFlight" + lane :upload_testflight do upload_to_testflight( api_key_path: "./ios/ios-fastlane-json-key.json", distribute_external: true, @@ -226,17 +229,17 @@ platform :ios do groups: ["Beta"], demo_account_required: true, beta_app_review_info: { - contact_email: ENV["APPLE_CONTACT_EMAIL"], - contact_first_name: "Andrew", - contact_last_name: "Gable", - contact_phone: ENV["APPLE_CONTACT_PHONE"], - demo_account_name: ENV["APPLE_DEMO_EMAIL"], - demo_account_password: ENV["APPLE_DEMO_PASSWORD"], - notes: "1. In the Expensify app, enter the email 'appletest.expensify@proton.me'. This will trigger a sign-in link to be sent to 'appletest.expensify@proton.me' - 2. Navigate to https://account.proton.me/login, log into Proton Mail using 'appletest.expensify@proton.me' as email and the password associated with 'appletest.expensify@proton.me', provided above - 3. Once logged into Proton Mail, navigate to your inbox and locate the email triggered in step 1. The email subject should be 'Your magic sign-in link for Expensify' - 4. Open the email and copy the 6-digit sign-in code provided within - 5. Return to the Expensify app and enter the copied 6-digit code in the designated login field" + contact_email: ENV["APPLE_CONTACT_EMAIL"], + contact_first_name: "Andrew", + contact_last_name: "Gable", + contact_phone: ENV["APPLE_CONTACT_PHONE"], + demo_account_name: ENV["APPLE_DEMO_EMAIL"], + demo_account_password: ENV["APPLE_DEMO_PASSWORD"], + notes: "1. In the Expensify app, enter the email 'appletest.expensify@proton.me'. This will trigger a sign-in link to be sent to 'appletest.expensify@proton.me' + 2. Navigate to https://account.proton.me/login, log into Proton Mail using 'appletest.expensify@proton.me' as email and the password associated with 'appletest.expensify@proton.me', provided above + 3. Once logged into Proton Mail, navigate to your inbox and locate the email triggered in step 1. The email subject should be 'Your magic sign-in link for Expensify' + 4. Open the email and copy the 6-digit sign-in code provided within + 5. Return to the Expensify app and enter the copied 6-digit code in the designated login field" } ) @@ -248,8 +251,8 @@ platform :ios do ) end - desc "Move app to App Store Review" - lane :production do + desc "Submit app to App Store Review" + lane :submit_for_review do deliver( api_key_path: "./ios/ios-fastlane-json-key.json", @@ -286,7 +289,6 @@ platform :ios do # Precheck cannot check for in app purchases with the API key we use precheck_include_in_app_purchases: false, submission_information: { - # We currently do not use idfa: https://developer.apple.com/app-store/user-privacy-and-data-use/ add_id_info_uses_idfa: false, @@ -311,6 +313,5 @@ platform :ios do 'en-US' => "Improvements and bug fixes" } ) - end end diff --git a/package.json b/package.json index f9c5dd28a7f7..7e834c15d41c 100644 --- a/package.json +++ b/package.json @@ -30,7 +30,7 @@ "createDocsRoutes": "ts-node .github/scripts/createDocsRoutes.ts", "detectRedirectCycle": "ts-node .github/scripts/detectRedirectCycle.ts", "desktop-build-adhoc": "scripts/build-desktop.sh adhoc", - "ios-build": "fastlane ios build", + "ios-build": "fastlane ios build_unsigned", "android-build": "fastlane android build", "android-build-e2e": "bundle exec fastlane android build_e2e", "android-build-e2edelta": "bundle exec fastlane android build_e2edelta", From c120b75ed101b81829bb74f707339a1a3e3b3a54 Mon Sep 17 00:00:00 2001 From: rory Date: Fri, 6 Sep 2024 18:10:51 -0700 Subject: [PATCH 08/20] Update ios fastlane usage in deploy.yml --- .github/workflows/deploy.yml | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index 16d9d7dc53bd..e87732328ad4 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -102,7 +102,7 @@ jobs: run: echo "VERSION_CODE=$(grep -o 'versionCode\s\+[0-9]\+' android/app/build.gradle | awk '{ print $2 }')" >> "$GITHUB_ENV" - name: Build Android app - if: fromJSON(env.SHOULD_DEPLOY_PRODUCTION) + if: ${{ !fromJSON(env.SHOULD_DEPLOY_PRODUCTION) }} run: bundle exec fastlane android build env: MYAPP_UPLOAD_STORE_PASSWORD: ${{ secrets.MYAPP_UPLOAD_STORE_PASSWORD }} @@ -269,13 +269,23 @@ jobs: - name: Set iOS version in ENV run: echo "IOS_VERSION=$(echo '${{ env.VERSION }}' | tr '-' '.')" >> "$GITHUB_ENV" - - name: Run Fastlane - run: bundle exec fastlane ios ${{ fromJSON(env.SHOULD_DEPLOY_PRODUCTION) && 'production' || 'beta' }} + - name: Build iOS release app + if: ${{ !fromJSON(env.SHOULD_DEPLOY_PRODUCTION) }} + run: bundle exec fastlane ios build + + - name: Upload release build to TestFlight + if: ${{ !fromJSON(env.SHOULD_DEPLOY_PRODUCTION) }} + run: bundle exec fastlane ios upload_testflight env: APPLE_CONTACT_EMAIL: ${{ secrets.APPLE_CONTACT_EMAIL }} APPLE_CONTACT_PHONE: ${{ secrets.APPLE_CONTACT_PHONE }} APPLE_DEMO_EMAIL: ${{ secrets.APPLE_DEMO_EMAIL }} APPLE_DEMO_PASSWORD: ${{ secrets.APPLE_DEMO_PASSWORD }} + + - name: Run Fastlane + if: ${{ fromJSON(env.SHOULD_DEPLOY_PRODUCTION) }} + run: bundle exec fastlane ios submit_for_review + env: VERSION: ${{ env.IOS_VERSION }} - name: Upload iOS build to Browser Stack From 3826d71190138a4e5229018ad953ec34300f096b Mon Sep 17 00:00:00 2001 From: rory Date: Fri, 6 Sep 2024 18:13:06 -0700 Subject: [PATCH 09/20] Update ios fastlane usage in testBuild.yml --- .github/workflows/testBuild.yml | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/.github/workflows/testBuild.yml b/.github/workflows/testBuild.yml index 1d523eb87e7a..4cffd912c3ac 100644 --- a/.github/workflows/testBuild.yml +++ b/.github/workflows/testBuild.yml @@ -208,8 +208,11 @@ jobs: aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} aws-region: us-east-1 - - name: Run Fastlane - run: bundle exec fastlane ios build_internal + - name: Build AdHoc app + run: bundle exec fastlane ios build_adhoc + + - name: Upload AdHoc build to S3 + run: bundle exec fastlane ios upload_s3 env: S3_ACCESS_KEY: ${{ secrets.AWS_ACCESS_KEY_ID }} S3_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} From 3aab0df28ca8ddf7d9d1cdfb2ea6fbfe412823b7 Mon Sep 17 00:00:00 2001 From: rory Date: Fri, 6 Sep 2024 18:16:27 -0700 Subject: [PATCH 10/20] Move PULL_REQUEST_NUMBER environment variable to workflow level --- .github/workflows/testBuild.yml | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/.github/workflows/testBuild.yml b/.github/workflows/testBuild.yml index 4cffd912c3ac..0d403c92102f 100644 --- a/.github/workflows/testBuild.yml +++ b/.github/workflows/testBuild.yml @@ -10,6 +10,9 @@ on: types: [opened, synchronize, labeled] branches: ['*ci-test/**'] +env: + PULL_REQUEST_NUMBER: ${{ github.event.number || github.event.inputs.PULL_REQUEST_NUMBER }} + jobs: validateActor: runs-on: ubuntu-latest @@ -35,7 +38,6 @@ jobs: echo "The 'Ready to Build' label is not attached to the PR #${{ env.PULL_REQUEST_NUMBER }}" fi env: - PULL_REQUEST_NUMBER: ${{ github.event.number || github.event.inputs.PULL_REQUEST_NUMBER }} GITHUB_TOKEN: ${{ github.token }} getBranchRef: @@ -64,7 +66,6 @@ jobs: if: ${{ fromJSON(needs.validateActor.outputs.READY_TO_BUILD) }} runs-on: ubuntu-latest-xl env: - PULL_REQUEST_NUMBER: ${{ github.event.number || github.event.inputs.PULL_REQUEST_NUMBER }} RUBYOPT: '-rostruct' steps: - name: Checkout @@ -137,7 +138,6 @@ jobs: needs: [validateActor, getBranchRef] if: ${{ fromJSON(needs.validateActor.outputs.READY_TO_BUILD) }} env: - PULL_REQUEST_NUMBER: ${{ github.event.number || github.event.inputs.PULL_REQUEST_NUMBER }} DEVELOPER_DIR: /Applications/Xcode_15.2.0.app/Contents/Developer runs-on: macos-13-xlarge steps: @@ -229,8 +229,6 @@ jobs: name: Build and deploy Desktop for testing needs: [validateActor, getBranchRef] if: ${{ fromJSON(needs.validateActor.outputs.READY_TO_BUILD) }} - env: - PULL_REQUEST_NUMBER: ${{ github.event.number || github.event.inputs.PULL_REQUEST_NUMBER }} runs-on: macos-14-large steps: - name: Checkout @@ -274,8 +272,6 @@ jobs: name: Build and deploy Web needs: [validateActor, getBranchRef] if: ${{ fromJSON(needs.validateActor.outputs.READY_TO_BUILD) }} - env: - PULL_REQUEST_NUMBER: ${{ github.event.number || github.event.inputs.PULL_REQUEST_NUMBER }} runs-on: ubuntu-latest-xl steps: - name: Checkout @@ -310,8 +306,6 @@ jobs: name: Post a GitHub comment with app download links for testing needs: [validateActor, getBranchRef, android, iOS, desktop, web] if: ${{ always() }} - env: - PULL_REQUEST_NUMBER: ${{ github.event.number || github.event.inputs.PULL_REQUEST_NUMBER }} steps: - name: Checkout uses: actions/checkout@v4 From a4d3daa91d91410ae8c87bf9713a2976d044c324 Mon Sep 17 00:00:00 2001 From: rory Date: Fri, 6 Sep 2024 18:23:44 -0700 Subject: [PATCH 11/20] Put gradle apk output path in env --- fastlane/Fastfile | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/fastlane/Fastfile b/fastlane/Fastfile index 57a82cfaf419..c21be8f283f6 100644 --- a/fastlane/Fastfile +++ b/fastlane/Fastfile @@ -15,6 +15,12 @@ require 'ostruct' skip_docs opt_out_usage +KEY_GRADLE_APK_OUTPUT_PATH = "gradleAPKOutputPath" + +def setGradleAPKPathInEnv() + ENV[KEY_GRADLE_APK_OUTPUT_PATH] = lane_context[SharedValues::GRADLE_APK_OUTPUT_PATH] +end + platform :android do desc "Generate a new local APK for e2e testing" @@ -27,6 +33,7 @@ platform :android do flavor: 'Production', build_type: 'Release', ) + setGradleAPKPathInEnv() end lane :build_e2e do @@ -40,6 +47,7 @@ platform :android do flavor: 'e2e', build_type: 'Release', ) + setGradleAPKPathInEnv() end lane :build_e2edelta do @@ -53,6 +61,7 @@ platform :android do flavor: 'e2edelta', build_type: 'Release', ) + setGradleAPKPathInEnv() end desc "Build AdHoc testing build" @@ -64,6 +73,7 @@ platform :android do flavor: 'Adhoc', build_type: 'Release', ) + setGradleAPKPathInEnv() end desc "Upload build to S3" @@ -73,7 +83,7 @@ platform :android do secret_access_key: ENV['S3_SECRET_ACCESS_KEY'], bucket: ENV['S3_BUCKET'], region: ENV['S3_REGION'], - apk: lane_context[SharedValues::GRADLE_APK_OUTPUT_PATH], + apk: ENV[KEY_GRADLE_APK_OUTPUT_PATH], app_directory: "android/#{ENV['PULL_REQUEST_NUMBER']}", ) sh("echo '{\"apk_path\": \"#{lane_context[SharedValues::S3_APK_OUTPUT_PATH]}\",\"html_path\": \"#{lane_context[SharedValues::S3_HTML_OUTPUT_PATH]}\"}' > ../android_paths.json") From 51874d5c79cbe6232821fbf9265271b92616ab7e Mon Sep 17 00:00:00 2001 From: rory Date: Fri, 6 Sep 2024 18:30:56 -0700 Subject: [PATCH 12/20] Communicate across lanes with environment variables --- fastlane/Fastfile | 31 +++++++++++++++++++++---------- 1 file changed, 21 insertions(+), 10 deletions(-) diff --git a/fastlane/Fastfile b/fastlane/Fastfile index c21be8f283f6..3fe1e70a09d6 100644 --- a/fastlane/Fastfile +++ b/fastlane/Fastfile @@ -15,10 +15,17 @@ require 'ostruct' skip_docs opt_out_usage -KEY_GRADLE_APK_OUTPUT_PATH = "gradleAPKOutputPath" +KEY_GRADLE_APK_PATH = "gradleAPKOutputPath" +KEY_IPA_PATH = "ipaPath" +KEY_DSYM_PATH = "dsymPath" -def setGradleAPKPathInEnv() - ENV[KEY_GRADLE_APK_OUTPUT_PATH] = lane_context[SharedValues::GRADLE_APK_OUTPUT_PATH] +def setGradleOutputsInEnv() + ENV[KEY_GRADLE_APK_PATH] = lane_context[SharedValues::GRADLE_APK_OUTPUT_PATH] +end + +def setIOSBuildOutputsInEnv() + ENV[KEY_IPA_PATH] = lane_context[SharedValues::IPA_OUTPUT_PATH] + ENV[KEY_DSYM_PATH] = lane_context[SharedValues::DSYM_OUTPUT_PATH] end platform :android do @@ -33,7 +40,7 @@ platform :android do flavor: 'Production', build_type: 'Release', ) - setGradleAPKPathInEnv() + setGradleOutputsInEnv() end lane :build_e2e do @@ -47,7 +54,7 @@ platform :android do flavor: 'e2e', build_type: 'Release', ) - setGradleAPKPathInEnv() + setGradleOutputsInEnv() end lane :build_e2edelta do @@ -61,7 +68,7 @@ platform :android do flavor: 'e2edelta', build_type: 'Release', ) - setGradleAPKPathInEnv() + setGradleOutputsInEnv() end desc "Build AdHoc testing build" @@ -73,7 +80,7 @@ platform :android do flavor: 'Adhoc', build_type: 'Release', ) - setGradleAPKPathInEnv() + setGradleOutputsInEnv() end desc "Upload build to S3" @@ -83,7 +90,7 @@ platform :android do secret_access_key: ENV['S3_SECRET_ACCESS_KEY'], bucket: ENV['S3_BUCKET'], region: ENV['S3_REGION'], - apk: ENV[KEY_GRADLE_APK_OUTPUT_PATH], + apk: ENV[KEY_GRADLE_APK_PATH], app_directory: "android/#{ENV['PULL_REQUEST_NUMBER']}", ) sh("echo '{\"apk_path\": \"#{lane_context[SharedValues::S3_APK_OUTPUT_PATH]}\",\"html_path\": \"#{lane_context[SharedValues::S3_HTML_OUTPUT_PATH]}\"}' > ../android_paths.json") @@ -175,6 +182,8 @@ platform :ios do manageAppVersionAndBuildNumber: false } ) + + setIOSBuildOutputsInEnv() end desc "Build an unsigned iOS production build" @@ -184,6 +193,7 @@ platform :ios do workspace: "./ios/NewExpensify.xcworkspace", scheme: "New Expensify" ) + setIOSBuildOutputsInEnv() end desc "Build AdHoc app for testing" @@ -214,6 +224,7 @@ platform :ios do manageAppVersionAndBuildNumber: false } ) + setIOSBuildOutputsInEnv() end desc "Upload app to S3" @@ -223,7 +234,7 @@ platform :ios do secret_access_key: ENV['S3_SECRET_ACCESS_KEY'], bucket: ENV['S3_BUCKET'], region: ENV['S3_REGION'], - ipa: lane_context[SharedValues::IPA_OUTPUT_PATH], + ipa: ENV[KEY_IPA_PATH], app_directory: "ios/#{ENV['PULL_REQUEST_NUMBER']}", ) sh("echo '{\"ipa_path\": \"#{lane_context[SharedValues::S3_IPA_OUTPUT_PATH]}\",\"html_path\": \"#{lane_context[SharedValues::S3_HTML_OUTPUT_PATH]}\"}' > ../ios_paths.json") @@ -255,7 +266,7 @@ platform :ios do upload_symbols_to_crashlytics( app_id: "1:921154746561:ios:216bd10ccc947659027c40", - dsym_path: lane_context[SharedValues::DSYM_OUTPUT_PATH], + dsym_path: ENV[KEY_DSYM_PATH], gsp_path: "./ios/GoogleService-Info.plist", binary_path: "./ios/Pods/FirebaseCrashlytics/upload-symbols" ) From 0026ff1198c7b14e86d8aa5dbb21ea11716bc7ed Mon Sep 17 00:00:00 2001 From: rory Date: Fri, 6 Sep 2024 18:33:07 -0700 Subject: [PATCH 13/20] Rename step from Run Fastlane --- .github/workflows/deploy.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index e87732328ad4..3d1dd534a4d0 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -282,7 +282,7 @@ jobs: APPLE_DEMO_EMAIL: ${{ secrets.APPLE_DEMO_EMAIL }} APPLE_DEMO_PASSWORD: ${{ secrets.APPLE_DEMO_PASSWORD }} - - name: Run Fastlane + - name: Submit build for App Store review if: ${{ fromJSON(env.SHOULD_DEPLOY_PRODUCTION) }} run: bundle exec fastlane ios submit_for_review env: From 5a7fee7e2519f4411e284f97b4c6a6f5f5079308 Mon Sep 17 00:00:00 2001 From: rory Date: Fri, 6 Sep 2024 21:21:13 -0700 Subject: [PATCH 14/20] Include platform in android s3 upload --- .github/workflows/testBuild.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/testBuild.yml b/.github/workflows/testBuild.yml index 0d403c92102f..f523faf785c0 100644 --- a/.github/workflows/testBuild.yml +++ b/.github/workflows/testBuild.yml @@ -120,7 +120,7 @@ jobs: MYAPP_UPLOAD_KEY_PASSWORD: ${{ secrets.MYAPP_UPLOAD_KEY_PASSWORD }} - name: Upload AdHoc build to S3 - run: bundle exec fastlane upload_s3 + run: bundle exec fastlane android upload_s3 env: S3_ACCESS_KEY: ${{ secrets.AWS_ACCESS_KEY_ID }} S3_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} From 54cc2fee43c2f9617b54116bce56bd4b821d33e7 Mon Sep 17 00:00:00 2001 From: rory Date: Fri, 6 Sep 2024 21:25:48 -0700 Subject: [PATCH 15/20] Add logs in setOutputsInEnv utilities --- fastlane/Fastfile | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/fastlane/Fastfile b/fastlane/Fastfile index 3fe1e70a09d6..cf2827a01f03 100644 --- a/fastlane/Fastfile +++ b/fastlane/Fastfile @@ -20,11 +20,16 @@ KEY_IPA_PATH = "ipaPath" KEY_DSYM_PATH = "dsymPath" def setGradleOutputsInEnv() + puts "Saving Android build outputs in env..." + puts "#{KEY_GRADLE_APK_PATH}=#{lane_context[SharedValues::GRADLE_APK_OUTPUT_PATH]}" ENV[KEY_GRADLE_APK_PATH] = lane_context[SharedValues::GRADLE_APK_OUTPUT_PATH] end def setIOSBuildOutputsInEnv() + puts "Saving iOS build outputs in env..." + puts "#{KEY_IPA_PATH}=#{lane_context[SharedValues::IPA_OUTPUT_PATH]}" ENV[KEY_IPA_PATH] = lane_context[SharedValues::IPA_OUTPUT_PATH] + puts "#{KEY_DSYM_PATH}=#{lane_context[SharedValues::DSYM_OUTPUT_PATH]}" ENV[KEY_DSYM_PATH] = lane_context[SharedValues::DSYM_OUTPUT_PATH] end From 124a8aefec3c7ac56040b30474e24dc2f468736a Mon Sep 17 00:00:00 2001 From: rory Date: Fri, 6 Sep 2024 21:32:11 -0700 Subject: [PATCH 16/20] Add logs when reading custom env vars --- fastlane/Fastfile | 3 +++ 1 file changed, 3 insertions(+) diff --git a/fastlane/Fastfile b/fastlane/Fastfile index cf2827a01f03..2134bc9d3a76 100644 --- a/fastlane/Fastfile +++ b/fastlane/Fastfile @@ -90,6 +90,7 @@ platform :android do desc "Upload build to S3" lane :upload_s3 do + puts "APK path: #{ENV[KEY_GRADLE_APK_PATH]}" aws_s3( access_key: ENV['S3_ACCESS_KEY'], secret_access_key: ENV['S3_SECRET_ACCESS_KEY'], @@ -234,6 +235,7 @@ platform :ios do desc "Upload app to S3" lane :upload_s3 do + puts "IPA path: #{ENV[KEY_IPA_PATH]}" aws_s3( access_key: ENV['S3_ACCESS_KEY'], secret_access_key: ENV['S3_SECRET_ACCESS_KEY'], @@ -269,6 +271,7 @@ platform :ios do } ) + puts "dsym path: #{ENV[KEY_DSYM_PATH]}" upload_symbols_to_crashlytics( app_id: "1:921154746561:ios:216bd10ccc947659027c40", dsym_path: ENV[KEY_DSYM_PATH], From 7a56429a50d33cad693fcc976eeb7774a1afacd0 Mon Sep 17 00:00:00 2001 From: rory Date: Fri, 6 Sep 2024 22:19:32 -0700 Subject: [PATCH 17/20] Move description to the right place --- fastlane/Fastfile | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/fastlane/Fastfile b/fastlane/Fastfile index 2134bc9d3a76..cd249294f298 100644 --- a/fastlane/Fastfile +++ b/fastlane/Fastfile @@ -34,8 +34,6 @@ def setIOSBuildOutputsInEnv() end platform :android do - desc "Generate a new local APK for e2e testing" - desc "Generate a new local APK" lane :build do ENV["ENVFILE"]=".env.production" @@ -48,6 +46,7 @@ platform :android do setGradleOutputsInEnv() end + desc "Generate a new local APK for e2e testing" lane :build_e2e do ENV["ENVFILE"]="tests/e2e/.env.e2e" ENV["ENTRY_FILE"]="src/libs/E2E/reactNativeLaunchingTest.ts" From 47316253ed0f4723481f42ebb306cb73e25f806b Mon Sep 17 00:00:00 2001 From: rory Date: Fri, 6 Sep 2024 22:42:22 -0700 Subject: [PATCH 18/20] Create and use setEnvVarsInParentShell utility function --- fastlane/Fastfile | 36 ++++++++++++++++++++++++++++++------ 1 file changed, 30 insertions(+), 6 deletions(-) diff --git a/fastlane/Fastfile b/fastlane/Fastfile index cd249294f298..6a7e54997f31 100644 --- a/fastlane/Fastfile +++ b/fastlane/Fastfile @@ -19,18 +19,42 @@ KEY_GRADLE_APK_PATH = "gradleAPKOutputPath" KEY_IPA_PATH = "ipaPath" KEY_DSYM_PATH = "dsymPath" +# This is a utility function to setting environment variables in the parent shell. +# In a GitHub Actions environment, it will save the environment variables in the GITHUB_ENV file. +# In any other environment, it will save them to the current shell environment using the `export` command. +def setEnvVarsInParentShell(env_vars) + github_env_path = ENV['GITHUB_ENV'] + if github_env_path && File.exist?(github_env_path) + puts "Saving environment variables in GITHUB_ENV..." + File.open(github_env_path, "a") do |file| + env_vars.each do |key, value| + puts "#{key}=#{value}" + file.puts "#{key}=#{value}" + end + end + else + puts "Saving environment variables in parent shell..." + env_vars.each do |key, value| + puts "#{key}=#{value}" + command = "export #{key}=#{value}" + system(command) + end + end +end + def setGradleOutputsInEnv() puts "Saving Android build outputs in env..." - puts "#{KEY_GRADLE_APK_PATH}=#{lane_context[SharedValues::GRADLE_APK_OUTPUT_PATH]}" - ENV[KEY_GRADLE_APK_PATH] = lane_context[SharedValues::GRADLE_APK_OUTPUT_PATH] + setEnvVarsInParentShell({ + KEY_GRADLE_APK_PATH => lane_context[SharedValues::GRADLE_APK_OUTPUT_PATH], + }) end def setIOSBuildOutputsInEnv() puts "Saving iOS build outputs in env..." - puts "#{KEY_IPA_PATH}=#{lane_context[SharedValues::IPA_OUTPUT_PATH]}" - ENV[KEY_IPA_PATH] = lane_context[SharedValues::IPA_OUTPUT_PATH] - puts "#{KEY_DSYM_PATH}=#{lane_context[SharedValues::DSYM_OUTPUT_PATH]}" - ENV[KEY_DSYM_PATH] = lane_context[SharedValues::DSYM_OUTPUT_PATH] + setEnvVarsInParentShell({ + KEY_IPA_PATH => lane_context[SharedValues::IPA_OUTPUT_PATH], + KEY_DSYM_PATH => lane_context[SharedValues::DSYM_OUTPUT_PATH], + }) end platform :android do From dc653fe62f262801cd81f703af24140f525c1ddd Mon Sep 17 00:00:00 2001 From: rory Date: Fri, 6 Sep 2024 22:44:11 -0700 Subject: [PATCH 19/20] Rename to simply exportEnvVars --- fastlane/Fastfile | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/fastlane/Fastfile b/fastlane/Fastfile index 6a7e54997f31..4a7e8d85b95f 100644 --- a/fastlane/Fastfile +++ b/fastlane/Fastfile @@ -22,7 +22,7 @@ KEY_DSYM_PATH = "dsymPath" # This is a utility function to setting environment variables in the parent shell. # In a GitHub Actions environment, it will save the environment variables in the GITHUB_ENV file. # In any other environment, it will save them to the current shell environment using the `export` command. -def setEnvVarsInParentShell(env_vars) +def exportEnvVars(env_vars) github_env_path = ENV['GITHUB_ENV'] if github_env_path && File.exist?(github_env_path) puts "Saving environment variables in GITHUB_ENV..." @@ -44,14 +44,14 @@ end def setGradleOutputsInEnv() puts "Saving Android build outputs in env..." - setEnvVarsInParentShell({ + exportEnvVars({ KEY_GRADLE_APK_PATH => lane_context[SharedValues::GRADLE_APK_OUTPUT_PATH], }) end def setIOSBuildOutputsInEnv() puts "Saving iOS build outputs in env..." - setEnvVarsInParentShell({ + exportEnvVars({ KEY_IPA_PATH => lane_context[SharedValues::IPA_OUTPUT_PATH], KEY_DSYM_PATH => lane_context[SharedValues::DSYM_OUTPUT_PATH], }) From d3a130d4cc77275767fcf9e6f14d8b48eef81618 Mon Sep 17 00:00:00 2001 From: rory Date: Fri, 6 Sep 2024 22:46:26 -0700 Subject: [PATCH 20/20] Improve comment --- fastlane/Fastfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fastlane/Fastfile b/fastlane/Fastfile index 4a7e8d85b95f..66c5000a6ea3 100644 --- a/fastlane/Fastfile +++ b/fastlane/Fastfile @@ -19,7 +19,7 @@ KEY_GRADLE_APK_PATH = "gradleAPKOutputPath" KEY_IPA_PATH = "ipaPath" KEY_DSYM_PATH = "dsymPath" -# This is a utility function to setting environment variables in the parent shell. +# Export environment variables in the parent shell. # In a GitHub Actions environment, it will save the environment variables in the GITHUB_ENV file. # In any other environment, it will save them to the current shell environment using the `export` command. def exportEnvVars(env_vars)