@@ -58,6 +58,139 @@ EXTRA_ARGS="$SENTRY_CLI_EXTRA_ARGS $SENTRY_CLI_DEBUG_FILES_UPLOAD_EXTRA_ARGS $IN
5858
5959UPLOAD_DEBUG_FILES=" \" $SENTRY_CLI_EXECUTABLE \" debug-files upload $EXTRA_ARGS \" $DWARF_DSYM_FOLDER_PATH \" "
6060
61+ # Function to wait for dSYM files to be generated
62+ # This addresses a race condition where the upload script runs before dSYM generation completes
63+ wait_for_dsym_files () {
64+ local max_attempts=" ${SENTRY_DSYM_WAIT_MAX_ATTEMPTS:- 10} "
65+ local wait_interval=" ${SENTRY_DSYM_WAIT_INTERVAL:- 2} "
66+ local attempt=1
67+
68+ # Check if we should wait for dSYM files
69+ if [ " $SENTRY_DSYM_WAIT_ENABLED " == " false" ]; then
70+ echo " SENTRY_DSYM_WAIT_ENABLED=false, skipping dSYM wait check"
71+ return 0
72+ fi
73+
74+ # Warn if DWARF_DSYM_FILE_NAME is not set - we can't verify the main app dSYM
75+ if [ -z " $DWARF_DSYM_FILE_NAME " ]; then
76+ echo " warning: DWARF_DSYM_FILE_NAME not set, cannot verify main app dSYM specifically"
77+ echo " warning: Will proceed when any dSYM bundle is found"
78+ fi
79+
80+ echo " Checking for dSYM files in: $DWARF_DSYM_FOLDER_PATH "
81+
82+ # Debug information to help diagnose issues
83+ if [ -n " ${SENTRY_DSYM_DEBUG} " ]; then
84+ echo " DEBUG: DWARF_DSYM_FOLDER_PATH=$DWARF_DSYM_FOLDER_PATH "
85+ echo " DEBUG: DWARF_DSYM_FILE_NAME=$DWARF_DSYM_FILE_NAME "
86+ echo " DEBUG: PRODUCT_NAME=$PRODUCT_NAME "
87+ if [ -d " $DWARF_DSYM_FOLDER_PATH " ]; then
88+ echo " DEBUG: Contents of dSYM folder:"
89+ ls -la " $DWARF_DSYM_FOLDER_PATH " 2> /dev/null || echo " Cannot list folder"
90+ else
91+ echo " DEBUG: dSYM folder does not exist yet"
92+ fi
93+ fi
94+
95+ while [ $attempt -le $max_attempts ]; do
96+ # Check if the dSYM folder exists
97+ if [ -d " $DWARF_DSYM_FOLDER_PATH " ]; then
98+ # Check if there are any .dSYM bundles in the folder
99+ local dsym_count=$( find " $DWARF_DSYM_FOLDER_PATH " -name " *.dSYM" -type d 2> /dev/null | wc -l | tr -d ' ' )
100+
101+ if [ " $dsym_count " -gt 0 ]; then
102+ echo " Found $dsym_count dSYM bundle(s) in $DWARF_DSYM_FOLDER_PATH "
103+
104+ # If DWARF_DSYM_FILE_NAME is set, verify the main app dSYM exists and is complete
105+ if [ -n " $DWARF_DSYM_FILE_NAME " ]; then
106+ local main_dsym=" $DWARF_DSYM_FOLDER_PATH /$DWARF_DSYM_FILE_NAME "
107+
108+ if [ -d " $main_dsym " ]; then
109+ # Directory exists, now verify the actual DWARF binary exists inside
110+ local dwarf_dir=" $main_dsym /Contents/Resources/DWARF"
111+
112+ if [ -d " $dwarf_dir " ]; then
113+ # Check if there are any files in the DWARF directory
114+ local dwarf_files=$( find " $dwarf_dir " -type f 2> /dev/null | head -1)
115+
116+ if [ -n " $dwarf_files " ]; then
117+ # Verify the DWARF file is not empty (still being written)
118+ local dwarf_size=$( find " $dwarf_dir " -type f -size +0 2> /dev/null | head -1)
119+
120+ if [ -n " $dwarf_size " ]; then
121+ echo " Verified main app dSYM is complete: $DWARF_DSYM_FILE_NAME "
122+ return 0
123+ else
124+ echo " Main app dSYM DWARF binary is empty (still being written): $DWARF_DSYM_FILE_NAME (attempt $attempt /$max_attempts )"
125+ fi
126+ else
127+ echo " Main app dSYM DWARF directory is empty: $DWARF_DSYM_FILE_NAME (attempt $attempt /$max_attempts )"
128+ fi
129+ else
130+ echo " Main app dSYM structure incomplete (missing DWARF directory): $DWARF_DSYM_FILE_NAME (attempt $attempt /$max_attempts )"
131+ fi
132+ else
133+ echo " Main app dSYM not found yet: $DWARF_DSYM_FILE_NAME (attempt $attempt /$max_attempts )"
134+ fi
135+ else
136+ # DWARF_DSYM_FILE_NAME not set, check if any dSYM has valid DWARF content
137+ # This is less strict but better than nothing
138+ local has_valid_dsym=false
139+ for dsym in " $DWARF_DSYM_FOLDER_PATH " /* .dSYM; do
140+ if [ -d " $dsym /Contents/Resources/DWARF" ]; then
141+ local dwarf_files=$( find " $dsym /Contents/Resources/DWARF" -type f -size +0 2> /dev/null | head -1)
142+ if [ -n " $dwarf_files " ]; then
143+ has_valid_dsym=true
144+ break
145+ fi
146+ fi
147+ done
148+
149+ if [ " $has_valid_dsym " = true ]; then
150+ echo " Found dSYM bundle(s) with valid DWARF content"
151+ return 0
152+ else
153+ echo " Found dSYM bundle(s) but none have complete DWARF content yet (attempt $attempt /$max_attempts )"
154+ fi
155+ fi
156+ else
157+ echo " No dSYM bundles found yet in $DWARF_DSYM_FOLDER_PATH (attempt $attempt /$max_attempts )"
158+ fi
159+ else
160+ echo " dSYM folder does not exist yet: $DWARF_DSYM_FOLDER_PATH (attempt $attempt /$max_attempts )"
161+ fi
162+
163+ if [ $attempt -lt $max_attempts ]; then
164+ # Progressive backoff: quick checks first, longer waits later
165+ # Attempts 1-3: 0.5s (total 1.5s)
166+ # Attempts 4-6: 1s (total 3s)
167+ # Attempts 7+: 2s (remaining time)
168+ local current_interval=" $wait_interval "
169+ if [ -z " ${SENTRY_DSYM_WAIT_INTERVAL} " ]; then
170+ # Only use progressive intervals if user hasn't set custom interval
171+ if [ $attempt -le 3 ]; then
172+ current_interval=0.5
173+ elif [ $attempt -le 6 ]; then
174+ current_interval=1
175+ else
176+ current_interval=2
177+ fi
178+ fi
179+
180+ echo " Waiting ${current_interval} s for dSYM generation to complete..."
181+ sleep $current_interval
182+ fi
183+
184+ attempt=$(( attempt + 1 ))
185+ done
186+
187+ # Timeout reached
188+ echo " warning: Timeout waiting for dSYM files after $(( max_attempts * wait_interval)) s"
189+ echo " warning: This may result in incomplete debug symbol uploads"
190+ echo " warning: To disable this check, set SENTRY_DSYM_WAIT_ENABLED=false"
191+ return 1
192+ }
193+
61194XCODE_BUILD_CONFIGURATION=" ${CONFIGURATION} "
62195
63196if [ " $SENTRY_DISABLE_AUTO_UPLOAD " == true ]; then
@@ -67,6 +200,12 @@ elif [ "$SENTRY_DISABLE_XCODE_DEBUG_UPLOAD" == true ]; then
67200elif echo " $XCODE_BUILD_CONFIGURATION " | grep -iq " debug" ; then # case insensitive check for "debug"
68201 echo " Skipping debug files upload for *Debug* configuration"
69202else
203+ # Wait for dSYM files to be generated (addresses race condition in EAS builds)
204+ # Don't fail the script if wait times out - we still want to attempt upload
205+ set +e
206+ wait_for_dsym_files
207+ set -e
208+
70209 # 'warning:' triggers a warning in Xcode, 'error:' triggers an error
71210 set +x +e # disable printing commands otherwise we might print `error:` by accident and allow continuing on error
72211 SENTRY_UPLOAD_COMMAND_OUTPUT=$( /bin/sh -c " \" $LOCAL_NODE_BINARY \" $UPLOAD_DEBUG_FILES " 2>&1 )
0 commit comments