Costruzioni iOS automatiche con GitHub azioni 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 consigliamo di utilizzare Capgo Costruzione con il Capgo CLI per le costruzioni native Capacitor. Questa guida di Fastlane Match è mantenuta per i team che mantengono pipeline di azioni esistenti GitHub, ma le nuove costruzioni iOS dovrebbero utilizzare il Capgo CLI in modo da non dover mantenere i repository di Fastlane, Match, i runner di Xcode, i certificati e i script di caricamento.
Requisiti
Prima di iniziare, avrai bisogno di configurare:
- Un account GitHub con accesso amministrativo
- Iscolarizzazione del programma di sviluppo iOS
- Accesso a App Store Connect API con le autorizzazioni corrette
- Comprensione dei flussi di lavoro di GitHub Actions
- Conoscenza della configurazione di Fastlane e Match
- Tempo per mantenere e debuggare il pipeline
- Un team di molti sviluppatori, altrimenti consigliamo di utilizzare fastlane cert per flussi di lavoro più semplici
Impianto CI/CD professionale da Capgo
Saltare la complessità. Capgo configura la tua pipeline CI/CD direttamente nella tua piattaforma preferita:
- Indipendenza di Piattaforma: Funziona con GitHub Actions, GitLab CI o altri
- Integrazione Semplice: Non è necessario cambiare piattaforma, funziona con il tuo processo attuale
- Configurazione Personalizzata: Impostazione personalizzata che si adatta alle esigenze del tuo progetto
- Guida Esperta: Abbiamo già configurato la CI/CD per oltre 50 app
Prezzi
- Fattura di configurazione unica: $2,600
- I tuoi costi di esecuzione correnti: ~$300/anno
- Confronta con Altre soluzioni proprietarie: $6,000/anno
- Salva $26,100 in 5 anni
Guida di configurazione manuale
Se desideri ancora impostare tutto da solo, ecco cosa devi fare:
Distribuzione Continua per iOS utilizzando Fastlane e GitHub Azioni utilizzando match
Requisiti
Prima di continuare con la guida…
- Assicurati di avere Fastlane installato sul tuo computer di sviluppo.
- Membresia del programma di sviluppo iOS.
- Desiderio di leggere 😆…
- Ecco un team di molti sviluppatori, altrimenti consigliamo di utilizzare fastlane cert per flussi di lavoro più semplici.
Importante per il prezzo

https://github.com/features/actions
Il servizio è ‘gratuito’ fino al limite, a seconda della macchina scelta.
Stiamo per utilizzare un macOS computer, potete vedere nel screenshot il suo prezzo e limiti (prezzi validi alla creazione del tutorial, potrebbero subire cambiamenti in futuro)
🔴 Una volta avvertiti dei requisiti e dei prezzi, se piace, continuiamo…
📣 In questo post supponiamo di avere già creato l'applicazione in iTunes Connect, abbiamo le certificazioni dell'ecosistema Apple, tutto verrà copiato da Fastlane!
Scendiamo in acqua 🤿
Passaggi da seguire in questo post
- Utilizzare App Store Connect API con Fastlane Match
- Requisiti
- Creazione di una chiave App Store Connect API
- Utilizzare una chiave App Store Connect API
- Copiare i file di Fastlane
- Configurare Fastlane match
- Configurare Fastlane match
1. Utilizzare App Store Connect API con Fastlane Match
A partire 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 ulteriore strato di sicurezza per il tuo ID Apple aiuta a garantire che tu sia l'unica persona che può accedere al tuo account.
Da Supporto Apple
Per iniziare con match è necessario 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 ID. emittente.
- ID. chiave.
- File di chiave o contenuto di chiave.
- Creazione di una chiave App Store Connect __CAPGO_KEEP_0__
Creating an App Store Connect API Key
Per utilizzare App Store Connect __CAPGO_KEEP_0__, Fastlane richiede
1 — Accedi a App Store Connect.
2 — Seleziona Utenti e accesso.

3 — Seleziona la scheda di integrazione.

