Skip to content

Commit 783fa4c

Browse files
committed
ci: cleanup mac build runner disk before concourse builds
1 parent 4fa04eb commit 783fa4c

3 files changed

Lines changed: 259 additions & 2 deletions

File tree

ci/pipeline.yml

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ groups:
4141
- check-code
4242
- install-deps
4343
- dev-build
44+
- cleanup-mac-build-worker
4445
- prerelease
4546
- prod-build
4647
- name: image
@@ -149,6 +150,7 @@ jobs:
149150
SPARK_TOKEN_IDENTIFIER: #@ data.values.spark_token_identifier
150151
BREEZ_API_KEY: #@ data.values.breez_api_key
151152
BREEZ_NETWORK: #@ data.values.breez_network
153+
MIN_BUILD_FREE_GB: 30
152154
- task: upload-to-gcs
153155
config:
154156
platform: linux
@@ -218,6 +220,27 @@ jobs:
218220
params:
219221
file: testflight-version/version
220222

223+
- name: cleanup-mac-build-worker
224+
serial: true
225+
plan:
226+
- in_parallel:
227+
- get: daily
228+
trigger: true
229+
- get: pipeline-tasks
230+
- #@ claim_lock()
231+
- task: cleanup-mac-build-worker
232+
tags: [ mac-m1 ]
233+
ensure: #@ release_lock()
234+
config:
235+
platform: darwin
236+
inputs:
237+
- name: pipeline-tasks
238+
run:
239+
path: /bin/sh
240+
args: [ "-c", "arch -arm64 pipeline-tasks/ci/tasks/macos-build-disk-cleanup.sh scheduled" ]
241+
params:
242+
MIN_BUILD_FREE_GB: 35
243+
221244
- name: prod-build
222245
serial: true
223246
plan:
@@ -296,6 +319,7 @@ jobs:
296319
SPARK_TOKEN_IDENTIFIER: #@ data.values.spark_token_identifier
297320
BREEZ_API_KEY: #@ data.values.breez_api_key
298321
BREEZ_NETWORK: #@ data.values.breez_network
322+
MIN_BUILD_FREE_GB: 30
299323
- task: upload-to-gcs
300324
config:
301325
platform: linux

ci/tasks/build.sh

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,21 @@ set -eu
44
export CI_ROOT="$(pwd)"
55
export ENVFILE=.env.ci
66
REACT_NATIVE_CONFIG_ENV="${CI_ROOT}/repo/${ENVFILE}"
7+
DISK_CLEANUP_TASK="${CI_ROOT}/pipeline-tasks/ci/tasks/macos-build-disk-cleanup.sh"
78

