I am currently testing Xcode Cloud as a member of Apple's private beta program and encountered an issue when trying to Archive / Build (any action) on the cloud for my project.
The project is a fairly basic SwiftUI app with CocoaPods dependencies. I have followed the steps to integrate CocoaPods into my project as described by Apple by simply committing my Pods directory to GitHub. However, I am getting a build error on the cloud for every attempted action:
Command PhaseScriptExecution failed with a nonzero exit code
Here is the ASC log for reference:
This is very strange because the same project builds and archives successfully on my local machine. I have used the same macOS and Xcode versions in the Workflow editor as my local version of Xcode.
How can I resolve this error?
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:
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:
xcodebuild
.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.
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:
DerivedData
.Add the Swift Package version of the CocoaPod as a dependency following Apple's documentation.
Downgrade your CocoaPod to a version without external shell scripts.
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...