ソースを参照

CI: Add wrapper function for macOS disk image operations

As not only detaching but apparently all operations of hdiutil can be
blocked by slow disk I/O on CI runners, this wraps all invocations of
it in a helper function that attempts up to 5 retries with a backoff
timer.
PatTheMav 2 年 前
コミット
7ece5cd057
1 ファイル変更35 行追加24 行削除
  1. 35 24
      .github/scripts/utils.zsh/create_diskimage

+ 35 - 24
.github/scripts/utils.zsh/create_diskimage

@@ -19,16 +19,46 @@ log_group "Create macOS disk image"
 local _hdiutil_flags
 if (( _loglevel < 1 )) _hdiutil_flags='-quiet'
 
-trap "hdiutil detach ${_hdiutil_flags} /Volumes/${output_name}; rm temp.dmg; log_group; return 2" ERR
+trap "safe_hdiutil detach ${_hdiutil_flags} /Volumes/${output_name}; rm temp.dmg; log_group; return 2" ERR
 
-hdiutil create ${_hdiutil_flags} \
+safe_hdiutil() {
+  local _status=0
+  local -r -a _backoff=(2 5 10 15 30)
+
+  for i ({1..5}) {
+    if [[ ${1} == detach ]] {
+      if ! [[ -d ${@[-1]} ]] {
+        log_warning "Volume at mountpoint ${@[-1]} is not mounted anymore. Continuing."
+        _status=0
+        break
+      }
+    }
+
+    hdiutil ${@} && _status=0 || _status=1
+
+    if (( _status )) {
+      log_warning "Unable to run 'hdiutil ${@}' (attempt #${i}). Retrying."
+      sleep ${_backoff[${i}]}
+    } else {
+      break
+    }
+  }
+
+  if (( _status )) {
+    log_error "Unable to run 'hdiutil ${@}'. Aborting"
+    log_group
+    return 2
+  }
+}
+
+safe_hdiutil create ${_hdiutil_flags} \
   -volname "${volume_name}" \
   -srcfolder ${source} \
   -ov \
   -fs APFS \
   -format UDRW \
   temp.dmg
-hdiutil attach ${_hdiutil_flags} \
+safe_hdiutil attach ${_hdiutil_flags} \
   -noverify \
   -readwrite \
   -mountpoint /Volumes/${output_name} \
@@ -48,28 +78,9 @@ SetFile -a C /Volumes/${output_name}
 rm -rf -- /Volumes/${output_name}/.fseventsd(N)
 log_info "Converting disk image..."
 
-if (( ${+CI} )) {
-  local _status=0
-  for i ({1..5}) {
-    hdiutil detach ${_hdiutil_flags} /Volumes/${output_name} && _status=0 || _status=1
-
-    if (( _status )) {
-      log_warning "Unable to eject disk image (attempt #${i}). Retrying."
-    } else {
-      break
-    }
-  }
-
-  if (( _status )) {
-    log_error "Unable to eject disk image after 5 attempts. Aborting"
-    log_group
-    return 2
-  }
-} else {
-  hdiutil detach ${_hdiutil_flags} /Volumes/${output_name}
-}
+safe_hdiutil detach ${_hdiutil_flags} /Volumes/${output_name}
 
-hdiutil convert ${_hdiutil_flags} \
+safe_hdiutil convert ${_hdiutil_flags} \
   -format ULMO \
   -ov \
   -o ${output_name}.dmg temp.dmg