Custom shell scripts restrictions
TL;DR
Apple has locked down the security of their hosted infrastructure by only enabling shell scripts to run as part of ci_post_clone.sh
, ci_pre_xcodebuild.sh
or ci_post_xcodebuild.sh
in the ci_scripts
folder. Your Pods project has a custom shell script outside of this folder that is not triggered by one of these CI scripts, so does not have running permissions.
The solution for this specific issue are:
- (technically) Refactor your build script phase to inline the shell script file inside the run script.
- (recommended, but not always possible) Use the Swift Package version of the CocoaPod if available.
- (workaround) Downgrade the CocoaPod to a version without an external shell script.
Reference
From Customize your advanced Xcode Cloud workflows:
If your script doesn't appear to be running when you expect it to,
double-check that you've named it correctly and placed it in a
ci_scripts
folder alongside your project.
...
Lastly, it should be
noted that in a test action, multiple environments are used to build
and run your tests. Only the environment that is used for building
your tests will have your source code cloned into it by default. The
environments that run your tests won't have source code cloned into
them. They'll only have the ci_scripts folder made available on
them. As a result, the post-clone script won't run in these
environments and your custom scripts and any of their dependencies,
such as other shell scripts and small tools, must be entirely
contained within the ci_scripts folder.
Build script phases ARE allowed to run user-defined code as part of the build process, however, we can only run inlined custom scripts here. As discussed, external shell scripts have restricted permissions. Running the external shell script file after moving to ci_scripts
does NOT work. e.g. "${PODS_ROOT}/../ci_scripts/AppCenter-xcframeworks.sh"
.
Although not relevant here, note that the environment that tests your project won't have the source code cloned into them.
For tests or other environments to reference custom script files, we need to store additional scripts inside the ci_scripts
folder to ensure the action has access to it. Apple only allows 3 scripts to run corresponding to 3 stages of a build:
- After cloning the source code into the build environment.
- Before running
xcodebuild
.
- After running
xcodebuild
.
Additional shell scripts can can ONLY run here after delegating from the respective ci_post_clone.sh
, ci_pre_xcodebuild.sh
or ci_post_xcodebuild.sh
files in the ci_scripts
folder.
Solution 1
My issue was running an external shell script during the build process. Apple does allow Run Script Build Phases in Xcode Cloud workflows, but they have to be inlined. So, I had to do 4 steps to run a custom Pod shell script as part of a build phase:
- Refactor your Build Phases -> Run Script Phase script to inline the shell script file.
- Check the project builds locally after clearing
DerivedData
.
- Commit your code to GitHub / VCS.
- Trigger the workflow.

Solution 2 (recommended, but not always possible)
Add the Swift Package version of the CocoaPod as a dependency following Apple's documentation.
Solution 3 (workaround)
Downgrade your CocoaPod to a version without external shell scripts.
Notes
As you can tell from the amount of effort required to workaround custom shell script build phases with Xcode Cloud, I suggest raising an issue on the specific CocoaPod repository to migrate away from custom shell script files. These kinds of steps make using Xcode Cloud very painful.
As Xcode Cloud adoption grows it is entirely possible that individual CocoaPods no longer reference custom shell script files. I don't see Apple opening up their infrastructure to enable arbitrary shell script execution because this is a security risk, and to be honest, should have been prevented on other CI providers too.
I can also see how hassles like these to include legacy CocoaPods dependencies could accelerate more projects to migrate to SPM. SPM is already popular, and will likely become more popular as Apple ensures first-class integration.
Disclaimer: Xcode Cloud is in private beta so this issue may be resolved in future versions if shell script permissions are relaxed...