diff --git a/.github/workflows/buildAdHoc.yml b/.github/workflows/buildAdHoc.yml index 83a8da1a47ee..70d77851b7ca 100644 --- a/.github/workflows/buildAdHoc.yml +++ b/.github/workflows/buildAdHoc.yml @@ -94,6 +94,7 @@ jobs: mobile-expensify-ref: ${{ inputs.MOBILE_EXPENSIFY_REF }} pull-request-number: ${{ inputs.APP_PR_NUMBER }} force-native-build: ${{ inputs.FORCE_NATIVE_BUILD }} + download-dsyms: 'true' secrets: inherit buildWeb: diff --git a/.github/workflows/buildIOS.yml b/.github/workflows/buildIOS.yml index ddf63a534f62..501dce8bb18d 100644 --- a/.github/workflows/buildIOS.yml +++ b/.github/workflows/buildIOS.yml @@ -27,6 +27,10 @@ on: description: Force a full native build, bypassing Rock remote cache type: string default: 'false' + download-dsyms: + description: Download the prebuilt react-native dSYMs so Sentry can symbolicate its native frames. Off by default - it adds two large downloads per build. + type: string + default: 'false' outputs: IOS_VERSION: @@ -51,6 +55,7 @@ jobs: runs-on: blacksmith-12vcpu-macos-latest env: PULL_REQUEST_NUMBER: ${{ inputs.pull-request-number }} + RCT_SYMBOLICATE_PREBUILT_FRAMEWORKS: ${{ inputs.download-dsyms == 'true' && '1' || '0' }} outputs: IOS_VERSION: ${{ steps.getIOSVersion.outputs.IOS_VERSION }} ROCK_ARTIFACT_URL: ${{ steps.set-artifact-url.outputs.ARTIFACT_URL }} @@ -112,6 +117,19 @@ jobs: - name: Install New Expensify Gems run: bundle install + - name: Resolve react-native artifact version + id: resolve-rn-artifacts + run: | + VERSION=$(bun scripts/artifacts-utils/resolve-artifacts.ts --platform=ios --hybrid=true --new-dot-root="$GITHUB_WORKSPACE" | jq -r '.version // "source"') + echo "VERSION=$VERSION" >> "$GITHUB_OUTPUT" + + - name: Cache react-native artifacts + # v5.0.1 + uses: actions/cache@9255dc7a253b0ccc959486e2bca901246202afeb + with: + path: ~/Library/Caches/Expensify/react-native-artifacts + key: ${{ runner.os }}-rn-artifacts-react-hybrid-${{ steps.resolve-rn-artifacts.outputs.VERSION }} + - name: Cache Pod dependencies # v5.0.1 uses: actions/cache@9255dc7a253b0ccc959486e2bca901246202afeb diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index efcd1a9cbd62..c1b8dfd80147 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -434,6 +434,7 @@ jobs: with: ref: ${{ needs.prep.outputs.DEPLOY_SHA }} variant: Release + download-dsyms: 'true' secrets: inherit iosUploadTestflight: diff --git a/scripts/artifacts-utils/android/ExpensiUtils.gradle b/scripts/artifacts-utils/android/ExpensiUtils.gradle index b76b617d16d2..11180e6d7750 100644 --- a/scripts/artifacts-utils/android/ExpensiUtils.gradle +++ b/scripts/artifacts-utils/android/ExpensiUtils.gradle @@ -27,10 +27,10 @@ ext.ExpensiUtils = new Object() { } // Returns [buildFromSource, version, githubUsername, githubToken]; any failure -> build from source. - Map resolveArtifacts(String packageName, String newDotRootDir, boolean isHybrid) { + Map resolveArtifacts(String newDotRootDir, boolean isHybrid) { def cmd = [ "bun", "${newDotRootDir}/scripts/artifacts-utils/resolve-artifacts.ts", - "--platform=android", "--package=${packageName}", "--hybrid=${isHybrid}", "--new-dot-root=${newDotRootDir}" + "--platform=android", "--hybrid=${isHybrid}", "--new-dot-root=${newDotRootDir}" ] try { def result = runCommand(cmd, 120, new File(newDotRootDir)) diff --git a/scripts/artifacts-utils/android/PatchedArtifactsSettings.gradle b/scripts/artifacts-utils/android/PatchedArtifactsSettings.gradle index 5654e57838d6..0c7987888858 100644 --- a/scripts/artifacts-utils/android/PatchedArtifactsSettings.gradle +++ b/scripts/artifacts-utils/android/PatchedArtifactsSettings.gradle @@ -25,7 +25,7 @@ settings.extensions.configure(PatchedArtifactsConfig) { config -> config.packageName = getProperty('patchedArtifacts.packageName') def isHybrid = config.packageName == 'react-hybrid' - def resolution = ExpensiUtils.resolveArtifacts(config.packageName, getNewDotRootDir().toString(), isHybrid) + def resolution = ExpensiUtils.resolveArtifacts(getNewDotRootDir().toString(), isHybrid) config.version = resolution.version config.buildFromSource = resolution.buildFromSource diff --git a/scripts/artifacts-utils/ios/patched_ios_artifacts.rb b/scripts/artifacts-utils/ios/patched_ios_artifacts.rb index d2ec5a6bae80..47bf64038836 100644 --- a/scripts/artifacts-utils/ios/patched_ios_artifacts.rb +++ b/scripts/artifacts-utils/ios/patched_ios_artifacts.rb @@ -29,12 +29,11 @@ def self.log(message, level = :info) def self.setup is_hybrid = ENV['IS_HYBRID_APP'] == 'true' - package_name = is_hybrid ? 'react-hybrid' : 'react-standalone' # Manual escape hatch: force a full from-source build (e.g. to unblock a prebuild issue). build_from_source = ENV['BUILD_RN_FROM_SOURCE'] == '1' # The escape hatch short-circuits before anything touches the network: no resolver, no prefetch. - resolution = build_from_source ? {'buildFromSource' => true, 'version' => nil} : prefetch(resolve(package_name, is_hybrid)) + resolution = build_from_source ? {'buildFromSource' => true, 'version' => nil} : prefetch(resolve(is_hybrid)) # A single decision drives both prebuilt flags, so we never land in a mixed # prebuilt-deps / source-core state (which desyncs the CocoaPods sandbox). @@ -181,10 +180,10 @@ def self.download_and_verify(url, destination, github_token) destination end - def self.resolve(package_name, is_hybrid) + def self.resolve(is_hybrid) cmd = [ 'bun', File.join(NEW_DOT_ROOT, 'scripts/artifacts-utils/resolve-artifacts.ts'), - '--platform=ios', "--package=#{package_name}", "--hybrid=#{is_hybrid}", "--new-dot-root=#{NEW_DOT_ROOT}" + '--platform=ios', "--hybrid=#{is_hybrid}", "--new-dot-root=#{NEW_DOT_ROOT}" ] # stdout is pure JSON; the resolver logs to stderr. output = IO.popen(cmd, chdir: NEW_DOT_ROOT, &:read) diff --git a/scripts/artifacts-utils/resolve-artifacts.ts b/scripts/artifacts-utils/resolve-artifacts.ts index 5ae804c87dc7..028cd044aafe 100644 --- a/scripts/artifacts-utils/resolve-artifacts.ts +++ b/scripts/artifacts-utils/resolve-artifacts.ts @@ -7,13 +7,14 @@ import resolveArtifacts from './lib/artifactsResolver'; * * Usage: * bun scripts/artifacts-utils/resolve-artifacts.ts \ - * --platform=ios --package=react-hybrid --hybrid=true --new-dot-root=. + * --platform=ios --hybrid=true --new-dot-root=. * * Prints the result as JSON to stdout (logs go to stderr) and always exits 0. */ const args = parseCommandLineArguments(); const platform = args.platform; -const packageName = args.package ?? ''; +const isHybrid = args.hybrid === 'true'; +const packageName = isHybrid ? 'react-hybrid' : 'react-standalone'; if (platform !== 'ios' && platform !== 'android') { process.stderr.write(`[PatchedArtifacts] Invalid or missing --platform "${platform ?? ''}" (expected "ios" or "android"); building from source.\n`); @@ -21,7 +22,7 @@ if (platform !== 'ios' && platform !== 'android') { process.exit(0); } -const options = {packageName, newDotRoot: args['new-dot-root'] ?? '.', isHybrid: args.hybrid === 'true'}; +const options = {packageName, newDotRoot: args['new-dot-root'] ?? '.', isHybrid}; const resolution = platform === 'ios' ? resolveArtifacts({...options, platform: 'ios'}) : resolveArtifacts({...options, platform: 'android'}); resolution