Saltarse al contenido principal
CI/CD

Construcción automática de IOS con Capacitor y GitHub con certificado

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

Martin Donadieu

Martin Donadieu

Gerente de contenido

Construcción automática de IOS con Capacitor y GitHub con certificado

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

Ahora recomendamos utilizar Capgo Build con el Capgo CLI para construcciones nativas Capacitor. Esta guía de Fastlane se mantiene para equipos que mantienen pipelines de acciones existentes GitHub, pero nuevos builds de iOS deberían utilizar el Capgo CLI para que no tengas que mantener Fastlane, ejecutores de Xcode, certificados y scripts de carga.

Capgo Build para CI/CD por Capgo

Saltate la configuración de Fastlane, ejecutor de Xcode, certificado, perfil de provisión y script de carga. Capgo Build ejecuta construcciones nativas de iOS firmadas desde tu pipeline de CI/CD existente:

  • Funciona con tu pipeline: Disparar Capgo Build desde GitHub Actions, GitLab CI, Jenkins o scripts locales después de tu build web y npx cap sync.
  • Iniciando 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 del ejecutor nativo: Capgo Build proporciona entornos de compilación Apple mantenidos, por lo que no tienes que administrar ejecutores de macOS, imágenes de Xcode o rutas de Fastlane.
  • Artículos y presentación: Descarga artefactos firmados para QA o presenta versiones 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 debes hacer:

Distribución Continua para iOS utilizando Fastlane y GitHub Acciones y certificado

Requisitos previos

Antes de continuar con el tutorial:

  • Asegúrate de tener instalado Fastlane en tu máquina de desarrollo. Asegúrate de ser parte del programa de membresía de desarrollador de iOS.
  • Información importante sobre el precio

Precio __CAPGO_KEEP_0__ Acción

https://GitHub.com/features/actions

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 máquina de 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, continuemos.

Nota: En el post supongo que ya tienes la aplicación creada en App Store Connect. La información importante se copiará con Fastlane!

¿Qué aprenderás en el tutorial?

Pasos a seguir en el post

  1. Usando App Store Connect API con Fastlane
    • Requisitos:
      • Crear una clave de App Store Connect API
      • Usando una clave de App Store Connect API
  2. Copiar archivos de Fastlane
  3. Configurar acciones de GitHub

1. Usando App Store Connect API con Fastlane

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

Requisitos

Para que Fastlane pueda utilizar App Store Connect API para subir su aplicación, necesita proporcionar los siguientes tres cosas:

  1. Identificador del emisor
  2. ID de clave
  3. Archivo de clave o contenido de clave

Obteniendo 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.

  1. Iniciar sesión en App Store Connect.

  2. Seleccionar Usuarios y Acceso.

Acceso de usuario de App Store Connect

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

Integración de App Store Connect API

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

App Store Connect API llaves crean

  1. Ingrese un nombre para la llave. El nombre es solo para su referencia y no forma parte de la llave en sí.

App Store Connect API llaves crean nombre

6 — Debajo de Acceso, seleccione el rol para la llave. Los roles que se aplican a las llaves son los mismos roles que se aplican a los usuarios de su equipo. Consulte permisos de rol. Recomendamos seleccionar Administrador de aplicaciones.

  1. Haga clic en Generar.

El acceso 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

Puede obtener aquí toda la información necesaria.
ID de la cuestión. (APPLE_ISSUER_ID ID de la clave. (
Haz clic en “Descargar __CAPGO_KEEP_0__ Clave” para descargar tu __CAPGO_KEEP_1__ 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.APPLE_KEY_ID Almacena tu clave privada en un lugar seguro. Nunca debes compartir tus claves, almacenar claves en un __CAPGO_KEEP_0__ repositorio o incluir claves en el lado del cliente __CAPGO_KEEP_1__.
<3> Click “Download API Key” to download your API private key. The download link appears only if the private key has not yet been downloaded. Apple does not keep a copy of the private key. So, you can download it only once.

🔴 Store your private key in a safe place. You should never share your keys, store keys in a code repository, or include keys in client-side code.

Using an App Store Connect API Key

The API Key file (p8 file that you download), the key ID, and the issuer ID are required in order to create the JWT token for authorization. There are multiple ways that this information can be passed into Fastlane. I chose to use the Fastlane’s new action app_store_connect_api_keyLa muestro porque creo que es la forma más fácil de trabajar con la mayoría de las CI en el lugar, donde puedes establecer variables de entorno. Por favor, convierte el archivo p8 que descargas a Base64 y almacénalo como un secreto (ID de la cuestión. (

ID de la clave. (APPLE_KEY_CONTENT).

base64 -i APPLE_KEY_CONTENT.p8 | pbcopy

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

2. Certificados

Abra XCode y vaya a Configuración > Cuentas > ID de Apple > Equipos y seleccione su equipo.

Code identidades de firma

Haga clic en Administrar certificados.

Si aún no ha creado un certificado, puede crear un nuevo certificado.

Haz clic en + y selecciona Distribución de Apple

Distribución de Apple

Luego debes ir a la llave de cadena para descargar el certificado como un .p12 archivo.

Para hacer esto, debes ir a la llave de cadena, cambiar a la llave de cadena de inicios de sesión y luego la pestaña Mis Certificados.

Mis Certificados

Luego puedes seleccionar el certificado que deseas descargar. (Busca por la fecha del certificado)

Y luego haz clic derecho en la clave privada en el certificado y selecciona __CAPGO_KEEP_0__.

Elegir el formato de archivo Intercambio de información personal (.p12).

Eso descargará el certificado como un .p12 archivo.

Por favor, abre el archivo en una terminal y utiliza el siguiente comando para convertirlo a Base64:

base64 -i BUILD_CERTIFICATE.p12 | pbcopy

Eso se convertirá en tu BUILD_CERTIFICATE_BASE64 clave secreta. También, cuando se te pregunte, por favor proporciona la contraseña del certificado. Esta contraseña será tu P12_PASSWORD clave secreta.

3. Perfiles de configuración de provisión

Abrir Desarrollador de Apple y selecciona el equipo correcto.

Luego crea un nuevo perfil, haciendo clic en +

Crear un nuevo perfil

Y selecciona App Store Connect.

Selecciona App Store Connect

Luego debes seleccionar la aplicación correcta, ten cuidado, no puedes usar comodines de lo contrario la firma fallará.

Selecciona la aplicación correcta

Selecciona el certificado correcto que creaste antes (busca la fecha de vencimiento, debe ser el mismo día y mes que hoy) y haz clic en Continúa.

Selecciona el certificado correcto

Finalmente ingresa el nombre del perfil y haz clic en Generar.

El nombre se utilizará para identificar el perfil en Fastlane, bajo el valor de APPLE_PROFILE_NAME.

Generar el perfil

Puedes descargar el perfil como un .mobileprovision archivo.

Descargar el perfil

Por favor, convierte el perfil a Base64 y almacénalo como un secreto (BUILD_PROVISION_PROFILE_BASE64).

base64 -i BUILD_PROVISION_PROFILE.mobileprovision | pbcopy

4. Copiar archivos de Fastlane

Fastlane es una biblioteca de Ruby creada para automatizar tareas comunes de desarrollo móvil. Utilizando Fastlane, puedes configurar carriles 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, utilizaremos solo una pequeña cantidad de acciones básicas.

Crear el folder de Fastlane en la raíz de tu proyecto Capacitor/Ionic y agregar el Fastfile allí:

  • Folder: <project-root>/fastlane/
  • Archivo: <project-root>/fastlane/Fastfile

Este es el mismo nivel que package.json, capacitor.config.*, y el ios/ carpeta. No cree esta carpeta dentro de ios/App/.

platform :ios do
  desc 'Export ipa and submit to TestFlight'
  lane :beta do
    keychain_info = { keychain_name: "ios-build-#{Time.now.to_i}.keychain", keychain_password: SecureRandom.uuid }
    
    begin
      setup_signing(keychain_info)
      bump_build_number
      build_app_with_signing(keychain_info)
      submit_to_testflight
    ensure
      cleanup_keychain(keychain_info)
    end
  end

  private_lane :setup_signing do |options|
    create_keychain(
      name: options[:keychain_name],
      password: options[:keychain_password],
      unlock: true,
      timeout: 0,
      lock_when_sleeps: false, 
      add_to_search_list: true
    )
    import_cert(options)
    install_profile
    update_project_settings
  end

  lane :bump_build_number do
		file = File.read('../package.json')
		data_hash = JSON.parse(file)
		api_key = app_store_connect_api_key(
      key_id: ENV['APPLE_KEY_ID'],
      issuer_id: ENV['APPLE_ISSUER_ID'],
      key_content: ENV['APPLE_KEY_CONTENT'],
      is_key_content_base64: true,
      duration: 1200,
      in_house: false
    )
		build_num = app_store_build_number(
      api_key: api_key,
			app_identifier: ENV['BUNDLE_IDENTIFIER'],
			live: false
    )
		build_num = build_num + 1
		UI.message("Bumped build number to #{build_num}")
		increment_build_number(
			build_number: build_num,
			xcodeproj: "./ios/App/App.xcodeproj",
			skip_info_plist: true
		)
	end

  private_lane :import_cert do |options|
    cert_path = "#{Dir.tmpdir}/build_certificate.p12"
    File.write(cert_path, Base64.decode64(ENV['BUILD_CERTIFICATE_BASE64']))
    import_certificate(
      certificate_path: cert_path,
      certificate_password: ENV['P12_PASSWORD'] || "",
      keychain_name: options[:keychain_name],
      keychain_password: options[:keychain_password],
      log_output: true
    )
    File.delete(cert_path)
  end  
  
  private_lane :cleanup_keychain do |options|
    delete_keychain(
      name: options[:keychain_name]
    )
  end  

  private_lane :install_profile do
    profile_path = "#{Dir.tmpdir}/build_pp.mobileprovision"
    File.write(profile_path, Base64.decode64(ENV['BUILD_PROVISION_PROFILE_BASE64']))
    UI.user_error!("Failed to create provisioning profile at #{profile_path}") unless File.exist?(profile_path)
    ENV['PROVISIONING_PROFILE_PATH'] = profile_path
    install_provisioning_profile(path: profile_path)
    File.delete(profile_path)
  end

  private_lane :update_project_settings do
    update_code_signing_settings(
      use_automatic_signing: false,
      path: "./ios/App/App.xcodeproj",
      code_sign_identity: "iPhone Distribution",
      profile_name: ENV['APPLE_PROFILE_NAME'],
      bundle_identifier: ENV['BUNDLE_IDENTIFIER'],
      team_id: ENV['APP_STORE_CONNECT_TEAM_ID']
    )
    update_project_team(
      path: "./ios/App/App.xcodeproj",
      teamid: ENV['APP_STORE_CONNECT_TEAM_ID']
    )
  end

  private_lane :build_app_with_signing do |options|
    unlock_keychain(
      path: options[:keychain_name],
      password: options[:keychain_password],
      set_default: false
    )
    build_app(
      workspace: "./ios/App/App.xcworkspace",
      scheme: "App",
      configuration: "Release",
      export_method: "app-store",
      output_name: "App.ipa",
      export_options: {
        provisioningProfiles: {
          ENV['BUNDLE_IDENTIFIER'] => ENV['APPLE_PROFILE_NAME']
        }
      },
      xcargs: "-verbose",
      buildlog_path: "./build_logs",
      export_xcargs: "-allowProvisioningUpdates",
    )
  end   

  private_lane :submit_to_testflight do
    api_key = app_store_connect_api_key(
      key_id: ENV['APPLE_KEY_ID'],
      issuer_id: ENV['APPLE_ISSUER_ID'],
      key_content: ENV['APPLE_KEY_CONTENT'],
      is_key_content_base64: true,
      duration: 1200,
      in_house: false
    )
    pilot(
      api_key: api_key,
      skip_waiting_for_build_processing: true,
      skip_submission: true,
      distribute_external: false,
      notify_external_testers: false,
      ipa: "./App.ipa"
    )
  end
end

5. Configuración de secretos

GitHub Acciones utiliza los secretos de repositorio que configuras en el siguiente paso. Solo necesitas un archivo local .env si deseas ejecutar o probar Fastlane desde tu propia máquina.

Para pruebas locales, crea <project-root>/fastlane/.env al lado de Fastfile. No comites este archivo. Agrega fastlane/.env a tu .gitignore primero (o verifica que ya está ignorado). Aquí tienes un ejemplo:

APP_STORE_CONNECT_TEAM_ID=UVTJ336J2D
BUNDLE_IDENTIFIER=ee.forgr.testfastlane
# See previous section for these secrets
BUILD_CERTIFICATE_BASE64=
BUILD_PROVISION_PROFILE_BASE64=
APPLE_KEY_ID=
APPLE_ISSUER_ID=
APPLE_KEY_CONTENT=
P12_PASSWORD=
APPLE_PROFILE_NAME=

Obtener el ID DE EQUIPO DE CONEXIÓN A LA TIENDA DE APLICACIONES

Ir a Centro de Desarrolladores y desplazarse hacia abajo hasta la Membership details sección. La Team ID es el valor que necesita establecer en el APP_STORE_CONNECT_TEAM_ID secret.

app-store-connect-team-id

Obtener el IDENTIFICADOR DE PAQUETE

  1. Abrir Xcode
  2. Hacer doble clic en el App en el navegador de proyectos
  3. Luego haz clic en la pestaña Signing and Capabilities
  4. Copia el valor de la Bundle identifierEsto es el valor que debes establecer en la BUNDLE_IDENTIFIER clave secreta.
bundle-identifier-xcode

6. Procesamiento de

En GitHub Acciones, se te facturará según los minutos que hayas utilizado para ejecutar tu flujo de trabajo CI/CD. A partir de mi experiencia, tarda aproximadamente 10–15 minutos antes de que un build pueda ser procesado en App Store Connect.

Para proyectos privados, el costo estimado por build puede llegar a $0.08/min x 15 min = $1.2o más, dependiendo de la configuración y dependencias de tu proyecto.

Si estás preocupado por los costos para proyectos privados, puedes establecer skip_waiting_for_build_processing para true. Esto ahorrará minutos de compilación ya que no tendrás que esperar a que App Store Connect termine de procesar la compilación.

Sin embargo, hay un tradeof - tendrás que actualizar manualmente la información de cumplimiento de tu aplicación en App Store Connect antes de poder distribuir la compilación a los usuarios.

Esta optimización es principalmente útil para proyectos privados donde los minutos de compilación cuestan dinero. Para proyectos públicos/gratuitos, los minutos de compilación son gratis, por lo que no hay necesidad de habilitar esta configuración. Consulta la página de precios de GitHub para obtener más detalles. 7. Configura acciones de __CAPGO_KEEP_0__ Configura secretos de __CAPGO_KEEP_0__

7. Setup GitHub Actions

archivo y pégalos en los secretos de la repositorio de GitHub.

Ve a .env 7. Configura acciones de GitHub

Configura secretos de __CAPGO_KEEP_0__ Configuración > Secretos y variables > Acciones > Nuevo secreto de repositorio

github-secretos

2. BUILD_CERTIFICATE_BASE64 - Certificado codificado en Base64.

3. BUILD_PROVISION_PROFILE_BASE64 - Perfil de provisión codificado en Base64.

4. BUNDLE_IDENTIFIER - Identificador de paquete de tu aplicación.

5. APPLE_KEY_ID — Identificador de clave de App Store Connect API 🔺ID de clave.

6. APPLE_ISSUER_ID — Identificador de emisor de App Store Connect API 🔺ID de emisor.

7. APPLE_KEY_CONTENT — Contenido de clave de App Store Connect API 🔺Clave de contenido. .p8, revisa esto

8. Configura el archivo de flujo de trabajo GitHub

Crea un directorio de flujo de trabajo GitHub.

cd .github/workflows

Dentro del workflow directorio, 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: '3.0'
          bundler-cache: true
      - uses: maierj/fastlane-action@v3.1.0
        env:
          APP_STORE_CONNECT_TEAM_ID: ${{ secrets.APP_STORE_CONNECT_TEAM_ID }}
          BUNDLE_IDENTIFIER: ${{ secrets.BUNDLE_IDENTIFIER }}
          BUILD_CERTIFICATE_BASE64: ${{ secrets.BUILD_CERTIFICATE_BASE64 }}
          BUILD_PROVISION_PROFILE_BASE64: ${{ secrets.BUILD_PROVISION_PROFILE_BASE64 }}
          APPLE_KEY_ID: ${{ secrets.APPLE_KEY_ID }}
          APPLE_ISSUER_ID: ${{ secrets.APPLE_ISSUER_ID }}
          APPLE_KEY_CONTENT: ${{ secrets.APPLE_KEY_CONTENT }}
          P12_PASSWORD: ${{ secrets.P12_PASSWORD }}
          APPLE_PROFILE_NAME: ${{ secrets.APPLE_PROFILE_NAME }}
        with:
          lane: ios beta
      - name: Upload release bundle
        uses: actions/upload-artifact@v6
        with:
          name: ios-release
          path: ./App.ipa
          retention-days: 10

Este flujo de trabajo debería ser desencadenado después de cada GitHub etiqueta, si necesitas automatizar la etiqueta, consulta Automatización de compilación y lanzamiento con acciones GitHub 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 en TestFlight.

Tu aplicación no necesita utilizar Ionic, solo el Capacitor base es obligatorio, puede tener un módulo Cordova antiguo, pero el Capacitor JS plugin se recomienda.

8. Desencadena el flujo de trabajo

Crear un Commit

Haz un commit. Deberías ver el flujo de trabajo activo en el repositorio.

Desencadena el flujo de trabajo

Pushe los nuevos commits a la rama main o development para desencadenar el flujo de trabajo.

Iniciado con commit

Después de unos minutos, la compilación debería estar disponible en su panel de App Store Connect.

Panel de Testflight

9. ¿Puedo desplegar desde la máquina local?

Sí, puedes hacerlo y es muy sencillo.

Puedes utilizar Xcode para compilar y firmar tu aplicación, como siempre.

Guías de configuración de CI/CD

Plataformas de CI/CD alternativas

Actualizaciones en vivo y despliegue

Gracias

Este blog se basa en los siguientes artículos:

Sigue adelante desde la construcción automática de IOS de Capacitor con acciones de GitHub con certificado

Si estás utilizando Construcción automática de IOS de Capacitor con acciones de GitHub con certificado para planificar la automatización de CI/CD, conecta con Automatización de CI/CD de Capgo 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 para el detalle de implementación en GitHub Integración de Acciones.

Actualizaciones en vivo para Capacitor aplicaciones

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

Comienza ahora

Últimas noticias de nuestro blog

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