Costruzioni iOS automatiche con GitHub Actions utilizzando Match
La configurazione della CI/CD per le app Capacitor può essere complessa e richiede molto tempo. Ecco cosa devi sapere:
Consigliato per Nuove Costruzioni: Utilizza Capgo Costruzione
Adesso raccomandiamo di utilizzare Capgo Costruzione con il Capgo CLI per le costruzioni native Capacitor. Questa guida Fastlane Match viene mantenuta per le squadre che mantengono pipeline di azioni esistenti GitHub, ma nuove costruzioni iOS dovrebbero utilizzare il Capgo CLI in modo da non dover mantenere Fastlane, Match repository, esecutori Xcode, certificati e script di caricamento da soli.
Capgo Costruisci per CI/CD da Capgo
Svuota la manutenzione di Fastlane Match, esecutori Xcode, certificati, profili di provisioning e script di caricamento. Capgo Costruisci Esegue costruzioni native iOS firmate direttamente dalla tua pipeline CI/CD esistente:
- Funziona con la tua pipeline: Attiva Capgo Costruisci da GitHub Actions, GitLab CI, Jenkins o script locali dopo la costruzione web e
npx cap sync. - Firma da segreti CI: __CAPGO_KEEP_0__ Costruisci mantiene ambienti di costruzione Apple aggiornati, quindi non devi gestire esecutori macOS, immagini Xcode, Fastlane o repository Match.
- Articoli e sottoscrizioneCapgo Costruisci per CI/CD da __CAPGO_KEEP_1__
- Svuota la manutenzione di Fastlane Match, esecutori Xcode, certificati, profili di provisioning e script di caricamento.: Scarica gli artefatti firmati per la QA o invia i build di rilascio attraverso il Capgo CLI.
Prenotazione
- i piani Capgo iniziano da 12€/mese
- Incluso gli aggiornamenti OTA e circa 15 build nativi al mese
- I minuti aggiuntivi per i build sono fatturati per minuto attraverso i crediti
Configura Capgo Build nella CI/CD
Guida di configurazione manuale
Ecco cosa devi fare:
Continua la consegna continua per iOS utilizzando Fastlane e GitHub Azioni utilizzando match
Prerequisiti
Prima di continuare con il tutorial…
- Assicurati di avere Fastlane installato sul tuo computer di sviluppo.
- iscrizione al programma di sviluppo iOS.
- Desiderio di leggere 😆…
- Un team di molti sviluppatori, altrimenti raccomandiamo di utilizzare fastlane cert per flussi di lavoro più semplici.
Importante per il prezzo

https://github.com/caratteristiche/azioni
Il servizio è ‘gratuito’ fino al limite, a seconda della macchina scelta.
Utilizzeremo un macOS Potete vedere nel screenshot il prezzo e le limitazioni (i prezzi sono validi alla data di creazione del tutorial e potrebbero subire modifiche in futuro)
🔴 Una volta informati sui requisiti e sui prezzi, se lo desiderate, continuiamo…
📣 Nel post si assume che abbiamo già creato l'applicazione in iTunes Connect, abbiamo i certificati dell'ecosistema Apple, tutto sarà copiato da Fastlane!
Scendiamo in acqua 🤿
Passaggi da seguire nel post
- Utilizzo di App Store Connect API con Fastlane Match
- Requisiti
- Creazione di una chiave App Store Connect API
- Utilizzo di una chiave App Store Connect API
- Copia dei file Fastlane
- Configurazione di Fastlane match
1. L'uso di App Store Connect API con Fastlane Match
Iniziando da febbraio 2021, l'autenticazione a due fattori o la verifica a due passaggi è richiesta per tutti gli utenti per accedere a App Store Connect. Questo strato aggiuntivo di sicurezza per il tuo ID Apple aiuta a garantire che tu sia l'unica persona che può accedere al tuo account.
Dal Sostegno Apple
Iniziare con match richiede di revocare i certificati esistenti. Ma non preoccuparti, avrai il nuovo uno direttamente.
Requisiti
Per poter utilizzare App Store Connect API, Fastlane ha bisogno di tre cose.
- ID emittente.
- ID chiave.
- File chiave o contenuto della chiave.
Creare una chiave di App Store Connect API
Per generare le chiavi, è necessario avere il permesso di amministratore in App Store Connect. Se non si ha quel permesso, si può indirizzare la persona competente a questo articolo e seguire le istruzioni seguenti.
1 — Accedi a App Store Connect.
2 — Seleziona Utenti e accessi.

3 — Seleziona la scheda di integrazione.

4 — Clicca su Genera chiave API o sul pulsante Aggiungi (+).

5 — Inserisci un nome per la chiave. Il nome è solo per la tua referenza e non fa parte della chiave stessa.

6 — Sotto Accesso, seleziona il ruolo per la chiave. I ruoli che si applicano alle chiavi sono gli stessi ruoli che si applicano agli utenti del tuo team. Vedi permessi di ruolo. Consigliamo di selezionare amministratore dell'app.
7 — Clicca su Genera.
Un'API chiave non può avere accesso limitato a specifiche app.
Il nome della nuova chiave, ID chiave, un link di download e altre informazioni vengono visualizzate sulla pagina.

Qui puoi prendere tutte e tre le informazioni necessarie.
1> ID della richiesta.
2> ID della chiave.
Clicka su “Downloada API Key” per scaricare la tua chiave privata API.
🔴 Riponi la tua chiave privata in un luogo sicuro. Non condividere mai le tue chiavi, archivia le chiavi in un code repository o includile nei code client-side.
Utilizza una chiave API di App Store Connect
Per creare il token JWT di autorizzazione, sono necessari il file della chiave API (p8 che si scarica), l'ID della chiave e l'ID dell'emittente. Ci sono diverse modalità per inserire queste informazioni nel Fastlane utilizzando l'azione nuova di Fastlane. app_store_connect_api_keySi può imparare altre modalità in La documentazione di Fastlane. Mostra questo metodo perché penso che sia la via più facile per lavorare con la maggior parte dei CI, dove si possono impostare le variabili di ambiente.
Ora possiamo gestire Fastlane con la chiave API di App Store Connect, fantastico!
2. Copia i file di Fastlane
Fastlane è una libreria Ruby creata per automatizzare le attività di sviluppo mobile comuni. Utilizzando Fastlane, puoi configurare delle “linee” personalizzate che raggruppano una serie di “azioni” che eseguono compiti che normalmente si eseguirebbero utilizzando Android Studio. Con Fastlane puoi fare molto, ma per i fini di questo tutorial, utilizzeremo solo una manciata di azioni di base.
Creare un folder Fastlane alla radice del tuo progetto e copia i seguenti file: 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 è un nuovo approccio per la firma iOS di code. Fastlane match rende facile per i team gestire i certificati e i profili di provisioning richiesti per le tue app iOS.
Crea un nuovo repository privato denominato certificatesad esempio sul tuo GitHub account personale o organizzazione.
Inizia Fastlane match per la tua app iOS.
fastlane match init
Poi seleziona opzione #1 (Archiviazione Git).
[01:00:00]: fastlane match supports multiple storage modes, please select the one you want to use:1. git2. google_cloud3. s3?
Assegna l'URL del repository appena creato.
[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>
Ora hai all'interno della cartella Fastlane un file denominato Matchfile e
_git_url_Deve essere impostato sull'URL HTTPS del repository dei certificati. In opzione, puoi anche utilizzare SSH, ma richiede un passaggio diverso per l'esecuzione.
# ios/Matchfilegit_url("https://github.com/gitusername/certificates")storage_mode("git")type("appstore")
Successivamente, andiamo a generare i certificati e inserire le credenziali quando richiesto con Fastlane Match.
Ti verrà chiesto di inserire una passphrase. Ricordatela correttamente perché verrà utilizzata in seguito dalle GitHub Actions per decrittografare il tuo repository dei certificati.
fastlane match appstore
Se tutto è andato bene, dovresti vedere qualcosa di simile:
[01:40:52]: All required keys, certificates and provisioning profiles are installed 🙌
Se hai incontrato un problema con GitHub e le necessarie autorizzazioni, forse questo post aiuterà a generare i token di autenticazione per git.
I certificati e i profili di provisioning generati vengono caricati nel repository dei certificati delle risorse

Infine, apri il tuo project in Xcode, e aggiorna il profilo di provisioning per la configurazione di rilascio del tuo app.

Alcune cose da notare 💡
MATCH
Per importare i certificati e i profili di provisioning, il CI/CD deve avere accesso al repository dei certificati. Puoi farlo generando un token di accesso personale (che dovrebbe essere utilizzato prima) che abbia lo scopo di accedere o leggere repository privati.
In GitHub, vai a Impostazioni → Impostazioni dello sviluppatore → Token di accesso personale → clicca Generate New Token → seleziona la repo scope → clicca quindi Generate token.

Hai una copia del token di accesso personale generato. Lo utilizzerai in seguito per la variabile di ambiente GIT_TOKEN.
Rimpiazzare il file di match generato nella cartella di Fastlane con 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)
Questo verrà utilizzato dalle GitHub Actions per importare i certificati e i profili di provisioning. E var verrà impostato nelle GitHub Secrets, al posto di codificarli manualmente nel file.
Elaborazione del Prodotto
In GitHub Actions, si viene fatturati in base ai minuti si sono utilizzati per eseguire il flusso di lavoro CI/CD. Dall'esperienza, ci vuole circa 10-15 minuti prima che un build possa essere elaborato in App Store Connect.
Per i progetti privati, il costo stimato per ogni build può arrivare a $0,08/min x 15 minuti = $1,2, o più, a seconda della configurazione o delle dipendenze del tuo progetto.
Se condividi le stesse preoccupazioni per il prezzo come faccio io per i progetti privati, puoi mantenere il skip_waiting_for_build_processing perché? true.
C'è un trucco? Devi aggiornare manualmente la conformità del tuo app in App Store Connect dopo che il build è stato elaborato, per poter distribuire il build ai tuoi utenti.
This è solo un parametro facoltativo da aggiornare se desideri risparmiare sui minuti di build per progetti privati. Per i progetti gratuiti, questo non dovrebbe essere un problema per niente. Vedi tariffe.
3. Configura GitHub azioni
Configura GitHub segreti
Ti sei mai chiesto da dove provengono i valori di ENV ? Bene, non è più un segreto – provengono dal segreto del tuo progetto.

1. APP_STORE_CONNECT_TEAM_ID - l'ID del tuo team di App Store Connect se sei in più team.
2. DEVELOPER_APP_ID - in App Store Connect, vai all'app → Informazioni sull'app → Scrolla verso il basso nella sezione General Information del tuo app e cerca Apple ID.
3. DEVELOPER_APP_IDENTIFIER - l'identificatore del bundle della tua app.
4. DEVELOPER_PORTAL_TEAM_ID - l'ID del tuo team del portale dei sviluppatori se sei in più team.
5. FASTLANE_APPLE_ID - l'ID Apple o l'indirizzo email del tuo account di sviluppatore che utilizzi per gestire l'app.
6. GIT_USERNAME & GIT_TOKEN - il tuo username Git e il tuo token di accesso personale.
7. MATCH_PASSWORD - la passphrase che hai assegnato quando hai inizializzato match, verrà utilizzata per decrittografare i certificati e i profili di provisioning.
8. PROVISIONING_PROFILE_SPECIFIER - match AppStore <YOUR_APP_BUNDLE_IDENTIFIER>, es. match AppStore com.domain.blabla.demo.
9. TEMP_KEYCHAIN_USER & TEMP_KEYCHAIN_PASSWORD - assegna un utente e una password di keychain temporanei per il tuo workflow.
10. APPLE_KEY_ID — App Store Connect API Chiave 🔺ID Chiave.
11. APPLE_ISSUER_ID — App Store Connect API Chiave 🔺ID Emittente.
12. APPLE_KEY_CONTENT — App Store Connect API Chiave 🔺 Contenuto della chiave o file della chiave. .p8, controlla
13. CERTIFICATE_STORE_URL — L'URL del tuo repository di Match chiavi (ad esempio https://github.com/***/fastlane_match.git)
4. Configura il file di workflow di GitHub
Crea un directory di workflow di GitHub.
cd .github/workflows
All'interno della workflow cartella, crea un file denominato build-upload-ios.ymle aggiungi il seguente.
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
Questo workflow dovrebbe essere attivato dopo ogni GitHub tag, se hai bisogno di automatizzare i tag, si prega di fare riferimento a Costruzione automatica e rilascio con GitHub azioni primo.
Poi questo workflow preleverà i tuoi dipendenze NodeJS, li installerà e costruirà il tuo'applicazione JavaScript.
Ogni volta che invii un nuovo commit, verrà costruito un rilascio in TestFlight.
La tua App non ha bisogno di utilizzare Ionic, è sufficiente che abbia la base Capacitor obbligatoria, può avere il vecchio modulo Cordova, ma è preferibile il plugin Capacitor JS.
5. Attiva il workflow
Crea un Commit
Fai un commit, dovresti vedere il workflow attivo nel repository.
Attiva il workflow
Invia i nuovi commit sulla branca main o development per attivare il workflow.

