Skip to content

[No QA] Consume react-native dSYMS in CI workflows - #98853

Open
mateuuszzzzz wants to merge 11 commits into
Expensify:mainfrom
software-mansion-labs:add-dsyms-to-deploy-workflow
Open

[No QA] Consume react-native dSYMS in CI workflows#98853
mateuuszzzzz wants to merge 11 commits into
Expensify:mainfrom
software-mansion-labs:add-dsyms-to-deploy-workflow

Conversation

@mateuuszzzzz

@mateuuszzzzz mateuuszzzzz commented Aug 18, 2026

Copy link
Copy Markdown
Contributor

Explanation of Change

  • PR enables dSYMs consumption for staging, production and adhoc builds. During creating Xcode archive those dSYMs are consumed by Sentry build phase so later we can read react-native frames in crash reports.

  • Additionally, this PR removed redundancy from artifacts utility script and now package name is picked based on platform and hybrid flags.

  • dSYMs are large files so cache step was added for them so we could retrieve them quickly during workflow run.

For clarification:

  • react-native build utils download dSYMs separately. Later they're copied into xcframework. Finally, Xcode archive extracts those dSYMs into a directory that Sentry build phase reads.

Fixed Issues

$ #99186
PROPOSAL:

Tests

Trigger an AdHoc build with workflow changes from this PR

  • In the buildIOS job, verify the Resolve react-native artifact version step outputs a real version (not source)
  • Verify the Cache react-native artifacts step uses key …-rn-artifacts-react-hybrid-<version>
  • In the pod install logs, verify dSYM tarballs are fetched and merged:
    Cache miss: downloading reactnative-core-dSYM-debug.tar.gz … and Adding symbols … to framework tarball …
  • Verify the archive succeeds and the Sentry upload step reports React dSYMs

Offline tests

QA Steps

