Xcode build counter (Run Script) and ENABLE_USER_SCRIPT_SANDBOXING

For some years now I’ve used the following ‘Run Script’ in Xcode to maintain a build counter in Info.plist for reference within my code:

#!/bin/bash    
buildNumber=$(/usr/libexec/PlistBuddy -c "Print CFBundleVersion" "$INFOPLIST_FILE")
buildNumber=$(($buildNumber + 1))
/usr/libexec/PlistBuddy -c "Set :CFBundleVersion $buildNumber" "$INFOPLIST_FILE"

In Swift I can access this with let bld = Bundle.main.infoDictionary?["CFBundleVersion"], which I would like to keep doing.

Recently Xcode 15 suggested I update project settings with ENABLE_USER_SCRIPT_SANDBOXING = YES;, which led to the error PhaseScriptExecution failed with a nonzero exit code linking to an issue in Info.plist until I understood to add Info.plist as an both an input and output file for the Run Script.

Now I have an error Cycle inside <myProject>; building could produce unreliable results. This usually can be resolved by moving the shell script phase 'Run Script' so that it runs before the build phase that depends on its outputs.

In particular this complains that Images.xcassets depends on (apparently) Info.plist.

The ‘Run Script’ build phase already runs first (as high as I can drag it in the ‘Build Phases’ list). Obviously I can ignore the new default setting for ENABLE_USER_SCRIPT_SANDBOXING and leave out the Input/Output file settings, but it would be nice to find the right way to do this so everything is satisfied and secure. Images.xcassets is an Apple/Xcode thing which is opaque to me.

Suggestions / solutions much appreciated.

Leave a Comment