8-
cleanup_react_native_config_env() {
9+
cleanup_build_task() {
910
rm -f "$REACT_NATIVE_CONFIG_ENV"
11+
lsof -ti:8080,8081 | xargs kill -9 || true
12+
/bin/bash "$DISK_CLEANUP_TASK" post || true
1013
}
11-
trap cleanup_react_native_config_env EXIT
14+
trap cleanup_build_task EXIT
1215

1316
export PATH=$(cat /Users/m1/concourse/path)
1417
export PUBLIC_VERSION=$(cat $VERSION_FILE)
1518

19+
echo " --> Preparing macOS build worker disk"
20+
/bin/bash "$DISK_CLEANUP_TASK" pre
21+
1622
# Make sure ssh agent is running - to access GaloyMoney ios keystore from github
1723
echo " --> Setting up ssh agent"
1824
eval "$(ssh-agent -s)"
Lines changed: 227 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,227 @@
1+
#!/bin/bash
2+
3+
set -euo pipefail
4+
5+
MODE="${1:-check}"
6+
MIN_FREE_GB="${MIN_BUILD_FREE_GB:-${2:-30}}"
7+
CI_ROOT="${CI_ROOT:-$(pwd)}"
8+
DISK_CHECK_PATH="${DISK_CHECK_PATH:-$CI_ROOT}"
9+
CONCOURSE_WORKDIR="${CONCOURSE_WORKDIR:-/Users/m1/concourse/workdir}"
10+
11+
required_kb=$((MIN_FREE_GB * 1024 * 1024))
12+
13+
free_kb() {
14+
df -Pk "$DISK_CHECK_PATH" | awk 'NR == 2 { print $4 }'
15+
}
16+
17+
free_gb() {
18+
awk "BEGIN { printf \"%.1f\", $(free_kb) / 1024 / 1024 }"
19+
}
20+
21+
remove_path() {
22+
local path="$1"
23+
24+
if [[ -e "$path" || -L "$path" ]]; then
25+
echo "Removing $path"
26+
rm -rf -- "$path"
27+
fi
28+
}
29+
30+
remove_old_children() {
31+
local dir="$1"
32+
local days="$2"
33+
34+
if [[ -d "$dir" ]]; then
35+
echo "Removing children older than ${days}d from $dir"
36+
find "$dir" -mindepth 1 -maxdepth 1 -mtime +"$days" -exec rm -rf {} + || true
37+
fi
38+
}
39+
40+
remove_all_children() {
41+
local dir="$1"
42+
43+
if [[ -d "$dir" ]]; then
44+
echo "Removing children from $dir"
45+
find "$dir" -mindepth 1 -maxdepth 1 -exec rm -rf {} + || true
46+
fi
47+
}
48+
49+
current_ios_runtime_identifier() {
50+
local sdk_version
51+
sdk_version="$(xcodebuild -version -sdk iphoneos SDKVersion 2>/dev/null | tr -d '[:space:]' || true)"
52+
53+
if [[ -n "$sdk_version" ]]; then
54+
echo "com.apple.CoreSimulator.SimRuntime.iOS-${sdk_version//./-}"
55+
fi
56+
}
57+
58+
installed_ios_runtime_identifiers() {
59+
local runtime_list
60+
61+
if ! command -v xcrun >/dev/null 2>&1; then
62+
echo "xcrun is not available on PATH." >&2
63+
return 1
64+
fi
65+
66+
if ! runtime_list="$(xcrun simctl runtime list 2>&1)"; then
67+
echo "$runtime_list" >&2
68+
return 1
69+
fi
70+
71+
printf "%s\n" "$runtime_list" \
72+
| sed -n 's/.*\(com\.apple\.CoreSimulator\.SimRuntime\.iOS-[0-9A-Za-z.-]*\).*/\1/p' \
73+
| sort -u
74+
}
75+
76+
print_disk_report() {
77+
echo "---- Disk usage ----"
78+
df -h "$DISK_CHECK_PATH" || true
79+
df -h || true
80+
81+
echo "---- Large macOS build paths ----"
82+
for path in \
83+
"$CI_ROOT/repo/node_modules" \
84+
"$CI_ROOT/repo/ios/Pods" \
85+
"$CI_ROOT/repo/android/app/build" \
86+
"$CI_ROOT/repo/android/build" \
87+
"$CI_ROOT/repo/ios/build" \
88+
"$CONCOURSE_WORKDIR/volumes/dead" \
89+
"$CONCOURSE_WORKDIR/volumes/live" \
90+
"/private/var/root/Library/Developer/Xcode/Archives" \
91+
"/private/var/root/Library/Developer/Xcode/DerivedData" \
92+
"$HOME/Library/Developer/Xcode/Archives" \
93+
"$HOME/Library/Developer/Xcode/DerivedData" \
94+
"/Users/m1/Library/Developer/Xcode/Archives" \
95+
"/Users/m1/Library/Developer/Xcode/DerivedData" \
96+
"/Library/Developer/CoreSimulator/Volumes"; do
97+
if [[ -e "$path" ]]; then
98+
du -sh "$path" 2>/dev/null || true
99+
fi
100+
done
101+
102+
echo "---- iOS simulator runtimes ----"
103+
if command -v xcrun >/dev/null 2>&1; then
104+
xcrun simctl runtime list || true
105+
fi
106+
}
107+
108+
cleanup_workspace_build_outputs() {
109+
remove_path "$CI_ROOT/repo/android/app/build"
110+
remove_path "$CI_ROOT/repo/android/build"
111+
remove_path "$CI_ROOT/repo/ios/build"
112+
remove_path "$CI_ROOT/repo/ios/Blink.ipa"
113+
}
114+
115+
cleanup_xcode_artifacts() {
116+
for dir in \
117+
"/private/var/root/Library/Developer/Xcode/Archives" \
118+
"$HOME/Library/Developer/Xcode/Archives" \
119+
"/Users/m1/Library/Developer/Xcode/Archives"; do
120+
remove_old_children "$dir" 28
121+
done
122+
123+
for dir in \
124+
"/private/var/root/Library/Developer/Xcode/DerivedData" \
125+
"$HOME/Library/Developer/Xcode/DerivedData" \
126+
"/Users/m1/Library/Developer/Xcode/DerivedData"; do
127+
if [[ -d "$dir" ]]; then
128+
echo "Removing GaloyApp DerivedData older than 28d from $dir"
129+
find "$dir" -mindepth 1 -maxdepth 1 -name "GaloyApp-*" -mtime +28 -exec rm -rf {} + || true
130+
fi
131+
done
132+
}
133+
134+
cleanup_concourse_dead_volumes() {
135+
remove_all_children "$CONCOURSE_WORKDIR/volumes/dead"
136+
}
137+
138+
cleanup_old_ios_runtimes() {
139+
local current_runtime
140+
local installed_runtimes
141+
current_runtime="$(current_ios_runtime_identifier)"
142+
143+
if [[ -z "$current_runtime" ]]; then
144+
echo "Could not determine current iOS SDK runtime; skipping simulator runtime cleanup."
145+
return
146+
fi
147+
148+
echo "Keeping current iOS simulator runtime: $current_runtime"
149+
150+
if ! installed_runtimes="$(installed_ios_runtime_identifiers)"; then
151+
echo "Could not list iOS simulator runtimes; skipping simulator runtime cleanup."
152+
return
153+
fi
154+
155+
while IFS= read -r runtime; do
156+
[[ -z "$runtime" ]] && continue
157+
158+
if [[ "$runtime" != "$current_runtime" ]]; then
159+
echo "Deleting old iOS simulator runtime: $runtime"
160+
xcrun simctl runtime delete "$runtime" || true
161+
fi
162+
done <<< "$installed_runtimes"
163+
}
164+
165+
assert_current_ios_runtime_present() {
166+
local current_runtime
167+
local installed_runtimes
168+
current_runtime="$(current_ios_runtime_identifier)"
169+
170+
if [[ -z "$current_runtime" ]]; then
171+
echo "Could not determine current iOS SDK runtime; skipping current runtime assertion."
172+
return
173+
fi
174+
175+
if ! installed_runtimes="$(installed_ios_runtime_identifiers)"; then
176+
echo "ERROR: Could not list iOS simulator runtimes."
177+
echo "Check CoreSimulatorService/simdiskimaged on the Scaleway Mac before running the build."
178+
exit 1
179+
fi
180+
181+
if ! printf "%s\n" "$installed_runtimes" | grep -qx "$current_runtime"; then
182+
echo "ERROR: Required iOS runtime $current_runtime is not installed."
183+
echo "Install the current platform runtime on the Scaleway Mac with: xcodebuild -downloadPlatform iOS"
184+
exit 1
185+
fi
186+
}
187+
188+
assert_free_space() {
189+
local available
190+
available="$(free_kb)"
191+
192+
if (( available < required_kb )); then
193+
echo "ERROR: Only $(free_gb) GB free on $DISK_CHECK_PATH after macOS build cleanup. Required: ${MIN_FREE_GB} GB."
194+
echo "Manual follow-up: remove only stale Concourse live volumes with the worker stopped, or run Nix garbage collection with the worker stopped."
195+
print_disk_report
196+
exit 1
197+
fi
198+
199+
echo "Free disk space on $DISK_CHECK_PATH: $(free_gb) GB (required: ${MIN_FREE_GB} GB)"
200+
}
201+
202+
case "$MODE" in
203+
check)
204+
print_disk_report
205+
assert_current_ios_runtime_present
206+
assert_free_space
207+
;;
208+
pre|scheduled)
209+
print_disk_report
210+
cleanup_workspace_build_outputs
211+
cleanup_xcode_artifacts
212+
cleanup_concourse_dead_volumes
213+
assert_current_ios_runtime_present
214+
cleanup_old_ios_runtimes
215+
assert_current_ios_runtime_present
216+
assert_free_space
217+
;;
218+
post)
219+
cleanup_workspace_build_outputs
220+
cleanup_concourse_dead_volumes
221+
print_disk_report
222+
;;
223+
*)
224+
echo "Usage: $0 {check|pre|post|scheduled}" >&2
225+
exit 2
226+
;;
227+
esac

0 commit comments

Comments
 (0)