Compilaciones automáticas de iOS con GitHub Actions utilizando Match
Configurar CI/CD para aplicaciones Capacitor puede ser complejo y tiempo consumidor. Aquí está lo que debes saber:
Recomendado para Nuevas Compilaciones: Utilizar Capgo Build
Ahora recomendamos utilizar Capgo Construye con el Capgo CLI para compilaciones nativas de Capacitor. Esta guía de Fastlane Match se mantiene para equipos que mantienen pipelines de acciones existentes de GitHub, pero los nuevos builds 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 Construye para CI/CD por Capgo
Saltate la mantenimiento de Fastlane Match, ejecutor de Xcode, certificado, perfil de provisión y script de carga. Capgo Construye ejecuta compilaciones nativas firmadas de iOS desde tu pipeline de CI/CD existente:
- Funciona con tu pipeline: Desencadena Capgo Construye desde acciones de GitHub, CI de GitLab, Jenkins o scripts locales después de tu build web y
npx cap sync. - Firma desde secretos de CI: Mantén las claves de App Store Connect, certificados, perfiles de provisión, contraseñas y IDs de equipo en tus propios secretos de CI.
- No hay mantenimiento de ejecutor nativo: Capgo Build proporciona entornos de compilación mantenidos de Apple, por lo que no tiene que gestionar ejecutores de macOS, imágenes de Xcode, Fastlane o repositorios de Match.
- Artículos y presentación: Descargar artefactos firmados para QA o presentar compilaciones de lanzamiento a través del Capgo CLI.
Precios
- Capgo planes comienzan en $12/mes
- Incluye actualizaciones OTA y aproximadamente 15 compilaciones nativas por mes
- Los minutos adicionales de compilación se facturan por minuto a través de créditos
Configura Capgo Build en CI/CD
Guía de configuración manual
Aquí está lo que necesita hacer:
Distribución continua para iOS utilizando Fastlane y GitHub Acciones utilizando match
Requisitos previos
Antes de continuar con el tutorial…
- Asegúrese de tener instalado Fastlane en su 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 para flujos de trabajo más simples. Importante sobre el precio
Precio __CAPGO_KEEP_0__ Action

https://github.com/features/actions
El servicio es ‘gratuito’ hasta el límite, dependiendo de la máquina elegida.
Vamos a utilizar una máquina de macOS, puedes ver en la captura 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 de Apple, todo se copiará con Fastlane!
📣 ¡Vamos a sumergirnos!
Pasos a seguir en el post
Usando App Store Connect __CAPGO_KEEP_0__ con Fastlane Match
- Using App Store Connect API with Fastlane Match
- Creando una llave de App Store Connect __CAPGO_KEEP_0__
- Usando una llave de App Store Connect API
- Usando App Store Connect API con Fastlane Match
- Copiar archivos de Fastlane
- Configurar Fastlane match
1. Usar 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 usted es la única persona que puede acceder a su cuenta.
Desde Soporte de Apple
Para empezar con match se requiere revocar los certificados existentes. Pero no se preocupe, tendrá el nuevo directamente.
Requisitos
Para poder usar App Store Connect API, Fastlane necesita tres cosas.
- ID. del emisor
- ID 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 instrucciones siguientes.
1 — Iniciar sesión en App Store Connect.
2 — Seleccionar Usuarios y Acceso.

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

4 — Haga clic en Generar clave de API o en el botón (+) de agregar.

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

6 — Debajo de Acceso, selecciona el rol para la llave. Los roles que se aplican a las llaves 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.
La accesibilidad de una llave API no puede limitarse a aplicaciones específicas.
La información del nombre de la nueva llave, el ID de la llave, un enlace de descarga y otros detalles aparecen en la página.