PR Author Checklist

  • I linked the correct issue in the ### Fixed Issues section above
  • I wrote clear testing steps that cover the changes made in this PR
    • I added steps for local testing in the Tests section
    • I added steps for the expected offline behavior in the Offline steps section
    • I added steps for Staging and/or Production testing in the QA steps section
    • I added steps to cover failure scenarios (i.e. verify an input displays the correct error message if the entered data is not correct)
    • I turned off my network connection and tested it while offline to ensure it matches the expected behavior (i.e. verify the default avatar icon is displayed if app is offline)
    • I tested this PR with a High Traffic account against the staging or production API to ensure there are no regressions (e.g. long loading states that impact usability).
  • I included screenshots or videos for tests on all platforms
  • I ran the tests on all platforms & verified they passed on:
    • Android: Native
    • Android: mWeb Chrome
    • iOS: Native
    • iOS: mWeb Safari
    • MacOS: Chrome / Safari
  • I verified there are no console errors (if there's a console error not related to the PR, report it or open an issue for it to be fixed)
  • I followed proper code patterns (see Reviewing the code)
    • I verified that comments were added to code that is not self explanatory
    • I verified that any new or modified comments were clear, correct English, and explained "why" the code was doing something instead of only explaining "what" the code was doing.
    • I verified any copy / text that was added to the app is grammatically correct in English. It adheres to proper capitalization guidelines (note: only the first word of header/labels should be capitalized), and is either coming verbatim from figma or has been approved by marketing (in order to get marketing approval, ask the Bug Zero team member to add the Waiting for copy label to the issue)
  • If a new code pattern is added I verified it was agreed to be used by multiple Expensify engineers
  • I followed the guidelines as stated in the Review Guidelines
  • I tested other components that can be impacted by my changes (i.e. if the PR modifies a shared library or component like Avatar, I verified the components using Avatar are working as expected)
  • If a new CSS style is added I verified that:
    • A similar style doesn't already exist
    • The style can't be created with an existing StyleUtils function (i.e. StyleUtils.getBackgroundAndBorderStyle(theme.componentBG))
  • If new assets were added or existing ones were modified, I verified that:
    • The assets are optimized and compressed (for SVG files, run npm run compress-svg)
    • The assets load correctly across all supported platforms.
  • If the PR modifies code that runs when editing or sending messages, I tested and verified there is no unexpected behavior for all supported markdown - URLs, single line code, code blocks, quotes, headings, bold, strikethrough, and italic.
  • If the PR modifies a generic component, I tested and verified that those changes do not break usages of that component in the rest of the App (i.e. if a shared library or component like Avatar is modified, I verified that Avatar is working as expected in all cases)
  • If the PR modifies a component related to any of the existing Storybook stories, I tested and verified all stories for that component are still working as expected.
  • If the PR modifies a component or page that can be accessed by a direct deeplink, I verified that the code functions as expected when the deeplink is used - from a logged in and logged out account.
  • If the PR modifies the UI (e.g. new buttons, new UI components, changing the padding/spacing/sizing, moving components, etc) or modifies the form input styles:
    • I verified that all the inputs inside a form are aligned with each other.
    • I added Design label and/or tagged @Expensify/design so the design team can review the changes.
  • I added unit tests for any new feature or bug fix in this PR to help automatically prevent regressions in this user flow.
  • If the main branch was merged into this PR after a review, I tested again and verified the outcome was still expected according to the Test steps.

Screenshots/Videos

Android: Native
Android: mWeb Chrome
iOS: Native
iOS: mWeb Safari
MacOS: Chrome / Safari

@mateuuszzzzz mateuuszzzzz changed the title Use react-native dSYMs in deploy.yml workflow [No QA] Use react-native dSYMs in deploy.yml workflow Aug 18, 2026
@mateuuszzzzz mateuuszzzzz changed the title [No QA] Use react-native dSYMs in deploy.yml workflow [No QA] Consume react-native dSYMS in CI workflows Aug 18, 2026
Comment thread .github/workflows/buildIOS.yml
path: ~/Library/Caches/Expensify/react-native-artifacts
key: ${{ runner.os }}-rn-artifacts-react-hybrid-${{ steps.resolve-rn-artifacts.outputs.VERSION }}

- name: Cache Pod dependencies

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems that the Pods cache key doesn't account for download-dsyms but the dSYM state lives inside the cached path: process_dsyms merges the symbols into the framework tarball under Pods/ReactNativeCore-artifacts (artifacts_dir in rncore.rb).

verifyHybridApp.yml calls this workflow with the download-dsyms: 'false' and runs on pull_request_target, so its caches are main-scoped and restorable by staging/production deploy runs. This creates a situation where a deploy that restores a Pods cache and then skips the CocoaPods installation will archive without the react-native dSYMs. As a result, Sentry silently loses the symbols, depending on who saved the cache last.

We could append -${{ inputs.download-dsyms }} to the cache key to prevent this from happening

@mateuuszzzzz mateuuszzzzz Aug 24, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Regarding pods installation step: This step is a bit outdated at the moment. Currently it does not have Github token in context so it cannot even install pods properly. Pods are also installed by Rock (so we have duplication) and this step does it correctly, but at the same time it does not have advanced caching logic. This is something I'd like to address in separate PR that will improve current pods installation and disable this step in rock.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Created the follow-up issue: #99331

It captures the three points from this thread — the missing GitHub token context, the duplication with Rock, and the lack of advanced caching — with the proposal to improve the pods installation and disable the equivalent step in Rock.


view run

Comment thread .github/workflows/buildIOS.yml

@collectioneur collectioneur left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM 🦾

@mateuuszzzzz
mateuuszzzzz marked this pull request as ready for review August 24, 2026 12:12
@mateuuszzzzz
mateuuszzzzz requested a review from a team as a code owner August 24, 2026 12:12
@melvin-bot
melvin-bot Bot requested a review from mananjadhav August 24, 2026 12:12
@melvin-bot

melvin-bot Bot commented Aug 24, 2026

Copy link
Copy Markdown

@mananjadhav Please copy/paste the Reviewer Checklist from here into a new comment on this PR and complete it. If you have the K2 extension, you can simply click: [this button]

@melvin-bot
melvin-bot Bot removed the request for review from a team August 24, 2026 12:12

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 6033111017

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

runs-on: blacksmith-12vcpu-macos-latest
env:
PULL_REQUEST_NUMBER: ${{ inputs.pull-request-number }}
RCT_SYMBOLICATE_PREBUILT_FRAMEWORKS: ${{ inputs.download-dsyms && '1' || '0' }}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Include the dSYM mode in Rock's native fingerprint

When the same commit is first built by verifyHybridApp.yml, this input defaults to false, while deployment and AdHoc builds later set it to true. Rock downloads an existing native build when its fingerprint matches (contributingGuides/SETUP_IOS.md:5-9), but rock.config.mjs:24-34 does not include RCT_SYMBOLICATE_PREBUILT_FRAMEWORKS in the fingerprint environment. Consequently, the dSYM-enabled run can reuse the archive produced without dSYMs and skip the pod install/archive work that consumes them, leaving React Native frames unsymbolicated; add this variable to fingerprint.env or otherwise force distinct native fingerprints for the two modes.

Useful? React with 👍 / 👎.

@mateuuszzzzz mateuuszzzzz Aug 24, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This comment can be a bit misleading, but the point is:

The output of the build is an xcarchive. This archive may or may not include dSYMs. I don't think the lack of this distinction breaks the build (in fact, it shouldn't, since debug symbols don't affect the binary layout), but it does clearly draw a line between archives with and without dSYMs.

I.e., our final output depends on the dSYMs flag, so it makes sense to include it in the rock fingerprint.

@mateuuszzzzz

Copy link
Copy Markdown
Contributor Author

@MelvinBot could you create a follow-up issue for this one: #98853 (comment)

@github-actions

Copy link
Copy Markdown
Contributor

🚧 roryabraham has triggered a test Expensify/App build. You can view the workflow run here.

@github-actions

Copy link
Copy Markdown
Contributor

env:
GITHUB_TOKEN: ${{ github.token }}
run: |
VERSION=$(bun scripts/artifacts-utils/resolve-artifacts.ts --platform=ios --hybrid=true --new-dot-root="$GITHUB_WORKSPACE" | jq -r '.version // "source"')

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
VERSION=$(bun scripts/artifacts-utils/resolve-artifacts.ts --platform=ios --hybrid=true --new-dot-root="$GITHUB_WORKSPACE" | jq -r '.version // "source"')
VERSION=$(./node_modules/.bin/bun scripts/artifacts-utils/resolve-artifacts.ts --platform=ios --hybrid=true --new-dot-root="$GITHUB_WORKSPACE" | jq -r '.version // "source"')

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

or alternatively: update setupNode composite action to add that to the path so plain bun works. npx bun would also work, but it spins up a node runtime just to resolve a known binary path for the bun binary, which then must start up. So it adds ~60ms vs executing bun directly. nbd in this context

@mananjadhav

Copy link
Copy Markdown
Collaborator

@roryabraham Does this need review?

@roryabraham

Copy link
Copy Markdown
Contributor

no thanks @mananjadhav

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants