Compilaciones de iOS automáticas con GitHub Acciones utilizando Match
Configurar CI/CD para aplicaciones Capacitor puede ser complejo y tiempo consumidor. Aquí está lo que necesitas saber:
Recomendado para Nuevas Compilaciones: Utilice Capgo Compilación
Ahora recomendamos utilizar Capgo Compilación con el Capgo CLI para compilaciones nativas Capacitor. Esta guía de Fastlane Match se mantiene para equipos que mantienen existentes pipelines de Acciones GitHub, pero nuevos compilados de iOS deben utilizar el Capgo CLI para que no tengas que mantener repositorios de Fastlane, Match, ejecutores de Xcode, certificados y scripts de carga.
Capgo Compilación para CI/CD por Capgo
Saltarse la configuración de Fastlane Match, ejecutor de Xcode, certificado, perfil de provisión y script de carga. Capgo Compilación ejecuta compilaciones nativas de iOS firmadas desde tu pipeline de CI/CD existente:
- Funciona con tu pipeline: Desencadena Capgo Construcción desde GitHub Acciones, GitLab CI, Jenkins o scripts locales después de tu compilación web y
npx cap sync. - Autenticación desde secretos de CI: Mantén las llaves de App Store Connect, certificados, perfiles de configuración, contraseñas y IDs de equipo en tus propios secretos de CI.
- No mantenimiento de ejecutor nativo: Capgo Construcción proporciona entornos de compilación Apple mantenidos, por lo que no tienes que administrar ejecutores de macOS, imágenes de Xcode, Fastlane o repositorios de Match.
- Artículos y presentación: Descarga artículos firmados para QA o envía compilaciones de lanzamiento a través del Capgo CLI.
Tarifas
- Los planes de Capgo comienzan en $12/mes
- Incluye actualizaciones OTA y aproximadamente 15 compilaciones nativas por mes
- Los minutos de compilación adicionales se facturan por minuto a través de créditos
Configura Capgo Construcción en CI/CD
Guía de Configuración Manual
Esto es lo que debes hacer:
Entrega Continua para iOS utilizando Fastlane y GitHub Acciones utilizando match
Requisitos previos
Antes de continuar con el tutorial…
- Asegúrate de tener instalado Fastlane en tu máquina de desarrollo. Miembro del programa de desarrolladores de iOS.
- Deseo de leer 😆…
- Un equipo de muchos devs, en caso contrario recomendamos utilizar
- fastlane cert fastlane cert para flujos de trabajo más simples.
Importante sobre el precio

https://github.com/features/actions
El servicio es ‘gratuito’ hasta la limitación, dependiendo de la máquina elegida.
Vamos a utilizar un máquina macOS, puedes ver en la captura de pantalla su precio y límites (precios a la creación del tutorial, podrían sufrir cambios en el futuro) Una vez advertidos de los requisitos y precios, si te gusta, continuamos…
🔴 En el post asumimos que tenemos la aplicación creada en iTunes connect, sí tenemos los certificados del ecosistema Apple, todo será copiado por Fastlane!
📣 ¡Vamos a sumergirnos!
Pasos a seguir en el post
¡Vamos a sumergirnos!
- Usando App Store Connect API con Fastlane Match
- Requisitos
- Crear una clave de App Store Connect API
- Usando una clave de App Store Connect API
- Copiar archivos de Fastlane
- Configurar Fastlane match
1. Usando App Store Connect API con Fastlane Match
A partir de febrero de 2021, se requiere autenticación en dos factores o verificación en dos pasos para todos los usuarios para iniciar sesión en App Store Connect. Esta capa adicional de seguridad para su ID de Apple ayuda a asegurarse de que solo usted puede acceder a su cuenta.
Desde Soporte de Apple
Para empezar con match, es necesario revocar sus certificados existentes. Pero no se preocupe, tendrá el nuevo directamente.
Requisitos
To poder usar App Store Connect API, Fastlane necesita tres cosas.
- Identificador de emisor.
- Identificador de clave.
- Archivo de clave o contenido de clave.
Crear una clave de App Store Connect API
Para generar claves, debe tener permiso de Administrador en App Store Connect. Si no tiene ese permiso, puede dirigir a la persona relevante a este artículo y seguir las siguientes instrucciones.
1 — Iniciar sesión en App Store Connect.
2 — Seleccionar Usuarios y Acceso.

3 — Selecciona la pestaña de Integración.

4 — Haz clic en Generar API clave o en el botón Agregar (+).

5 — Ingresa un nombre para la clave. El nombre es solo para tu referencia y no forma parte de la clave en sí.

6 — En Acceso, selecciona el rol para la clave. Los roles que se aplican a las claves son los mismos roles que se aplican a los usuarios de tu equipo. Consulta permisos de rol. Recomendamos seleccionar Administrador de aplicaciones.
7 — Haz clic en Generar.
Una clave de API no puede tener acceso limitado a aplicaciones específicas.
El nombre de la nueva clave, el ID de la clave, un enlace de descarga y otra información aparecen en la página.

Puedes obtener aquí la información necesaria.
<1> ID de la cuestión.
<2> ID de la clave.
<3> Haga clic en "Descargar clave de API" para descargar tu clave privada de API. El enlace de descarga aparece solo si la clave privada no se ha descargado aún. Apple no almacena una copia de la clave privada. Por lo tanto, solo puedes descargarla una vez.
🔴 Almacena tu clave privada en un lugar seguro. Nunca debes compartir tus claves, almacenar claves en un repositorio de code o incluir claves en el lado del cliente code.
Usar una clave de API de App Store Connect
El archivo de la clave de API (p8 que descargas), el ID de la clave y el ID del emisor son necesarios para crear el token JWT de autorización. Hay varias formas en que estos pedazos de información pueden ser ingresados en Fastlane utilizando la nueva acción de Fastlane. app_store_connect_api_keyPuedes aprender otras formas en Documentación de Fastlane. Muestro este método porque creo que es la forma más fácil de trabajar con la mayoría de las CI allí, donde puedes establecer variables de entorno.
Ahora podemos gestionar Fastlane con la clave de App Store Connect API, ¡genial!
2. Copiar archivos de Fastlane
Fastlane es una biblioteca de Ruby creada para automatizar tareas de desarrollo móvil comunes. Al utilizar Fastlane, puedes configurar
lanes
default_platform(:ios)
DEVELOPER_APP_IDENTIFIER = ENV["DEVELOPER_APP_IDENTIFIER"]
DEVELOPER_APP_ID = ENV["DEVELOPER_APP_ID"]
PROVISIONING_PROFILE_SPECIFIER = ENV["PROVISIONING_PROFILE_SPECIFIER"]
TEMP_KEYCHAIN_USER = ENV["TEMP_KEYCHAIN_USER"]
TEMP_KEYCHAIN_PASSWORD = ENV["TEMP_KEYCHAIN_PASSWORD"]
APPLE_ISSUER_ID = ENV["APPLE_ISSUER_ID"]
APPLE_KEY_ID = ENV["APPLE_KEY_ID"]
APPLE_KEY_CONTENT = ENV["APPLE_KEY_CONTENT"]
GIT_USERNAME = ENV["GIT_USERNAME"]
GIT_TOKEN = ENV["GIT_TOKEN"]
def delete_temp_keychain(name)
delete_keychain(
name: name
) if File.exist? File.expand_path("~/Library/Keychains/#{name}-db")
end
def create_temp_keychain(name, password)
create_keychain(
name: name,
password: password,
unlock: false,
timeout: 0
)
end
def ensure_temp_keychain(name, password)
delete_temp_keychain(name)
create_temp_keychain(name, password)
end
platform :ios do
lane :build do
build_app(
configuration: "Release",
workspace: "./ios/App/App.xcworkspace",
scheme: "App",
export_method: "app-store",
export_options: {
provisioningProfiles: {
DEVELOPER_APP_ID => "#{PROVISIONING_PROFILE_SPECIFIER}"
}
}
)
end
lane :refresh_profiles do
match(
type: "development",
force: true)
match(
type: "adhoc",
force: true)
end
desc "Register new device"
lane :register_new_device do |options|
device_name = prompt(text: "Enter the device name: ")
device_udid = prompt(text: "Enter the device UDID: ")
device_hash = {}
device_hash[device_name] = device_udid
register_devices(
devices: device_hash
)
refresh_profiles
end
lane :closed_beta do
keychain_name = TEMP_KEYCHAIN_USER
keychain_password = TEMP_KEYCHAIN_PASSWORD
ensure_temp_keychain(keychain_name, keychain_password)
api_key = app_store_connect_api_key(
key_id: APPLE_KEY_ID,
issuer_id: APPLE_ISSUER_ID,
key_content: APPLE_KEY_CONTENT,
duration: 1200,
in_house: false
)
match(
type: 'appstore',
git_basic_authorization: Base64.strict_encode64("#{GIT_USERNAME}:#{GIT_TOKEN}"),
readonly: true,
keychain_name: keychain_name,
keychain_password: keychain_password,
api_key: api_key
)
gym(
configuration: "Release",
workspace: "./ios/App/App.xcworkspace",
scheme: "App",
export_method: "app-store",
export_options: {
provisioningProfiles: {
DEVELOPER_APP_ID => "#{PROVISIONING_PROFILE_SPECIFIER}"
}
}
)
pilot(
apple_id: "#{DEVELOPER_APP_ID}",
app_identifier: "#{DEVELOPER_APP_IDENTIFIER}",
skip_waiting_for_build_processing: true,
skip_submission: true,
distribute_external: false,
notify_external_testers: false,
ipa: "./App.ipa"
)
delete_temp_keychain(keychain_name)
end
lane :submit_review do
version = ''
Dir.chdir("..") do
file = File.read("package.json")
data = JSON.parse(file)
version = data["version"]
end
deliver(
app_version: version,
submit_for_review: true,
automatic_release: true,
force: true, # Skip HTMl report verification
skip_metadata: false,
skip_screenshots: false,
skip_binary_upload: true
)
end
end
personalizados que agrupan una serie de
app_identifier(ENV["DEVELOPER_APP_IDENTIFIER"])
apple_id(ENV["FASTLANE_APPLE_ID"])
itc_team_id(ENV["APP_STORE_CONNECT_TEAM_ID"])
team_id(ENV["DEVELOPER_PORTAL_TEAM_ID"])
acciones
que realizan tareas que normalmente realizarías utilizando Android Studio. Puedes hacer mucho con Fastlane, pero para los propósitos de este tutorial, utilizaremos solo una pequeña cantidad de acciones básicas. Crea un carpeta de Fastlane en la raíz de tu proyecto y copia los siguientes archivos: Fastfile is a new approach to iOS’s code signing. Fastlane match makes it easy for teams to manage the required certificates and provisioning profiles for your iOS apps.
Configura Fastlane match certificatesFastlane match es una nueva aproximación al firmado de iOS GitHub. Fastlane match facilita a los equipos la gestión de los certificados y perfiles de configuración necesarios para tus aplicaciones de iOS.
Inicialice Fastlane match para su aplicación iOS.
fastlane match init
Luego seleccione la opción #1 (Almacenamiento Git).
[01:00:00]: fastlane match supports multiple storage modes, please select the one you want to use:1. git2. google_cloud3. s3?
Asigne la URL del repositorio creado recientemente.
[01:00:00]: Please create a new, private git repository to store the certificates and profiles there[01:00:00]: URL of the Git Repo: <YOUR_CERTIFICATES_REPO_URL>
Ahora tiene dentro de la carpeta Fastlane un archivo llamado Matchfile y
_git_url_debe estar configurado con la URL HTTPS del repositorio de certificados. De manera opcional, también puede utilizar SSH, pero requiere un paso diferente para ejecutar.
# ios/Matchfilegit_url("https://github.com/gitusername/certificates")storage_mode("git")type("appstore")
A continuación, vamos a generar los certificados y se le pedirá que ingrese sus credenciales cuando se le pregunte con Fastlane Match.
Se le pedirá que ingrese una contraseña. Recuerde correctamente porque se utilizará más tarde por las Acciones de GitHub para descifrar su repositorio de certificados.
fastlane match appstore
Si todo salió bien, debería ver algo como eso:
[01:40:52]: All required keys, certificates and provisioning profiles are installed 🙌
Si experimentó algún problema con GitHub y las permisos necesarios, tal vez esta publicación Te ayudará a generar tokens de autenticación para Git.
Los certificados y los perfiles de configuración generados se suben a los recursos del repositorio de certificados

Por último, abre tu project en Xcode, y actualiza el perfil de configuración de provisión para la configuración de lanzamiento de tu aplicación.

Pocos detalles a tener en cuenta 💡
MATCH
Para que el CI/CD importe los certificados y los perfiles de configuración, necesita tener acceso al repositorio de certificados. Puedes hacer esto generando un token de acceso personal (que se debe utilizar antes) que tenga el alcance para acceder o leer repositorios privados.
In GitHub, ve a Ajustes → Ajustes de Desarrollador → Tokens de acceso personal → haz clic Generate New Token → marca la casilla repo ámbito → luego haz clic Generate token.

Tienes una copia del token de acceso personal generado. Lo utilizarás más tarde para la variable de entorno GIT_TOKEN.
Luego reemplaza el archivo de coincidencia generado en el folder de Fastlane por Matchfile
CERTIFICATE_STORE_URL = ENV["CERTIFICATE_STORE_URL"]
GIT_USERNAME = ENV["GIT_USERNAME"]
GIT_TOKEN = ENV["GIT_TOKEN"]
FASTLANE_APPLE_ID = ENV["FASTLANE_APPLE_ID"]
git_url(CERTIFICATE_STORE_URL)
storage_mode("git")
type("appstore")
git_basic_authorization(Base64.strict_encode64("#{GIT_USERNAME}:#{GIT_TOKEN}"))
username(FASTLANE_APPLE_ID)
This will be used by GitHub Actions to import the certificates and provisioning profiles. And var will be set in GitHub Secrets, instead of hard-coding them in the file.
Y la variable se establecerá en __CAPGO_KEEP_1__ Secrets, en lugar de codificarlos en el archivo.
In GitHub Actions, En __CAPGO_KEEP_0__ Actions, se te facturará según los minutos que has utilizado para ejecutar tu flujo de trabajo de CI/CD. De la experiencia, lleva aproximadamente 10–15 minutos antes de que una compilación pueda ser procesada en App Store Connect.
For proyectos privados, el costo estimado por construcción puede llegar a $0.08/min x 15 mins = $1.2, o más, dependiendo de la configuración o dependencias de tu proyecto.
Si compartes las mismas preocupaciones por el precio que yo por proyectos privados, puedes mantener el skip_waiting_for_build_processing para true.
¿Cuál es el truco? Tienes que actualizar manualmente la conformidad de tu aplicación en App Store Connect después de que se haya procesado la construcción, para distribuir la construcción a tus usuarios.
Esto es solo un parámetro opcional para actualizar si quieres ahorrar minutos de construcción para proyectos privados. Para proyectos gratuitos, esto no debería ser un problema en absoluto. Consulta precios.
3. Configura GitHub Acciones
Configura GitHub secretos
¿Te has preguntado alguna vez de dónde vienen los valores de los ENV ? Bueno, ya no es un secreto – provienen de la secret de tu proyecto.