Puedes obtener aquí toda la información necesaria.
<1> Identificador de la cuestión.
<2> Identificador de la clave.
<3> Haz clic en “Descargar API Clave” para descargar tu API clave privada. 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 code repositorio o incluir claves en el lado del cliente code.
Usando una Clave de API de App Store Connect
El archivo de Clave de API (archivo p8 que descargas), el identificador de la clave y el identificador del emisor son necesarios para crear el token JWT de autorización. Hay varias formas en que estos elementos de información pueden ser ingresados en Fastlane utilizando la nueva acción de Fastlane. app_store_connect_api_key. Puedes 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 en la que 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 “corredores” personalizados que agrupan una serie de “acciones” que realizan tareas que normalmente realizarías utilizando Android Studio. Puedes hacer mucho con Fastlane, pero para los propósitos de este tutorial, solo utilizaremos una docena de acciones básicas.
Crea un carpeta de Fastlane en la raíz de tu proyecto y copia los siguientes archivos: Fastfile
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
Appfile
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"])
Configura Fastlane match
Fastlane match es una nueva aproximación al code de firmado de iOS. Fastlane match facilita a los equipos la gestión de los certificados y perfiles de configuración necesarios para tus aplicaciones de iOS.
Crea un repositorio privado llamado certificates, por ejemplo, en tu GitHub cuenta personal o organización.
Inicia Fastlane match para tu aplicación de iOS.
fastlane match init
Luego selecciona 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?
Asigna la URL del repositorio recién creado.
[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 tienes dentro de la carpeta Fastlane un archivo llamado El archivo Matchfile debe estar configurado con la URL HTTPS del repositorio de certificados. De manera opcional, también puedes utilizar SSH, pero requiere un paso diferente para ejecutar. A continuación, vamos a generar los certificados y se te pedirá que ingreses tus credenciales cuando se te pregunte con Fastlane Match.
_git_url_Te pedirán que ingreses una contraseña. Recuerda correctamente porque se utilizará más tarde por las acciones de __CAPGO_KEEP_0__ para descifrar tu repositorio de certificados.
# ios/Matchfilegit_url("https://github.com/gitusername/certificates")storage_mode("git")type("appstore")
Si todo salió bien, deberías ver algo así:
Si experimentaste algún problema con GitHub y los permisos necesarios, tal vez esta
fastlane match appstore
publicación
[01:40:52]: All required keys, certificates and provisioning profiles are installed 🙌
If you experienced any problem with GitHub and the necessary permissions, maybe this Los certificados y los perfiles de provisión generados se suben a los recursos del repositorio de certificados Certificados de App Store Connect
Finalmente, abre tu

will project In Xcode, actualice el perfil de provisión para la configuración de lanzamiento de su aplicación.

Pocos detalles a tener en cuenta 💡
MATCH
Para que la CI/CD importe los certificados y perfiles de provisión, necesita tener acceso al repositorio de certificados. Puede hacer esto generando un token de acceso personal (que debe haber utilizado antes) que tenga el alcance para acceder o leer repositorios privados.
In GitHub, vaya a Ajustes → Configuración de desarrollador → Tokens de acceso personal → haga clic Generate New Token → marque con un signo de verificación repo scope → luego haga clic Generate token.

Tener una copia del token de acceso personal generado. Lo utilizarás más tarde para la variable de entorno GIT_TOKEN.
Luego reemplaza tu archivo de match generado en la carpeta 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 las Acciones de __CAPGO_KEEP_0__ se facturan 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 se pueda procesar una construcción en App Store Connect. Para proyectos privados, el costo estimado por construcción puede llegar a$0,08/min x 15 min = $1,2
, o más, dependiendo de la configuración o dependencias de tu proyecto. skip_waiting_for_build_processing ¿Cuál es el truco? true.
¿Qué hay detrás de esto? Tienes que actualizar manualmente la conformidad de tu aplicación en App Store Connect después de que se ha procesado la compilación, para poder distribuir la compilación a tus usuarios.
Este es solo un parámetro opcional para actualizar si quieres ahorrar minutos de compilació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 de dónde vienen los valores de los ENV ¿De dónde salen los valores de los

1. APP_STORE_CONNECT_TEAM_ID Establece __CAPGO_KEEP_0__ secretos
2. DEVELOPER_APP_ID - el ID de tu equipo de App Store Connect si estás en múltiples equipos. - en App Store Connect, ve a la aplicación → → Desplázate hacia abajo hasta la General Information sección 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 del equipo de tu portal de desarrolladores si eres parte de varios equipos.
5. FASTLANE_APPLE_ID - el ID de Apple o correo electrónico de desarrollador que utilizas para administrar la aplicación.
6. GIT_USERNAME & GIT_TOKEN - Tu nombre de usuario de Git y tu token de acceso personal.
7. MATCH_PASSWORD - la frase de contraseña que asignaste cuando iniciaste match, se utilizará para descifrar los certificados y perfiles de provisió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 de keychain temporal para tu flujo de trabajo.
10. APPLE_KEY_ID — Conecta a App Store Connect API Clave 🔺ID de clave.
11. APPLE_ISSUER_ID — Conectar con App Store API Key 🔺 Identificador de emisor.
12. APPLE_KEY_CONTENT — Conectar con App Store API Key 🔺 Archivo de clave o contenido de la .p8, revisarlo
13. CERTIFICATE_STORE_URL — La URL del repositorio de sus claves de Match (por ejemplo, https://github.com/***/fastlane_match.git)
4. Configurar el archivo de flujo de trabajo de GitHub
Crear un directorio de flujo de trabajo de GitHub.
cd .github/workflows
Dentro del workflow carpeta, cree un archivo llamado build-upload-ios.ymly agregue lo siguiente.
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
Este flujo de trabajo debe ser desencadenado después de cada GitHub etiqueta, si necesitas automatizar la etiqueta, consulta Compilación y lanzamiento automático con GitHub acciones primero.
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 obligatorio el Capacitor base, puede tener módulos de Cordova antiguos, pero se recomienda utilizar el Capacitor plugin de JavaScript.
5. Activar 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
Pushe 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 de la plan gratuita y no quieres pagar por nuevos lanzamientos, o tal vez prefieres enviar la aplicación manualmente.
Vamos a ello
Ok, primero necesitamos crear en mi_proyecto_path/fastlane ruta de un archivo llamado .env, justo en el mismo path que Fastfile, para poder crear el mismo secreto propiedades encontradas en nuestro _GitHub, a_s a continuación:
archivo .env para desplegar desde la máquina local
Ahora, puedes ir al terminal y lanzar el Fastlane desde tu máquina:
fastlane closed_beta
❌ Es importante sobre el .env archivo, 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 de lanzamiento en el console de Google Play, canal beta. Me mejoraré este blog con tus retroalimentaciones, si tienes alguna pregunta o sugerencia, por favor házmelo saber por correo electrónico martin@capgo.app
Construye en tu dispositivo
Si todavía necesitas construir en tu dispositivo, debes agregarlos manualmente a la configuración de provisionamiento.
Conecta tu dispositivo a tu Mac y abre el menú de dispositivo
Luego copia tu identificador
Y luego inicia el comando:
fastlane register_new_device
Te pedirá que establezcas un nombre de dispositivo y el identificador:

Si tienes problemas
Si tienes problemas con el dispositivo de desarrollo que no puedes probar, etc. que suele solucionarlo.
Hay un comando mágico que puede salvarte:
fastlane match nuke development
fastlane match development
Luego: Limpia el proyecto manteniendo Shift(⇧)+Command(⌘)+K o seleccionando Product > Limpia (podría estar etiquetado como “Limpia Carpeta de Compilación”)
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 acciones de GitHub
- Documentación de Fastlane
- Este mensaje de GitHub 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 el detalle de implementación en Integración de CI/CD, y GitHub Integración de Acciones for the implementation detail in GitHub Actions Integration.