Saltate a la sección principal
CI/CD

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

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

Martin Donadieu

Martin Donadieu

Gerente de Contenido

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

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

Ahora recomendamos utilizar Capgo Compilación con el Capgo CLI para compilaciones nativas Capacitor. Esta guía de Fastlane se mantiene para los equipos que mantienen flujos de trabajo de acciones existentes de GitHub, pero los nuevos builds de iOS deben utilizar el Capgo CLI para que no tengas que mantener Fastlane, ejecutores de Xcode, certificados y scripts de carga tú mismo.

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 acciones de GitHub
  • Conocimiento de la configuración de Fastlane
  • Tiempo para mantener y depurar el pipeline
  • Certificados y perfiles de provisión adecuados

Configuración profesional de CI/CD por Capgo

Saltar la complejidad. Capgo configura directamente su pipeline CI/CD en su plataforma preferida:

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

Precios

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

Configura CI/CD Ahora

Guía de Configuración Manual

Si todavía quieres configurar todo tú mismo, aquí está lo que necesitas 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 desarrolladores 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 fecha de creación del tutorial, pueden cambiar en el futuro) Una vez advertido de los requisitos y precios, continuemos.

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

Nota: En el post supongo que 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 tu ID de Apple ayuda a asegurarte de que eres la única persona que puede acceder a tu 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 de emisor
  2. Identificador 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 — Seleccionar la pestaña de Integración.

Integración de App Store Connect API

  1. Haga clic en Generar API clave o en el botón 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 la clave de App Store Connect API

6 — En 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. Se recomienda seleccionar Administrador de la aplicación.

  1. Haz clic en Generar.

El acceso a una clave API no puede limitarse 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 cuestión. (APPLE_ISSUER_ID secreto)
<2> ID de la clave. (APPLE_KEY_ID secreto)
<3> 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, solo puedes descargarla 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.

Usar una clave API de App Store Connect

El archivo de la llave API (p8 que descargas), la ID de la llave y la ID del emisor son necesarios para crear el token JWT de autorización. app_store_connect_api_keyHay varias formas de pasar esta información a Fastlane. El método que elegí es el de utilizar la acción nueva de Fastlane Puedes aprender otros métodos enLa 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, donde puedes establecer variables de entorno.APPLE_KEY_CONTENT).

base64 -i APPLE_KEY_CONTENT.p8 | pbcopy

Now we can manage the App Store Connect with Fastlane using the API key, great!

Ahora podemos gestionar App Store Connect con Fastlane utilizando la llave __CAPGO_KEEP_0__, genial!

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

Code identidades de firma

Haz clic en Administra 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 un .p12 archivo.

Para hacerlo, debes ir a la llave de cadena, cambiar a la pestaña iniciar sesión clave de cadena 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 del certificado y selecciona Exportar.

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

Esto se convertirá en tu BUILD_CERTIFICATE_BASE64 __CAPGO_KEEP_0__ P12_PASSWORD también, cuando se le pregunte, por favor proporcione la contraseña del certificado. Esta contraseña será tu

__CAPGO_KEEP_0__

3. Perfiles de configuración Abrir Desarrollador de Apple

y seleccionar el equipo correcto. +

Luego cree un nuevo perfil, haciendo clic en

Crear un nuevo perfil Y seleccionar.

Conecta con la Tienda de Mac App

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

Seleccionar la aplicación correcta

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

Generar el perfil APPLE_PROFILE_NAME.

Puedes descargar el perfil como un

archivo. .mobileprovision Descargar el perfil

Seleccionar 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

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. Al utilizar 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 se realizarían 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. package.json, capacitor.config.*Crear el folder de Fastlane en la raíz de su proyecto __CAPGO_KEEP_0__/Ionic y agregue el 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 Actions uses the repository secrets you configure in the next step. You only need a local .env , y el folder. No lo cree dentro de este nivel de carpeta 5. Configuración de secretos __CAPGO_KEEP_0__ Actions utiliza los secretos de repositorio que configura en el siguiente paso. Solo necesita un archivo local si quiere ejecutar o probar Fastlane desde su propia máquina.

Para la prueba local, crea <project-root>/fastlane/.env al lado de Fastfile. No comentes 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=

Obteniendo el APP_STORE_CONNECT_TEAM_ID

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

ID de equipo de App Store Connect

Obtener el BUNDLE_IDENTIFIER

  1. Abrir Xcode
  2. Haz 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 Bundle identifierEste es el valor que debes establecer en BUNDLE_IDENTIFIER secret.
BUNDLE_IDENTIFIER en Xcode

6. Procesamiento de compilación

En GitHub Acciones, se le facturan minutos según los minutos que ha utilizado para ejecutar su flujo de trabajo de CI/CD. A partir de mi experiencia, tarda unos 10-15 minutos antes de que se pueda procesar una compilación en App Store Connect. Para proyectos privados, el costo estimado por compilació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 está preocupado por los costos para proyectos privados, puede establecer

para skip_waiting_for_build_processing . Esto ahorrará minutos de compilación no esperando a que App Store Connect termine procesando la compilación. trueSin 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 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 gratuitos, por lo que no hay necesidad de habilitar esta configuración. Consulte la página de precios de __CAPGO_KEEP_0__ para obtener más detalles.

This optimization is mainly useful for private projects where build minutes cost money. For public/free projects, the build minutes are free so there’s no need to enable this setting. See GitHub’s See __CAPGO_KEEP_0__’s pricing page for more details. This optimization is mainly useful for private projects where build minutes cost money.

7. Configura GitHub Acciones

Configura GitHub secretos

Por favor copia los secretos del .env archivo y pégalos en los secretos del repositorio GitHub.

Ve a Configuración > Secretos y variables > Acciones > Nuevo secreto de repositorio

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 - su identificador de paquete de la aplicación.

5. APPLE_KEY_ID — Conectar la Tienda de Mac API Clave 🔺ID de Clave.

6. APPLE_ISSUER_ID — Conectar la Tienda de Mac API Clave 🔺ID de Emisor.

7. APPLE_KEY_CONTENT — Conectar la Tienda de Mac API Clave 🔺Contenido de la Clave. .p8, revisarlo

8. Configurar el archivo de flujo de trabajo GitHub

Crear un directorio de flujo de trabajo GitHub.

cd .github/workflows

Dentro del workflow carpeta, crear un archivo llamado build-upload-ios.ymly agregar 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 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.

8. Desencadena el flujo de trabajo

Crear un Commit

Haz 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

9. ¿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 de CI/CD

Plataformas de CI/CD alternativas

Actualizaciones en vivo y despliegue

Gracias

Este blog se basa en los siguientes artículos:

Actualizaciones en vivo para aplicaciones de Capacitor

Cuando haya un error en la capa de web en vivo, envíe la corrección a través de Capgo en lugar de esperar días a 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 brinda las mejores perspectivas que necesitas para crear una aplicación móvil verdaderamente profesional.