Most of us still rely on self-hosted macOS servers for building iOS via Xcode. But Xcode does not clean up after itself that well:

$ du -h -d 1 "$HOME/Library/Developer/Xcode"

168G ~/Library/Developer/Xcode/Archives
12G ~/Library/Developer/Xcode/DerivedData

There are additional tools/rules/tasks in CI providers like the Gitlab or Azure Pipelines runner but I found that it was much easier to just quickly delete those myself with some cobbled together scripts. Advantage is I can now just run these not depending on a specific CI provider, but in a cron, via Ansible, via terminal...

Two scripts below: a regular Bash one, and an Ansible playbook. For the sake of it, also throw clearing out Gradle caches in there. Use it like you wish 😘

#!/usr/bin/env bash
set -e

function clean_xcode() {
rm -rf "$HOME/Library/Developer/Xcode/DerivedData"

# The find command here will delete all archive folders that are not created this month.
find "$HOME/Library/Developer/Xcode/Archives" \
-maxdepth 1 -type d \
! -name "$(date "+%Y-%m")*" -name "202*" -exec rm -rf {} \;
}

function clean_gradle() {
rm -rf "$HOME/.gradle/caches"
}

function clean_all() {
clean_xcode
clean_gradle
}

clean_all
- hosts: all
tasks:
- name: 'Delete Xcode Derived Data'
tags:
- ios
file:
state: absent
path: '/Library/Developer/Xcode/DerivedData'
- name: 'Delete old Xcode archives'
tags:
- ios
shell: |
find "/Library/Developer/Xcode/Archives" \
-maxdepth 1 -type d \
! -name "$(date "+%Y-%m")*" -name "202*" -exec rm -rf {} \;

- name: 'Clean Gradle caches'
tags:
- android
file:
state: absent
path: '/.gradle/caches'