Saltarse al contenido principal
CI/CD

Construcción automática de Capacitor IOS con GitHub acciones utilizando match

Cómo configurar una pipeline de CI/CD para tu aplicación IOS Ionic utilizando fastlane y GitHub Acciones en 5 minutos (2022)

Martin Donadieu

Martin Donadieu

Gerente de Contenido

Construcción automática de Capacitor IOS con GitHub acciones utilizando match

Construcciones automáticas de iOS con GitHub Acciones utilizando Match

Configurar CI/CD para aplicaciones Capacitor puede ser complejo y tiempo consumidor. Aquí lo que necesitas saber:

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.

Requisitos previos

Antes de empezar, necesitarás configurar:

  • Una cuenta de GitHub con acceso administrativo
  • Miembro del programa de desarrolladores de iOS
  • Acceso a API de App Store Connect con permisos adecuados
  • Conocimiento de flujos de trabajo de GitHub Actions
  • Conocimiento de la configuración de Fastlane y Match
  • Tiempo para mantener y depurar la pipeline
  • Un equipo de muchos devs, de lo contrario recomendamos utilizar fastlane cert para flujos de trabajo más simples

Configuración de CI/CD Profesional por Capgo

Saltate la complejidad. Capgo configura directamente tu pipeline de CI/CD en tu plataforma preferida:

  • Independencia de Plataforma: Funciona con GitHub Actions, GitLab CI u otros
  • Integración Sin Problemas: No es necesario cambiar de plataforma, funciona con tu proceso actual
  • Configuración Personalizada: Configuración personalizada que se adapta a las necesidades de tu proyecto
  • Asesoramiento Experto: Ya hemos configurado CI/CD para 50+ aplicaciones

Precios

  • Tarifa de configuración única: $2,600
  • Sus costos de ejecución: ~$300/año
  • Comparar con Otra solución propietaria: $6,000/año
  • Ahorre $26,100 en 5 años

Configurar CI/CD Ahora

Guía de Configuración Manual

Si todavía quiere configurar todo usted mismo, aquí está lo que necesita hacer:

Entrega Continua para iOS utilizando Fastlane y GitHub Acciones utilizando match

Requisitos previos

Antes de continuar con el tutorial…

  • Asegúrate de tener Fastlane instalado 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 para flujos de trabajo más simples.

Importante sobre el precio

Precio GitHub Action

https://github.com/features/actions

El servicio es ‘gratuito’ hasta la cantidad 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 será copiado por Fastlane!

📣 ¡Vamos a sumergirnos!

Pasos a seguir en el post

Usando App Store Connect __CAPGO_KEEP_0__ con Fastlane Match

  1. Using App Store Connect API with Fastlane Match
  2. Crear una llave de App Store Connect __CAPGO_KEEP_0__
  3. Usar una llave de App Store Connect API
  4. Usar App Store Connect API con Fastlane Match
  5. Copiar archivos de Fastlane
  6. Configurar Fastlane match
  7. 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 solo usted 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.

  1. Identificador del emisor.
  2. Identificador de la clave.
  3. Archivo de clave o contenido de la 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.

Acceso del usuario de App Store Connect

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

Integración de App Store Connect API

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

Las llaves de App Store Connect API crean

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

Las llaves de App Store Connect API crear nombre

6 — En 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 en 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.

El nombre de la nueva llave, el ID de la llave, un enlace de descarga y otra información aparecen en la página.

Descargar llaves de App Store Connect

You pueden obtener toda la información necesaria aquí.
<1> Identificador de la cuestión.
<2> Identificador de la clave.
<3> Haga clic en "Descargar API Clave" para descargar su 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 puede descargarla una vez.

🔴 Almacene su clave privada en un lugar seguro. Nunca debe compartir sus claves, almacene claves en un code repositorio o incluya claves en el lado del cliente code.

Usando una Clave de API de App Store Connect

El archivo de la Clave de API (archivo p8 que descargó), 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 pedazos de información pueden ser ingresados en Fastlane utilizando la nueva acción de Fastlane. app_store_connect_api_key. Puede 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 puede establecer variables de entorno.

Ahora podemos gestionar Fastlane con la clave de API de App Store Connect, ¡genial!

2. Copie los archivos de Fastlane

Fastlane es una biblioteca de Ruby creada para automatizar tareas comunes de desarrollo móvil. Utilizando Fastlane, puede 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

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"])

que agrupan una serie de

acciones que realizan tareas que normalmente realizaría utilizando Android Studio. Puede hacer mucho con Fastlane, pero para los propósitos de este tutorial, utilizaremos solo una pequeña cantidad de acciones básicas. 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.

Appfile certificates, for example on your GitHub personal account or organization.

Fastlane

fastlane match init

match

[01:00:00]: fastlane match supports multiple storage modes, please select the one you want to use:1. git2. google_cloud3. s3?

es un nuevo enfoque para la firma de iOS. Fastlane match facilita a los equipos la gestión de los certificados y perfiles de configuración necesarios para sus aplicaciones de iOS.

[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 de Fastlane un archivo llamado Matchfile y 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. _git_url_A continuación, vamos a generar los certificados y se te pedirá que ingreses tus credenciales cuando se te pregunte con Fastlane Match.

# ios/Matchfilegit_url("https://github.com/gitusername/certificates")storage_mode("git")type("appstore")

Te será solicitado 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.

You will be prompted to enter a passphrase. Remember it correctly because it will be used later by GitHub Actions to decrypt your certificates repository.

fastlane match appstore

Si experimentaste algún problema con __CAPGO_KEEP_0__ y los permisos necesarios, tal vez esta

[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 te ayudará a generar tokens de autenticación para Git. Los certificados y los perfiles de configuración generados se suben al repositorio de recursos de certificados

App Store Connect certificates

resources

Finalmente, abra su project en Xcode, y actualice el perfil de provisión para la configuración de lanzamiento de su aplicación.

certificados de XCode

Algunas cosas 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 usarse antes) que tenga el alcance para acceder o leer repositorios privados.

En GitHub, vaya a ConfiguraciónConfiguración de desarrolladorTokens de acceso personal → haga clic Generate New Token → marque la casilla repo scope → luego haz clic Generate token.

Crear token de acceso personal

Ten 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 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__ Secretos, en lugar de codificarlos en el archivo.

In GitHub Actions, En __CAPGO_KEEP_0__ Acciones, 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. Para proyectos privados, el costo estimado por compilación puede llegar a$0.08/min x 15 mins = $1.2

Si compartes las mismas preocupaciones por el precio que yo tengo para proyectos privados, puedes mantener el skip_waiting_for_build_processing a true.

¿Qué hay de por medio? Tienes que actualizar manualmente la conformidad de tu aplicación en App Store Connect después de que se haya procesado la compilación, para poder distribuir la compilación a tus usuarios.

Esto 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 alguna vez de dónde provienen los valores de los ENV ? Bueno, ya no es un secreto – provienen de tu proyecto secreto. 🤦

Establece GitHub secretos

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 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 perteneces a múltiples 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 contraseña que asignaste cuando iniciaste match, se utilizará para descifrar los certificados y perfiles de configuració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 un clon de llaves temporal para tu flujo de trabajo.

10. APPLE_KEY_ID — Conecta de la Tienda de Macos API Clave 🔺Clave de Identificador.

11. APPLE_ISSUER_ID — Conecta de la Tienda de Macos API Clave 🔺Identificador de Emisor.

12. APPLE_KEY_CONTENT — Conecta de la Tienda de Macos API Clave 🔺 Archivo de Clave o Contenido de la Clave de .p8, revisa esto

13. CERTIFICATE_STORE_URL — La URL del repositorio de tus Claves de Coincidencia (por ejemplo, https://github.com/***/fastlane_match.git)

4. Configura el archivo de flujo de trabajo de GitHub

Crea un directorio de flujo de trabajo de GitHub

cd .github/workflows

Dentro del workflow carpeta, crea un archivo llamado build-upload-ios.ymly agrega 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 debería ser desencadenado después de cada GitHub etiquetaSi necesita automatizar etiquetas, consulte Construcción y lanzamiento automático con GitHub acciones primero.

Luego, este flujo de trabajo extraerá sus dependencias NodeJS, las instalará y construirá su aplicación de JavaScript.

Cada vez que envíe un nuevo commit, se construirá una versión de prueba en TestFlight.

Su 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. Desencadenar 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.

Iniciado con commit

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

Panel de control de Testflight

¿Puedo desplegar desde la máquina local?

Sí, puedes, y es sencillo.

Imagina que tienes un repositorio privado, y has agotado los minutos del plan gratuito y no quieres pagar por nuevos lanzamientos, o tal vez prefieres enviar la aplicación manualmente.

Vamos a hacerlo

Ok, primero debemos crear en mi_proyecto_path/fastlane ruta un archivo llamado .env, simplemente en la misma ruta que Fastfile, para poder crear las mismas propiedades de secreto encontradas en nuestro ___CAPGO_KEEP_0__, a continuación: properties found in our _GitHub, a_s below:

Ahora, puedes ir al

terminal para poder crear el mismo entorno de desarrollo y lanzar el Fastlane desde tu máquina:

fastlane closed_beta

❌ Esencial 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 local de Fastlane

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, canal beta. 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 Encuentra el menú de dispositivo iOS Luego copia tu identificador Encuentra el identificador iOS fastlane register_new_device Y luego inicia el comando: Te pedirá que establezcas un nombre de dispositivo y el identificador:

Si tienes problemas con el dispositivo de desarrollo, no puedes probar, etc. que suele solucionarlo.

martin@__CAPGO_KEEP_0__.app

Hay una mágica comandos que puede salvar a usted:

fastlane match nuke development
fastlane match development

Luego: Limpia el proyecto manteniendo Shift(⇧)+Command(⌘)+K o seleccionando Product > Limpia (puede estar etiquetado como “Limpia Carpeta de Compilación”)

Luego intenta ejecutar de nuevo la aplicación en tu dispositivo.

Gracias

Este blog se basa en los siguientes artículos:

Actualizaciones en vivo para aplicaciones Capacitor

Cuando haya un error en la capa web, envía la corrección a través de Capgo en lugar de esperar días a la aprobación de la tienda. Los usuarios reciben la actualización en segundo plano mientras los cambios nativos siguen en el camino de revisión normal.

Comienza ahora

Últimas noticias de nuestro Blog

Capgo te da las mejores pistas que necesitas para crear una aplicación móvil verdaderamente profesional.