4 — Clicca su Genera API chiave 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 ruoli autorizzazioni. Consigliamo di selezionare Gestore App.
7 — Clicca su Genera.
Un API chiave non può essere limitata ad accessi specifici per app.
Il nome della nuova chiave, l'ID chiave, un link di download e altre informazioni vengono visualizzati sulla pagina.

Qui puoi trovare tutte e tre le informazioni necessarie.
1> ID della questione.
2> ID chiave.
3> Clicca su "Scarica API Chiave" per scaricare la tua API chiave privata. Il link di download compare solo se la chiave privata non è stata ancora scaricata. Apple non conserva una copia della chiave privata. Pertanto, puoi scaricarla solo una volta.
🔴 Conserva la tua chiave privata in un luogo sicuro. Non condividere mai le tue chiavi, conserva le chiavi in un code repository o includile nelle code client-side.
Utilizza una chiave App Store Connect API
La chiave API (file p8 che scarichi), l'ID chiave e l'ID emittente sono necessari per creare il token JWT per l'autenticazione. Ci sono diverse modalità in cui queste informazioni possono essere inserite in Fastlane utilizzando l'azione nuova di Fastlane, app_store_connect_api_key. Puoi 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 delle CI, dove puoi impostare le variabili di ambiente.
Ora possiamo gestire Fastlane con la chiave App Store Connect API del canale, fantastico!
2. Copia i file Fastlane
Fastlane è una libreria Ruby creata per automatizzare le attività di sviluppo mobile comuni. Utilizzando Fastlane, puoi configurare
percorsi
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
personalizzati che raggruppano una serie di
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"])
azioni
che eseguono compiti che normalmente eseguiresti utilizzando Android Studio. Puoi fare molto con Fastlane, ma per i fini di questo tutorial, utilizzeremo solo una manciata di azioni di base. Creare un cartella Fastlane nella radice del tuo progetto e copia i seguenti file: Fastfile Appfile Configura Fastlane match Fastlane match è un nuovo approccio per la firma di iOS. Fastlane match rende facile per i team gestire i certificati e i profili di provisioning richiesti per le vostre app iOS. 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.
, ad esempio sul tuo account o organizzazione __CAPGO_KEEP_0__ personale. certificates, for example on your GitHub personal account or organization.
Seleziona quindi l'opzione #1 (Archiviazione Git).
fastlane match init
Assegna l'URL del repository creato di recente.
[01:00:00]: fastlane match supports multiple storage modes, please select the one you want to use:1. git2. google_cloud3. s3?
Ora avrai all'interno della cartella Fastlane un file denominato
[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>
Matchfile e che dovrebbe essere impostato sull'URL HTTPS del repository dei certificati. Opzionalmente, puoi anche utilizzare SSH, ma richiede un passaggio diverso da eseguire.
_git_url_Successivamente, andiamo a generare i certificati e inserisci le tue credenziali quando richiesto con Fastlane Match.
# ios/Matchfilegit_url("https://github.com/gitusername/certificates")storage_mode("git")type("appstore")
is a new approach to iOS’s __CAPGO_KEEP_0__ signing.
Sarà richiesto di inserire una passphrase. Ricordatela correttamente perché verrà utilizzata successivamente da GitHub Actions per decrittografare il tuo repository dei certificati.
fastlane match appstore
Se tutto è andato bene, dovresti vedere qualcosa di questo tipo:
[01:40:52]: All required keys, certificates and provisioning profiles are installed 🙌
Se hai incontrato problemi con GitHub e le autorizzazioni necessarie, forse questo post aiuterà a generare i token di autenticazione per git.
I certificati e i profili di provisioning generati vengono caricati nei risorse del repository dei certificati.

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
For il CI/CD importare i certificati e i profili di provisioning, ha bisogno di avere accesso al repository dei certificati. Puoi farlo generando un token di accesso personale (che dovrebbe essere utilizzato prima) che ha 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 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.
Poi sostituisci 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 la variabile var sarà impostata nelle GitHub Secrets, al posto di codificarle direttamente nel file.
Esecuzione elaborazione
In GitHub Azioni, si viene fatturati in base ai minuti utilizzati per l'esecuzione del proprio workflow CI/CD. Dall'esperienza, ci vuole circa 10-15 minuti prima che un build possa essere elaborato in App Store Connect.
Per progetti privati, il costo stimato per build può arrivare a $0.08/min x 15 min = $1.2, o più, a seconda della configurazione o delle dipendenze del proprio progetto.
Se si condividono le stesse preoccupazioni per il prezzo come faccio per i progetti privati, si può tenere il skip_waiting_for_build_processing per true.
C'è un trucco? Si deve aggiornare manualmente la conformità dell'app in App Store Connect dopo che il build è stato elaborato, per poter distribuire il build ai propri utenti.
Questo è solo un parametro facoltativo da aggiornare se si vuole risparmiare sui minuti di build per i progetti privati. Per i progetti gratuiti, non dovrebbe essere un problema per niente. Vedi tariffe.
3. Configura GitHub azioni
Configura GitHub segreti
Ever wonder dove i valori di ENV vengono da? Bene, non è più un segreto – vengono dal tuo progetto di segreti.

1. APP_STORE_CONNECT_TEAM_ID - l'ID del tuo team di App Store Connect se ne hai più di uno.
2. DEVELOPER_APP_ID - in App Store Connect, vai all'app → App Information → Scorri verso il basso alla sezione General Information del tuo app e cerca Apple ID.
3. DEVELOPER_APP_IDENTIFIER - l'ID dell'identificatore del pacchetto del tuo app.
4. DEVELOPER_PORTAL_TEAM_ID - l'ID del tuo team del portale dello sviluppatore se ne hai più di uno.
5. FASTLANE_APPLE_ID - l'ID Apple o l'indirizzo email del developer che utilizza 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>, ad esempio. 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 🔺Chiave ID.
11. APPLE_ISSUER_ID — App Store Connect API Chiave 🔺ID rilasciatore.
12. APPLE_KEY_CONTENT — App Store Connect API Chiave 🔺 File chiave o contenuto della chiave in .p8 verificare, — App Store Connect __CAPGO_KEEP_0__ Chiave 🔺Contenuto della chiave
13. CERTIFICATE_STORE_URL — L'URL del tuo repository delle chiavi Match (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 tag di GitHub , se hai bisogno di automatizzare i tag, si prega di fare riferimento aCostruzione automatica e rilascio con __CAPGO_KEEP_0__ actions Automatic build and release with GitHub actions Automatic build and release with __CAPGO_KEEP_0__ actions
Allora questo workflow estrarrà le dipendenze NodeJS, le installerà e costruirà il tuo'applicazione JavaScript.
Ogni volta che invii un nuovo commit, verrà costruito un rilascio in TestFlight.
La tua App non deve utilizzare Ionic, solo la base Capacitor è obbligatoria, può avere vecchi moduli Cordova, ma il plugin JS Capacitor dovrebbe essere preferito.
5. Attiva il workflow
Crea un Commit
Fai un commite dovresti vedere il workflow attivo nel repository.
Attiva il workflow
Inserisci i nuovi commit nella branca main o development per attivare il workflow.

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

Puoi distribuire dal tuo computer 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 un file chiamato .env, nello stesso percorso di my_project_path/fastlane File Fastfile, per poter creare lo stesso segreto proprietà trovate nel nostro _GitHub, a_s di seguito:
file .env per il deploy da macchina locale
Ora, puoi andare al terminale e lanciare il Fastlane da tua macchina:
fastlane closed_beta
❌ Informazioni essenziali sul .env file, come preferiamo non esporre questi dati, dobbiamo aggiungerli nel nostro .gitignore, qualcosa del tipo: ❌
fastlane/*.env
Dovrebbe funzionare allo stesso modo di quanto accade dalle GitHub Actions sul computer remoto, ma sul nostro computer locale. 🍻

Esecuzione del terminale: $ 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 Actions.
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
Se ancora hai bisogno di costruire sul tuo dispositivo, devi aggiungerli manualmente al provisionning.
Collega il tuo dispositivo al tuo Mac e apri il menu del dispositivo
Poi copia il tuo identificatore
E poi avvia il comando:
fastlane register_new_device
ti 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 sugli articoli seguenti: