Saltarse al contenido principal
CI/CD

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

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

Martin Donadieu

Martin Donadieu

Gerente de Contenido

Automatic Capacitor IOS build with GitHub actions with certificate

Configuración de CI/CD para aplicaciones Capacitor puede ser compleja y tiempo consumidor. Aquí está lo que necesitas saber:

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

Capgo Construcción para CI/CD por Capgo

Saltar la mantenimiento de Fastlane, ejecutor de Xcode, certificado, perfil de provisión, y script de carga. Capgo Construcción ejecuta compilaciones nativas de iOS firmadas a partir de tu pipeline de CI/CD existente:

  • Funciona con tu pipeline: Desencadena la Capgo Construcción desde GitHub Actions, GitLab CI, Jenkins o scripts locales después de tu compilación 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.
  • Sin mantenimiento de ejecutor nativo: La Capgo Construcción 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 artículos firmados para QA o presenta compilaciones de lanzamiento a través del Capgo CLI.

Precios

  • Los planes de Capgo 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:

Entrega continua para iOS utilizando Fastlane y GitHub Acciones y certificado

Requisitos previos

Antes de continuar con el tutorial:

  • Asegúrate de tener Fastlane instalado 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 GitHub Acción

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 macOS, puedes ver en la captura de pantalla su precio y límites (precios a la creación del tutorial, pueden cambiar en el futuro) Una vez advertido de los requisitos y precios, continuemos.

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

¿Qué aprenderás en el tutorial

What will you learn in the 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

In order for Fastlane to be able to use App Store Connect API to upload your app, you need to provide the following tres cosas:

  1. ID de 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 a App Store Connect

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

Integración de App Store Connect API

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

Las claves de App Store Connect API crean

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

Nombre de las claves de App Store Connect API

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

  1. Haga clic en Generar.

Una clave 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.

Descargas de claves de App Store Connect

Puedes obtener aquí toda la información necesaria.
<1> ID de la incidencia. (APPLE_ISSUER_ID secreto)
<2> ID de la clave. (APPLE_KEY_ID secreto)
Haz clic en "Descargar clave API" para descargar tu clave privada 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, puedes descargarla solo una vez.

🔴 Almacena tu clave privada en un lugar seguro. Nunca debes compartir tus claves, almacenar claves en un repositorio code o incluir claves en el lado del cliente code.

Uso de una clave API de App Store Connect

El archivo de la clave 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 de pasar esta información a Fastlane. Elige usar la acción nueva de Fastlane app_store_connect_api_key. Puedes aprender otras formas de hacerlo 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 de ahí, donde puedes establecer variables de entorno.

Por favor, convierte el archivo p8 que descargaste a Base64 y almacénalo como un secreto (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

Abre XCode y ve a Configuración > Cuentas > Apple ID > Equipos y selecciona tu equipo.

Code identidades de firma

Haz clic en Gestionar certificados.

Si aún no has creado un certificado, puedes 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 .p12 archivo.

Para hacerlo, debes ir a la caja de llaves, cambiar a la pestaña login caja de llaves Certificados.

Certificados

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

Y luego haz clic derecho en la clave privada del certificado y selecciona Exportar.

Elige 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

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

3. Perfiles de configuració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.

Seleccione App Store Connect

Luego necesitará seleccionar la aplicación correcta, tenga cuidado, ya que no puede utilizar comodines, de lo contrario, la firma fallará.

Seleccione la aplicación correcta

Seleccione el certificado correcto que creó antes (busque la fecha de vencimiento, debe ser el mismo día y mes que hoy) y haga clic en Continuar.

Seleccione el certificado correcto

Finalmente ingrese el nombre del perfil y haga clic en Generar.

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

Genere el perfil

Puede descargar el perfil como .mobileprovision archivo.

Descargue el perfil

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

base64 -i BUILD_PROVISION_PROFILE.mobileprovision | pbcopy

4. Copie archivos de Fastlane

Fastlane es una biblioteca de Ruby creada para automatizar tareas comunes de desarrollo móvil. Utilizando Fastlane, puede configurar

Create the Fastlane folder at the root of your Capacitor/Ionic project and add the Fastfile there:

  • personalizados que agrupan una serie de <project-root>/fastlane/
  • acciones <project-root>/fastlane/Fastfile

que realizan tareas que normalmente realizaría utilizando Android Studio. Puede hacer mucho con Fastlane, pero para los fines de este tutorial, solo utilizaremos una pequeña cantidad de acciones básicas. package.json, capacitor.config.*Cree el carpeta de Fastlane en la raíz de su proyecto __CAPGO_KEEP_0__/Ionic y agregue el archivo Fastfile allí: ios/ Carpeta: 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

Archivo:

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 del 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 del equipo de desarrollador de App Store Connect

Ve a Centro de Desarrolladores y desplázate hacia abajo hasta la Membership details sección. Team ID es el valor que debes establecer en el APP_STORE_CONNECT_TEAM_ID secret.

app-store-connect-team-id

Obtener el BUNDLE_IDENTIFIER

  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. Copiar el valor de el Bundle identifier. Este es el valor que debes establecer en el BUNDLE_IDENTIFIER secret.
identificador-de-bundle-xcode

6. Procesamiento de la Construcción

En GitHub Acciones, se facturan según los minutos que ha utilizado para ejecutar su flujo de trabajo CI/CD. A partir de mi experiencia, tarda unos 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 y dependencias de su proyecto.

Si se preocupa por los costos para proyectos privados, puede establecer skip_waiting_for_build_processing a true. Esto ahorrará minutos de construcción no esperando a que App Store Connect termine procesando la construcción.

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

Esta optimización es principalmente útil para proyectos privados donde los minutos de construcción cuestan dinero. Para proyectos públicos/gratuitos, los minutos de construcción son gratuitos, por lo que no hay necesidad de habilitar esta configuración. Consulte GitHub’s página de precios Para obtener más detalles.

8. Configura GitHub Acciones

Configura GitHub secretos

Por favor, copia los secretos del archivo y pégalos en los secretos del repositorio __CAPGO_KEEP_0__. .env file and paste them into the GitHub repository secrets.

Configuración > Secretos y variables > Acciones 7. Configura __CAPGO_KEEP_0__ Acciones &gt; Nuevo repositorio secreto

github-secrets

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 — Llave de App Store Connect API 🔺ID de clave.

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

7. APPLE_KEY_CONTENT — Llave de App Store Connect API 🔺Contenido de la clave. .p8, revisarlo

8. Configurar archivo de flujo de trabajo GitHub

Crea un directorio de flujo de trabajo 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: '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 GitHub acciones en primer lugar.

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.

8. Desencadenar el flujo de trabajo

Crear un commit

Hacer un commitComprueba que el flujo de trabajo esté activo en el repositorio.

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

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

Guías de configuración CI/CD

Plataformas 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 Capacitor con acciones GitHub con certificado

Si estás utilizando Construcción automática de IOS Capacitor con acciones GitHub con certificado 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 Construcciones nativas para el flujo de trabajo del producto en Capgo Construcción Nativa, Capgo Integraciones para el flujo de trabajo del producto en Capgo Integraciones, Integración CI/CD para el detalle de implementación en Integración 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 un bug en la capa web está activo, 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 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.