Mi propio pipeline local para publicar .NET MAUI iOS en TestFlight
En este post explico cómo monté un pequeño pipeline local para publicar una app .NET MAUI iOS en TestFlight sin depender de un servicio externo de CI.
La idea final fue:
Visual Studio en Windows
-> ejecuta una External Tool
-> conecta por SSH al Mac mini
-> el Mac compila la app iOS
-> genera la IPA
-> sube la IPA a TestFlight
1. Separar el repositorio de los secretos
El primer aprendizaje importante fue no mezclar el repositorio Git con los secretos ni con scripts locales que necesitan permisos de ejecución.
Por ejemplo, podemos tener el repositorio en:
/Users/usuario/Builds/MiApp.Mobile
Y el pipeline local en una carpeta independiente:
/Users/usuario/LocalMagic
Creamos la estructura:
mkdir -p /Users/usuario/LocalMagic/secrets
mkdir -p /Users/usuario/LocalMagic/logs
2. Preparar los archivos necesarios
En la carpeta de secretos coloqué los siguientes archivos:
ios_distribution.p12
AuthKey_XXXXXXXXXX.p8
AppStore_Profile.mobileprovision
local-secrets.env
El archivo .p12 se exporta desde Acceso a Llaveros en el Mac, seleccionando el certificado de distribución de Apple junto con su clave privada.
El provisioning profile puede localizarse con este comando:
for f in ~/Library/MobileDevice/Provisioning\ Profiles/*.mobileprovision; do
echo "----"
echo "$f"
security cms -D -i "$f" | plutil -extract Name raw -
done
Después se copia el profile correcto:
cp "/Users/usuario/Library/MobileDevice/Provisioning Profiles/PROFILE_UUID.mobileprovision" \
/Users/usuario/LocalMagic/secrets/AppStore_Profile.mobileprovision
3. Crear el archivo de configuración local
Creamos el archivo:
nano /Users/usuario/LocalMagic/secrets/local-secrets.env
Con este contenido:
P12_PASSWORD="PASSWORD_DEL_P12"
APP_STORE_CONNECT_API_KEY_ID="XXXXXXXXXX"
APP_STORE_CONNECT_API_ISSUER_ID="xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
Este archivo contiene secretos y no debe subirse nunca al repositorio.
4. Crear el script local del Mac
Después creamos el script principal:
nano /Users/usuario/LocalMagic/build-ios-local.sh
Este script realiza el pipeline completo:
crear un keychain temporal
importar el certificado .p12
instalar el provisioning profile
hacer git pull
leer el build number desde Info.plist
compilar la IPA
subir la IPA a TestFlight
eliminar el keychain temporal
Después le damos permisos:
chmod +x /Users/usuario/LocalMagic/build-ios-local.sh
Y lo probamos directamente en el Mac:
/Users/usuario/LocalMagic/build-ios-local.sh
Si todo va bien, al final veremos un mensaje parecido a:
UPLOAD SUCCEEDED with no errors
5. Crear el script PowerShell en Windows
En el repositorio añadí un script PowerShell:
build/Publish-iOS-TestFlight.ps1
Su función es lanzar el script remoto del Mac por SSH:
$MacUser = "usuario"
$MacHost = "192.168.1.100"
$RemoteScript = "/Users/usuario/LocalMagic/build-ios-local.sh"
ssh -tt "$MacUser@$MacHost" "$RemoteScript"
También añadí guardado de logs y una pausa final para que la ventana no se cierre automáticamente.
6. Añadirlo como External Tool en Visual Studio
En Visual Studio abrimos:
Tools > External Tools...
Y añadimos una nueva herramienta con esta configuración:
Title:
Publish iOS TestFlight
Command:
powershell.exe
Arguments:
-ExecutionPolicy Bypass -File "$(SolutionDir)build\Publish-iOS-TestFlight.ps1"
Initial directory:
$(SolutionDir)
Con esto queda disponible desde el menú Tools de Visual Studio.
7. Ejecutar la publicación
El flujo final queda así:
Visual Studio
-> Tools
-> Publish iOS TestFlight
-> pide password SSH
-> ejecuta el script en el Mac
-> compila
-> sube a TestFlight
En mi caso mantuve la password SSH como una confirmación manual para evitar publicaciones accidentales.
Conclusión
El resultado es un pequeño pipeline local para publicar una app iOS desde Visual Studio usando un Mac mini.
Las principales ventajas son:
- No depende de colas externas.
- Usa un Mac propio.
- Los secretos quedan fuera del repositorio.
- Se lanza desde Visual Studio.
- Muestra logs en directo.
- Sube automáticamente a TestFlight.
El punto clave fue separar claramente las responsabilidades:
Repositorio Git: código fuente
Carpeta local del Mac: scripts y secretos
Visual Studio: botón de lanzamiento

Comentarios
Publicar un comentario