Dopo pochi minuti, il build dovrebbe essere disponibile nel tuo dashboard App Store Connect.

Si può distribuire dalla macchina locale?
Sì, puoi farlo e non è affatto difficile.
Immagina di avere un repository privato, e hai esaurito i minuti del piano gratuito e non vuoi pagare per nuove rilasci, o forse preferisci inviare l'applicazione manualmente.
Andiamo per questo
Ok, prima dobbiamo creare in my_project_path/fastlane un file chiamato .env, nello stesso percorso di Fastfile, per poter creare lo stesso segreto le proprietà trovate nel nostro _GitHub, elencate di seguito:
il file .env per il deploy da macchina locale
Ora, puoi andare al terminale e lanciare il Fastlane dalla tua macchina:
fastlane closed_beta
❌ Informazioni essenziali sul .env file, poiché non desideriamo esporre questa informazione, dobbiamo aggiungerla nel nostro .gitignore, qualcosa del genere: ❌
fastlane/*.env
Deve funzionare nello stesso modo in cui avviene dalle GitHub Azioni sul macchina remota, ma sul nostro macchina locale. 🍻

Terminal execution: $ Fastlane closed_beta
Se sei arrivato fin qui, i miei complimenti, ora hai un processo completamente automatizzato per le tue app iOS con Fastlane e GitHub Azioni.
Ogni volta che invii un nuovo commit, verrà costruito un rilascio nel console di Google Play, canale beta. Migliorerò questo blog con i tuoi feedback, se hai una domanda o una suggerenza, per favore lasciaci un messaggio via email martin@capgo.app
Costruisci sul tuo dispositivo
If necessario, per costruire su dispositivo, devi aggiungerli manualmente alla configurazione.
Collega il tuo dispositivo al tuo Mac e apri il menu del dispositivo
Poi copia il tuo identificatore
E quindi esegui il comando:
fastlane register_new_device
Chiederà di impostare un nome dispositivo e l'identificatore:

Se hai problemi
Se hai problemi con il dispositivo di sviluppo non in grado di testare ecc. che di solito risolve il problema.
C'è un comando magico che può salvarti:
fastlane match nuke development
fastlane match development
Poi: Pulisci il progetto tenendo premuto Shift(⇧)+Command(⌘)+K o selezionando Product > Pulisci (potrebbe essere etichettato “Pulisci cartella di costruzione”)
Poi prova a eseguire nuovamente l'app sul tuo dispositivo.
Grazie
Questo blog si basa sui seguenti articoli:
- Continua la consegna per IOS utilizzando Fastlane e azioni GitHub
- Documentazione Fastlane
- Questo GitHub messaggio da @mrogunlana
Continua a procedere dall'Automatico Capacitor build IOS con GitHub azioni utilizzando match
Se stai utilizzando Automatico Capacitor build IOS con GitHub azioni utilizzando match per pianificare l'automazione CI/CD, connettilo con Capgo CI/CD per il flusso di lavoro del prodotto in Capgo CI/CD, Capgo Build Native per il flusso di lavoro del prodotto in Capgo Costruzioni native Capgo Integrazioni per il flusso di lavoro del prodotto in Capgo Integrazioni Integrazione CI/CD per la dettaglio di implementazione in Integrazione CI/CD, e GitHub Integrazione azioni per la dettaglio di implementazione in GitHub Integrazione azioni