How to upload dSYMs files to Sentry with Xcode Cloud
3 min read

How to upload dSYMs files to Sentry with Xcode Cloud

I have 3 Xcode Cloud workflows:

  • any update on the `dev` branch creates a build for Internal Testing
  • any update on the `main` branch creates a build for External Testing
  • a manual trigger of my App Store build workflow will create a build that can

I use Sentry to track bugs and performance issues in production, and as explained in their docs, it requires dSYMs (debug information files) to symbolicate your stack traces and reveal functions, file names, and line numbers.

Without it, your Sentry UI ends up with messages such as "A required debug information file was missing.", "There are xxx issues blocking event processing" and more red than you need for a place that is already anxiety-inducing.

To avoid that and be able to get rid of all bugs, you need to add a post-build script that will upload the dSYM to sentry.

Add a post build script to your project

As explained in Writing custom build scripts, the first thing you need is a ci_scripts group (File > New > Group) at the root of your project (next to your FantasticApp.xcodeproj or FantasticApp.xcworkspace).

Then, you'll create a file called ci_post_xcodebuild.sh.

Open the terminal, and run chmod +x ci_post_xcodebuild.shon that file. This will prevent Xcode Cloud from spouting this message in the logs:

And now paste this into your .sh file:

#!/bin/sh

# Don't forget to run 'chmod +x ci_post_xcodebuild.sh' from the terminal after adding this file to your project

set -e
if [[ -n $CI_ARCHIVE_PATH ]];
then

    # Install Sentry CLI into the current directory ($CI_PRIMARY_REPOSITORY_PATH/ci_scripts)
    export INSTALL_DIR=$PWD

    if [[ $(command -v sentry-cli) == "" ]]; then
        curl -sL https://sentry.io/get-cli/ | bash
    fi

    # Upload dSYMs
    $CI_PRIMARY_REPOSITORY_PATH/ci_scripts/sentry-cli --auth-token $SENTRY_AUTH_TOKEN upload-dif --org $SENTRY_ORG --project $SENTRY_PROJECT $CI_ARCHIVE_PATH
else
    echo "Archive path isn't available. Unable to run dSYMs uploading script."
fi

What it does is really simple:

  • install sentry-cli
  • upload the dSYMs

As you can see, it mixes environment variables from Xcode Cloud (such as CI_ARCHIVE_PATH) and custom ones (SENTRY_*).

And the only thing we have to do now is to provide these variables.

Add environment variables to Xcode Cloud

Open each of your workflow in Xcode, go to the Environment tab and add these 3 variables:

  • SENTRY_AUTH_TOKEN: you can generate one from Sentry's docs or Sentry in Settings > Developer Settings > Auth Tokens
  • SENTRY_ORG: your organization slug (Settings > General Settings), otherwise featured in Sentry's docs
  • SENTRY_PROJET: your project slug  (Settings > Projects), otherwise featured in Sentry's docs

Build and verify upload

Even if everything is green in Xcode Cloud, you'll probably still want to see with your own two eyes that the dSYM was uploaded to Sentry. Here's how:

First, go to App Store Connect, open your project, head to the Xcode Cloud tab, and click on the latest build number to open it:

In the logs, find the Run ci_post_xcodebuild.sh script disclose group, open it and you should see something like that

Copy any of the UUID next to UPLOADED and head to your project settings in sentry, in the "Debug Files" section, and search for that UUID.

As you can see here, the f456235e-0d09-3eda-8156-205b85620051 for the Watch app figures in both listings. 🥳

Conclusion

So there you have it: a simple way to let Xcode Cloud upload your dSYMs to Sentry for any build it creates.

🤔
This adds about 14 to 20 seconds to the building process. If you see an easy way to improve that, ping me on Twitter or Mastodon! ☺️