Registro de build
¿Cómo evitas que una caída de GitHub rompa tu build de iOS?
Haz que pod install funcione primero desde una caché local, quita las fuentes que no necesitas y reintenta los fallos de red con espera en lugar de fallar al primer error. El 8 de noviembre de 2026 las descargas de releases de GitHub devolvieron 503 durante unos 30 minutos y se llevaron por delante dos builds de TestFlight de GoTasty, el juego en Unity de GOGOGO LLC; esta es la solución.
6 min de lectura

El 8 de noviembre de 2026, las descargas de releases de GitHub respondieron HTTP 503 durante una media hora. Dos builds de iOS de GoTasty, nuestro juego en Unity de GOGOGO LLC, murieron en el mismo paso: pod install, al descargar UnityAds.zip para el adaptador de mediación de Unity Ads. En nuestro código no había cambiado nada. Los builds fallaron porque una descarga de dependencias necesitaba que github.com estuviera en pie justo en ese minuto.
Si tu proyecto de iOS usa CocoaPods, probablemente tienes el mismo riesgo. Muchos pods son un podspec en la CDN de CocoaPods que apunta a un zip en una release de GitHub. Esto es lo que cambiamos.
¿Por qué pod install depende de GitHub?
Por dos razones. Primera: la fuente de un pod suele ser un archivo de una release de GitHub, así que descargar el pod es descargar de GitHub. Segunda: algunas herramientas añaden el antiguo repositorio git de specs, https://github.com/CocoaPods/Specs, como fuente junto a la CDN. En nuestro caso, el plugin de Google Mobile Ads para Unity escribe esa línea en el Podfile generado. Todos nuestros pods están en la CDN, así que la fuente git no añadía nada salvo otra petición a github.com y un montón de avisos "Found multiple specifications".
Paso 1: quita las fuentes que no necesitas
El External Dependency Manager de Unity genera el Podfile en cada build, así que editarlo a mano no dura. Borramos la fuente git de specs en el script de build, justo antes de pod install:
sed -i '' "\#^source 'https://github.com/CocoaPods/Specs'#d" Podfile
grep -n '^source' Podfile || trueEl grep imprime en el log las fuentes que quedan, para que veas qué usó de verdad el build.
Paso 2: instala primero desde la caché
CocoaPods guarda los pods descargados en ~/Library/Caches/CocoaPods y las specs en ~/.cocoapods. Si ambas están calientes y tus pods no han cambiado, pod install no necesita red. Por eso el primer intento es un pod install simple, sin --repo-update. Solo si falla, normalmente porque falta una spec, los intentos siguientes actualizan el repositorio.
Dónde vive la caché depende del runner. En nuestro Mac mini propio simplemente persiste entre ejecuciones. En un runner macOS alojado necesita actions/cache. Nuestro trabajo de archivo no tiene checkout, así que no hay fichero de bloqueo que hashear: restauramos la caché más reciente por prefijo y guardamos una nueva en cada ejecución.
- name: CocoaPods cache (cloud)
if: ${{ inputs.runner == 'cloud' }}
uses: actions/cache@v4
with:
path: |
~/Library/Caches/CocoaPods
~/.cocoapods/repos/trunk
key: pods-${{ runner.os }}-${{ github.run_id }}
restore-keys: pods-${{ runner.os }}-Paso 3: reintenta con espera
Las caídas como esta suelen ser cortas. Un build que falla al primer 503 tira a la basura la exportación de Unity que vino antes para ahorrarse un minuto de espera. Nuestro script lo intenta cuatro veces: la instalación simple y luego tres intentos con --repo-update, esperando 60 segundos y después 180 entre ellos.
attempts=("" "--repo-update" "--repo-update" "--repo-update")
waits=(0 60 180 0)
for i in "${!attempts[@]}"; do
echo "::group::pod install ${attempts[$i]} (attempt $((i + 1))/${#attempts[@]})"
if pod install ${attempts[$i]}; then echo "::endgroup::"; exit 0; fi
echo "::endgroup::"
if [ "$i" -lt $((${#attempts[@]} - 1)) ] && [ "${waits[$i]}" -gt 0 ]; then
echo "pod install failed; next attempt in ${waits[$i]} s"
sleep "${waits[$i]}"
fi
done
echo "::error::pod install failed after ${#attempts[@]} attempts"
exit 1Cada intento tiene su propio grupo plegable en el log, así que un reintento se ve en la ejecución sin enterrar la salida. Si fallan los cuatro, el error lo dice en una línea.
¿Cómo se prueba sin esperar a una caída?
No hace falta esperar a que GitHub falle. Bastan tres comprobaciones:
- Caché caliente, sin red. En una máquina que ya ha compilado el proyecto, bloquea github.com (en una máquina de pruebas basta una línea en el fichero hosts) y ejecuta el script de instalación. Con los pods sin cambios debería funcionar al primer intento.
- Una spec que falta. Añade una versión de un pod que nunca hayas descargado y mantén github.com bloqueado. El script debería pasar por los cuatro intentos, esperar entre ellos y terminar con el error de una línea en lugar de quedarse colgado.
- Red normal. Quita el bloqueo y vuelve a ejecutarlo. El intento que funcione debería seguir siendo la instalación simple, lo que demuestra que tus builds usan de verdad la caché.
Después, sigue leyendo los grupos del log. Si un build con los pods sin cambios llega alguna vez al segundo intento, la caché no está donde crees, y la próxima caída te lo dirá.
¿Qué no arregla esto?
- Un pod que nunca has descargado sigue necesitando red. Una dependencia nueva añadida durante una caída seguirá fallando, solo que más tarde y con más educación.
- Un runner alojado en frío sin caché restaurada está tan expuesto como antes.
- Los paquetes de Swift van por otro camino. Xcode los resuelve por su cuenta; si los usas, fíjalos y cachéalos aparte.
Lo que sí hace es convertir una caída corta de GitHub, para cada build cuyas dependencias no han cambiado (que son la mayoría), en un build más lento en lugar de uno fallido.
¿Deberías subir los pods al repositorio?
Hacer commit de la carpeta Pods saca la red del build por completo, y algunos equipos lo hacen. En un proyecto de Unity, donde el proyecto de Xcode y el Podfile se regeneran en cada build, añade una carpeta grande y ruidosa que revisar. Una caché caliente y los reintentos nos dieron casi todo el beneficio sin el peso en el repositorio. La máquina que mantiene caliente esa caché se describe en CI de Unity en un Mac mini propio.
Fuentes
- Releases · Unity-Technologies/unity-ads-ios · GitHub
- CocoaPods 1.8 Beta is Here! · CocoaPods Blog
- Podfile Syntax Reference · CocoaPods Guides
- Command-line Reference · CocoaPods Guides
- googlesamples/unity-jar-resolver (External Dependency Manager for Unity) · GitHub
- googleads/googleads-mobile-unity · GitHub
- Dependency caching reference · GitHub Docs
- actions/cache · GitHub