1. APP_STORE_CONNECT_TEAM_ID - el ID de tu equipo de App Store Connect si estás en múltiples equipos.
2. DEVELOPER_APP_ID - en App Store Connect, ve a la aplicación → Información de la Aplicación → Desplázate hacia abajo hasta la sección General Information de tu aplicación y busca Apple ID.
3. DEVELOPER_APP_IDENTIFIER - el identificador de paquete de tu aplicación.
4. DEVELOPER_PORTAL_TEAM_ID - el ID de tu equipo de Developer Portal si estás en múltiples equipos.
5. FASTLANE_APPLE_ID - el ID de Apple o correo electrónico del desarrollador que utilizas para gestionar la aplicación.
6. GIT_USERNAME & GIT_TOKEN - tu nombre de usuario de Git y tu token de acceso personal.
7. MATCH_PASSWORD - la passphrase que asignaste cuando iniciaste match, se utilizará para descifrar los certificados y perfiles de configuración de la aplicación.
8. PROVISIONING_PROFILE_SPECIFIER - match AppStore <YOUR_APP_BUNDLE_IDENTIFIER>por ejemplo match AppStore com.domain.blabla.demo.
9. TEMP_KEYCHAIN_USER & TEMP_KEYCHAIN_PASSWORD - asigna un usuario y contraseña temporal para tu flujo de trabajo.
10. APPLE_KEY_ID — App Store Connect API Clave 🔺ID de Clave.
11. APPLE_ISSUER_ID — App Store Connect API Clave 🔺ID de Emisor.
12. APPLE_KEY_CONTENT — App Store Connect API Clave 🔺 Archivo de Clave o contenido de la .p8, revisa
13. CERTIFICATE_STORE_URL — La URL del repositorio de tus claves Match (por ejemplo: https://github.com/***/fastlane_match.git)
4. Configura el archivo de flujo de trabajo GitHub
Crear un directorio de flujo de trabajo GitHub
cd .github/workflows
Dentro de la carpeta, crea un archivo llamado workflow y agrega lo siguiente. build-upload-ios.ymlEste flujo de trabajo debería ser desencadenado después de cada __CAPGO_KEEP_0__
name: Build source code on ios
on:
push:
tags:
- '*'
jobs:
build_ios:
runs-on: macOS-latest
steps:
- uses: actions/checkout@v6
- name: set Node.js
uses: actions/setup-node@v6
with:
node-version: '24'
cache: npm
- name: Install dependencies
id: install_code
run: npm ci
- name: Build
id: build_code
run: npm run build
- uses: actions/cache@v5
with:
path: ios/App/Pods
key: ${{ runner.os }}-pods-${{ hashFiles('**/Podfile.lock') }}
restore-keys: |
${{ runner.os }}-pods-
- name: Sync
id: sync_code
run: npx cap sync
- uses: ruby/setup-ruby@v1
with:
ruby-version: 2.7.2
- uses: maierj/fastlane-action@v2.3.0
env:
DEVELOPER_APP_IDENTIFIER: ${{ secrets.DEVELOPER_APP_IDENTIFIER }}
DEVELOPER_APP_ID: ${{ secrets.DEVELOPER_APP_ID }}
PROVISIONING_PROFILE_SPECIFIER: match AppStore ${{ secrets.DEVELOPER_APP_IDENTIFIER }}
TEMP_KEYCHAIN_USER: ${{ secrets.TEMP_KEYCHAIN_USER }}
TEMP_KEYCHAIN_PASSWORD: ${{ secrets.TEMP_KEYCHAIN_PASSWORD }}
APPLE_ISSUER_ID: ${{ secrets.APPLE_ISSUER_ID }}
APPLE_KEY_ID: ${{ secrets.APPLE_KEY_ID }}
APPLE_KEY_CONTENT: ${{ secrets.APPLE_KEY_CONTENT }}
CERTIFICATE_STORE_URL: https://github.com/${{ secrets.CERTIFICATE_STORE_REPO }}.git
GIT_USERNAME: ${{ secrets.GIT_USERNAME }}
GIT_TOKEN: ${{ secrets.PERSONAL_ACCESS_TOKEN }}
FASTLANE_APPLE_ID: ${{ secrets.FASTLANE_APPLE_ID }}
MATCH_USERNAME: ${{ secrets.FASTLANE_APPLE_ID }}
MATCH_PASSWORD: ${{ secrets.MATCH_PASSWORD }}
APP_STORE_CONNECT_TEAM_ID: ${{ secrets.APP_STORE_CONNECT_TEAM_ID }}
DEVELOPER_PORTAL_TEAM_ID: ${{ secrets.DEVELOPER_PORTAL_TEAM_ID }}
with:
lane: closed_beta
- name: Upload release bundle
uses: actions/upload-artifact@v2
with:
name: ios-release
path: ./App.ipa
retention-days: 60
This workflow should be triggered after each GitHub , si necesitas automatizar etiquetas, por favor, consultaAutomatización de compilación y lanzamiento con __CAPGO_KEEP_0__ acciones Automatic build and release with GitHub actions Luego, este flujo de trabajo extraerá tus dependencias NodeJS, las instalará y construirá tu aplicación de JavaScript.
Cada vez que envíes un nuevo commit, se construirá una versión de prueba en TestFlight.
Tu aplicación no necesita utilizar Ionic, solo es necesario el __CAPGO_KEEP_0__ base, puede tener módulos de Cordova antiguos, pero se recomienda utilizar el plugin de JavaScript __CAPGO_KEEP_1__
Your App doesn’t need to use Ionic, only Capacitor base is mandatory., it can have old Cordova module, but Capacitor JS plugin should be preferred.
5. Disparar flujo de trabajo
Crear un Commit
Hacer un commit,deberías ver el flujo de trabajo activo en el repositorio.
Activar el flujo de trabajo
Pushear los nuevos commits a la rama main o development para activar el flujo de trabajo.

Después de unos minutos, el build debería estar disponible en tu panel de control de App Store Connect.

¿Puedo desplegar desde la máquina local?
Sí, puedes, y es sencillo.
Imagina que tienes un repositorio privado, y has utilizado los minutos del plan gratuito y no quieres pagar por nuevos lanzamientos, o tal vez prefieres enviar la aplicación manualmente.
Vamos por ello
Ok, primero necesitamos crear en mi_proyecto_path/fastlane un archivo llamado .env, justo en el mismo camino que Fastfile, para poder crear las mismas propiedades secretas encontradas en nuestro ___CAPGO_KEEP_0__, a_s a continuación: secret properties found in our _GitHub, a_s below:
.env archivo para desplegar desde la máquina local
Ahora, puedes ir a la terminal y lanzar el Fastlane desde tu máquina:
fastlane closed_beta
❌ Lo esencial sobre el archivo .env , ya que preferimos no exponer esta información, debemos agregarla en nuestro .gitignore, algo así: ❌
fastlane/*.env
Debería funcionar de la misma manera que sucede desde GitHub Acciones en la máquina remota, pero en nuestra máquina local. 🍻

Ejecución en Terminal: $ Fastlane closed_beta
Si has llegado hasta aquí, mi felicitación, ahora tienes un proceso automatizado completo para tus aplicaciones iOS con Fastlane y GitHub Acciones.
Cada vez que envíes un nuevo commit, se construirá una versión en el console de Google Play, en el canal beta. martin@capgo.app
martin@__CAPGO_KEEP_0__.app
Construye en tu dispositivo
Conecta tu dispositivo a tu Mac y abre el menú de dispositivos
Luego copia tu identificador
fastlane register_new_device
Encuentra el identificador de iOS y luego inicia el comando:

Si tienes problemas
Si tienes problemas con el dispositivo de desarrollo que no puedes probar, etc. generalmente se resuelve con eso.
Hay un comando mágico que puede salvarte:
fastlane match nuke development
fastlane match development
Luego: Limpia el proyecto manteniendo presionada la tecla Shift(⇧)+Command(⌘)+K o seleccionando Product > Clean (podría estar etiquetado como “Limpia carpeta de compilación”)
Luego intenta ejecutar la aplicación nuevamente en tu dispositivo.
Gracias
Este blog se basa en los siguientes artículos:
- Entrega continua para IOS utilizando Fastlane y GitHub acciones
- Documentación de Fastlane
- Este GitHub mensaje de @mrogunlana
Keep going from Automatic Capacitor IOS build with GitHub actions using match
Si estás utilizando Automatic Capacitor IOS build with GitHub actions using match para planificar la automatización de CI/CD, conecta con Capgo CI/CD para el flujo de trabajo del producto en Capgo CI/CD, Capgo Compilaciones nativas para el flujo de trabajo del producto en Capgo Compilaciones nativas, Capgo Integraciones para el flujo de trabajo del producto en Capgo Integraciones, Integración de CI/CD para los detalles de implementación en Integración de CI/CD, y GitHub Integración de acciones para los detalles de implementación en GitHub Acciones de Integración.