Neuigkeiten von trion.
Immer gut informiert.

Upload einer NativeScript-App zum Apple App Store mittels Gitlab-CI

GitLab

In den vorherigen NativeScript-Artikeln haben wir zunächst ein kleines HelloWorld-NativeScript-Projekt erstellt und dieses dann auf einem GitLab-Server in einer Pipeline gebaut.

Nun wollen wir einen Schritt weiter gehen und das erstellte Projekt über die GitLab-Pipeline zu App Store Connect hochladen, um damit die Basis für Continuous Delivery zu legen.

App Store Connect ist das Webportal von Apple zur Verwaltung von Apps. Über das Portal werden unter anderem neue Apps definiert, Apps für Tester bereitgestellt, Apps zur Veröffentlichung bei Apple vorgelegt und Versionen freigegeben. Zugangsvoraussetzung ist ein Apple Developer Account.

Wichtig: Damit neue Apps erstellt werden können, ist ein Developer Account mit der Rolle App-Manager erforderlich. Außerdem empfiehlt es sich einen eigene Apple-ID für die Verwendung in der Gitlab-Pipeline zu erstellen, die nur die Rolle Developer hat.

Bundle-ID

Als Ersten passen wir die Bundle-ID für das Testprojekt an. Die Bundle-ID dient unter iOS als eindeutiger Bezeichner für die App. Nachdem die App einmal hochgeladen wurde, kann die Bundle-ID nicht mehr in App Store Connect geändert werden.

In NativeScript-Projekten entspricht die Bundle-ID dem Key nativescript.id, der in der Datei package.json definiert wird. Wir setzen diesen Wert auf de.trion.nativescript.HelloWorld:

Anpassung der Bundle-ID in NativeScript package.json Konfiguration
{
  "nativescript": {
    "id": "de.trion.nativescript.ios.HelloWorld",
    "tns-ios": {
      "version": "5.3.1"
    }
  },

Zertifikate

Für die lokale Installation und das Hochladen von Apps in den Apple App Store sind zwei verschiedene Zertifikate erforderlich, mit denen die App bzw. der Code signiert wird: Das Development- und das Distribution-Zertifikat.

Das Development-Zertifikat ist erforderlich, damit die App während der Entwicklung auf einem iOS installiert werden kann. Voraussetzung für den Upload der iOS-App in App Store Connect ist die Signierung mit einem Distribution-Zertifikat.

Die Erstellung der Zertifikate erfolgt am Einfachsten über Xcode. Dazu sind folgende Schritt ausführen:

  1. Xcode starten

  2. Über das Menü die Preferences öffnen

  3. Auf dem Reiter Accounts die entsprechende Apple ID auswählen bzw. falls erforderlich hinzufügen

  4. Manage Certificates…​ auswählen

  5. Über das +-Symbol sowohl ein iOS-Development- als auch ein iOS-Distribution-Zertifikat erstellen

  6. Damit wir das Distribution-Zertifikat später in unser Pipeline verwenden können, exportieren wir dieses nun in eine Datei.
    Dazu mit der rechten Maustaste auf das Distribution-Zertifikat klicken und Export auswählen.
    Als Speicherort definieren wir die Datei distribution-cert.p12 im Hauptordner des Projektverzeichnisses und geben ein Passwort an.

Alternativ kann die Erstellung der Zertifikate auch manuell erfolgen, wie hier beschrieben: Create a certificate signing request.

Die erstellten Certificate Signing Requests werden dann im Developer Portal zur Erstellung von Apple Development- und Apple Distribution-Zertifikat im Developer Portal verwendet: https://developer.apple.com/account/resources/certificates/add

Die beiden Zertifikate sollten danach im Apple Developer Portal hinterlegt sein und unter https://developer.apple.com/account/resources/certificates/list mit dem jeweiligen Typ angezeigt werden.

Lokale Installation auf einem iOS-Device

Nachdem das Development Zertifikat registriert und eingerichtet ist, können wir die App auf einem iOS-Device installieren. Dazu muss das iOS-Device über USB mit dem Mac verbunden sein.

Um die Device-Nummer zu ermitteln, die wir für die Installation der App benötigen, können wir mit dem Befehl tns devices die verfügbaren Geräte auflisten.

Anzeige der für NativeScript verfügbaren Geräte
$  tns devices

Connected devices & emulators
Searching for devices...
┌───┬─────────────┬──────────┬───────────────────────────┬────────┬───────────┐
│ # │ Device Name │ Platform │ Device Identifier         │ Type   │ Status    │
│ 1 │ test-iphone │ iOS      │ 00001234-0XXXXXXXXXXXXXXX │ Device │ Connected │
└───┴─────────────┴──────────┴───────────────────────────┴────────┴───────────┘

Danach kann die App mit dem Befehl tns deploy ios --device 1 auf dem iOS-Gerät mit der Nummer 1 installiert werden. Während der Installation muss noch das Development Team ausgewählt werden. Die Einstellungen sichern wir dann für den späteren CI-Build direkt in der Datei build.xcconfig:

Auswahl des Development Teams mit NativeScript für iOS
$ tns deploy ios --device 1

...

Building project...
Xcode requires a team id to be specified when building for device.
You can specify the team id by setting the DEVELOPMENT_TEAM setting in build.xcconfig file located in App_Resources folder of your app, or by using the --teamId option when calling run, debug or livesync commands.
? Found multiple development teams, select one: trion development GmbH (XXXXXXXXXX)
? Do you want to make teamId: XXXXXXXXX a persistent choice for your app? Yes, set the DEVELOPMENT_TEAM setting in build.xcconfig file.
Xcode build...

...

Installing on device 00001234-0XXXXXXXXXXXXXXX...
Successfully installed on device with identifier '00001234-0XXXXXXXXXXXXXXX'.

Danach finden wir die App auf dem Homescreen des angeschlossenen iOS-Devices und können diese starten.

TestFlight

Im nächsten Schritt wollen wir die App über TestFlight bereitstellen. Dazu müssen wir zuerst eine App ID erstellen und diese anschließend über ein Provisioning Profile in App Store Connect hochladen.

Erstellen einer App ID

Die App ID besteht aus zwei Teilen: Team ID (App ID Prefix) und App ID (App ID Suffix). Die Team ID wird durch Apple vorgegeben. Das App ID Suffix ist eine Zeichenkette, die entweder die Bundle-ID einer einzelnen App beschreibt, wie z.B. de.trion.nativescript.ios.HelloWorld, oder eine Gruppe von Apps über eine Wildcard, wie de.trion.nativescript.ios.* . Der App ID können wir im nächsten Schritt dann einem Provisioning Profile zuordnen.

App IDs werden über das Apple Developer Portal erstellt unter dem Punkt Identifiers:

  1. Aufruf von https://developer.apple.com/account/resources/identifiers/add/bundleId

  2. Als Typ App IDs auswählen

  3. Unter App ID Description eine Beschreibung einfügen, wie z.B. HelloWorld NativeScript App

  4. Bundle ID definieren - Wir wählen hier ein explizites Suffix: de.trion.nativescript.ios.HelloWorld

  5. Optional: App Services auswählen (Brauchen wir für unser HelloWorld-Projekt nicht anzupassen)

  6. Die Eingaben mit Continue bestätigen

  7. Zuletzt die Erstellung über den Register-Button bestätigen

Als nächstes benötigen wir ein Privisioning Profile.

Provisioning Profiles

Für die Installation einer iOS App auf einem iOS Device ist ein Provisioning Profile erforderlich. Es definitiert das Zertifikat, das zur Signierung der App verwendet werden soll, die App ID und die Zielgeräte auf denen die App installiert werden soll. Dabei wird, ähnlich wie bei den Zertifikaten, zwischen Development- und Distribution-Provisioning Profiles unterschieden.

Development-Profiles sind nur für die lokale Installation und den Upload zu App Store Connect einsetzbar und können mehrere Developer Zertifikate enthalten. Für die Veröffentlichung einer App über den App Store ist dagegen ein Distribution-Profile erforderlich. Ein Distribution-Profile verwendet immer genau ein Distribution-Zertifikat.

Um unser Testprojekt nun über Testflight bereitstellen zu können, verwenden wir direkt ein Distribution-Provisioning-Profile, da wir sonst den erstellten Build nicht veröffentlichen können. Das Distribution-Provisioning-Profile wird über das Apple Developer Portal im Menüpunkt Profiles erzeugt:

  1. Aufruf von https://developer.apple.com/account/resources/profiles/add

  2. Im Distribution-Bereich den Typ App Store auswählen und mit Continue bestätigen

  3. Die vorher erstellte App ID auswählen und mit Continue bestätigen

  4. Im nächsten Schritt ein gültiges Distribution-Zertifikat auswählen und mit Continue bestätigen

  5. Nun ein Profile-Namen vergeben und die Erstellung mit Continue abschließen

  6. Zuletzt laden wir das Production-Provisioning-Profile über den Download-Button herunter und speichern es unter dem Dateinamen production.mobileprovision ebenfalls im Hauptverzeichnis unseres Testprojektes.
    Die Datei benötigen wir später für den Upload zu App Store Connect über die Pipeline.

App Specific Passwort für Apple ID

Für den nachfolgenden Upload der iOS App mittels NativeScript-CLI ist ein anwendungsspezifisches Passwort erforderlich. Dieses muss über die Apple-ID Verwaltung im Bereich Sicherheit erstellt werden.

Erstellen der iOS App in App Store Connect

Zuletzt muss die App noch in App Store Connect angelegt werden. Dazu den Bereich Meine Apps in App Store Connect öffnen und über das +-Symbol eine neue App für die iOS-Plattform definieren und dabei die vorher definierte Bundle-ID auswählen. Als SKU kann auch die Bundle-ID verwendet werden.

iOS App in App Store Connect
Abbildung 1. Anlegen einer neuen iOS App in Apple App Store Connect

Upload der iOS-App

Jetzt sind alle Vorbereitungen für den Upload unseres Testprojektes vorgenommen und wir können mit dem Kommando tns publish ios <appleID> <password> --team-id <teamid> den Upload starten.

Das Provisioning-Profile wird automatisch ermittelt, kann jedoch auch als Parameter nach dem Passwort über die ID angegeben werden.

Upload der NativeScript iOS App
$ tns publish ios [email protected] XXXX-XXXX-XXXX-XXXX --team-id XXXXXXXXXZ

...

Package Summary:

1 packages were uploaded successfully:
...

Hinweis: Die Team-ID kann in den Account-Einstellungen im Developer Portal nachgesehen werden.

Und nun heißt es: Warten! Der Build erscheint trotz erfolgreichem Upload nicht direkt in App Store Connect. Erst wenn der Upload erfolgreich verarbeitet wurde, erhält man eine E-Mail über die registrierte E-Mailadresse der Apple-ID. Bei der Erstellung des Artikels hat es ca. 20 Minuten gedauert, bis die E-Mail eintraf.

Export Compliance

Damit die App über App Store Connect (TestFlight oder App Store) auf ein iOS-Gerät installiert werden kann, müssen die Fragen zur Export Compliance beantwortet werden. Dabei ist zu beachten, dass die Fragen für jeden hochgeladenen Build angegeben werden müsssen. Dies kann entweder manuell über App Store Connect erfolgen oder die Informationen wird in den Build eingefügt.

Der Dialog zur manuellen Angabe befindet sich in App Store Connect unter Meine App → <AppName> → TestFlight → iOS rechts neben der Versiosnummer.
Dort auf das Ausrufezeichen neben Fehlende Export Compliance klicken.

Über den Parameter linkl:https://developer.apple.com/documentation/bundleresources/information_property_list/itsappusesnonexemptencryption[ITSAppUsesNonExemptEncryption], der in der Datei Info.plist definiert werden kann, können wir die Information in den Build einpflegen.
Da unsere Test-App keine Verschlüsselung nutzt, können wir den Wert wie folgt auf false setzen:

app/App_Resources/iOS/Info.plist
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    ...
    <key>ITSAppUsesNonExemptEncryption</key>
    <false/>
</dict>
</plist>

Die Datei Info.plist ist unter app/App_Resources/iOS/Info.plist im NativeScript-Projekt zu finden. Weitere Informationen zum dem Thema finden sich hier: https://developer.apple.com/documentation/security/complying_with_encryption_export_regulations

Benutzerzuordnung

Wenn der Build erfolgreich verarbeitet wurde, kann die iOS-App über TestFlight an andere Teammitglieder oder externe Benutzer verteilt werden. Die Konfiguration erfolgt wieder über App Store Connect. Nachdem dort die App ausgewählt wurde, kann unter dem Reiter TestFlight die App an Tester verteilt werden.

Gitlab-Pipeline

Der letzte Schritt ist nun der Upload der App über die Gitlab-Pipeline in App Store Connect. Der Einfachheit halber laden wir die App bei jedem Commiit hoch.
In der Praxis wird das zu unnötigen vielen Builds in App Store Connect führen. Die Bedingung für den Upload sollte daher in der praktischen Anwendung an die Arbeitsweise des Teams angepasst werden.
Ein Möglichkeit wäre, den Upload nur durchzuführen, wenn der aktuelle Commit mit einem Versions-Tag versehen ist, das dann auch als Versionsnummern verwenden wird.

Version in Info.plist anpassen

Da pro Versionsnummer nur ein Upload in App Store Connect möglich ist, müssen wir im ersten Schritt sicherstellen, dass jeder Commit eine eindeutige Versionsnummer erhält. Nach den Apple-Vorgaben müssen die Versionsnummern von CFBundleVersion und CFBundleShortVersionString aus drei Ziffernblöcken bestehen, die durch einen Punkt getrennt sind.
Das Schema sieht damit so aus: [Major].[Minor].[Patch]

Als Patch-Version verwenden wir die Buildnummer. Major- und Minor-Version definieren wir manuell. Dazu setzen wir im ersten Schritt die Versionen für CFBundleVersion und CFBundleShortVersionString in der Datei app/App_Resources/iOS/Info.plist auf die Versionsnummer 1.0. Über die Pipeline hängen wir anschließend die Buildnummer an den String an. Die Datei Info.plist hat dann folgenden Inhalt:

Inhalt der Info.plist mit Platzhaltern
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>CFBundleDevelopmentRegion</key>
    <string>en</string>
    <key>CFBundleDisplayName</key>
    <string>${PRODUCT_NAME}</string>
    <key>CFBundleExecutable</key>
    <string>${EXECUTABLE_NAME}</string>
    <key>CFBundleInfoDictionaryVersion</key>
    <string>6.0</string>
    <key>CFBundleName</key>
    <string>${PRODUCT_NAME}</string>
    <key>CFBundlePackag<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>CFBundleDevelopmentRegion</key>
    <string>en</string>
    <key>CFBundleDisplayName</key>
    <string>${PRODUCT_NAME}</string>
    <key>CFBundleExecutable</key>
    <string>${EXECUTABLE_NAME}</string>
    <key>CFBundleInfoDictionaryVersion</key>
    <string>6.0</string>
    <key>CFBundleName</key>
    <string>${PRODUCT_NAME}</string>
    <key>CFBundlePackageType</key>
    <string>APPL</string>
    <key>CFBundleShortVersionString</key>
    <string>1.0</string>
    <key>CFBundleSignature</key>
    <string>????</string>
    <key>CFBundleVersion</key>
    <string>1.0</string>
    <key>LSRequiresIPhoneOS</key>
    <true/>
    <key>UILaunchStoryboardName</key>
    <string>LaunchScreen</string>
    <key>UIRequiresFullScreen</key>
    <true/>
    <key>UIRequiredDeviceCapabilities</key>
    <array>
        <string>armv7</string>
    </array>
    <key>UISupportedInterfaceOrientations</key>
    <array>
        <string>UIInterfaceOrientationPortrait</string>
        <string>UIInterfaceOrientationLandscapeLeft</string>
        <string>UIInterfaceOrientationLandscapeRight</string>
    </array>
    <key>UISupportedInterfaceOrientations~ipad</key>
    <array>
        <string>UIInterfaceOrientationPortrait</string>
        <string>UIInterfaceOrientationPortraitUpsideDown</string>
        <string>UIInterfaceOrientationLandscapeLeft</string>
        <string>UIInterfaceOrientationLandscapeRight</string>
    </array>
    <key>UIStatusBarStyle</key>
    <string>UIStatusBarStyleLightContent</string>
    <key>UIViewControllerBasedStatusBarAppearance</key>
    <false/>
    <key>ITSAppUsesNonExemptEncryption</key>
    <false/>
</dict>
</plist>eType</key>
    <string>APPL</string>
    <key>CFBundleShortVersionString</key>
    <string>1.0</string>
    <key>CFBundleSignature</key>
    <string>????</string>
    <key>CFBundleVersion</key>
    <string>1.0</string>
    <key>LSRequiresIPhoneOS</key>
    <true/>
    <key>UILaunchStoryboardName</key>
    <string>LaunchScreen</string>
    <key>UIRequiresFullScreen</key>
    <true/>
    <key>UIRequiredDeviceCapabilities</key>
    <array>
        <string>armv7</string>
    </array>
    <key>UISupportedInterfaceOrientations</key>
    <array>
        <string>UIInterfaceOrientationPortrait</string>
        <string>UIInterfaceOrientationLandscapeLeft</string>
        <string>UIInterfaceOrientationLandscapeRight</string>
    </array>
    <key>UISupportedInterfaceOrientations~ipad</key>
    <array>
        <string>UIInterfaceOrientationPortrait</string>
        <string>UIInterfaceOrientationPortraitUpsideDown</string>
        <string>UIInterfaceOrientationLandscapeLeft</string>
        <string>UIInterfaceOrientationLandscapeRight</string>
    </array>
    <key>UIStatusBarStyle</key>
    <string>UIStatusBarStyleLightContent</string>
    <key>UIViewControllerBasedStatusBarAppearance</key>
    <false/>
    <key>ITSAppUsesNonExemptEncryption</key>
    <false/>
</dict>
</plist>

UUID des Provisioning Profile ermitteln

Ein paar Schritte zuvor haben wir ein Production Provisioning Profile erstellt und dieses in der Datei production.mobileprovision im Projektordner gespeichert. Für den Upload der App mittels NativeScript-CLI benötigen wir die UUID dieses Profils. Dazu öffnen wir die Datei mit einem Texteditor und suchen nach dem String UUID. In der Zeile befindet sich die UUID als String.

Build Pipeline für iOS NativeScript

Nun haben wir alle Vorbereitungen getroffen, um den Upload über die Pipeline durchführen zu können.

In der Pipeline müssen nun die gesammelten Informationen genutzt werden, damit die App mit dem korrekten Provisioning-Profile und Production-Zertifikat gebaut wird.
Bei den nun folgenden Schritten fehlt die Variablen-Definition, diese werden in der folgenden GitLab Pipeline gesetzt:

  1. Das Provisioning-Profile können wir auf dem CI-Runner mit dem Befehl open production.mobileprovision in macOS importieren.

  2. Der Import des Production-Zertifikats in den Schlüsselbund (engl. keychain) des Benutzers ist etwas aufwendiger und erfolgt durch folgende Befehle:

    $ security -v unlock-keychain -p ${MACOS_USER_PASSWORD} ${HOME}/Library/Keychains/login.keychain-db
    $ security set-key-partition-list -S "apple-tool:,apple:" -s -k ${MACOS_USER_PASSWORD} ${HOME}/Library/Keychains/login.keychain-db
    $ security import ${PRODUCTION_CERT_FILE} -k ${HOME}/Library/Keychains/login.keychain-db -P ${PRODUCTION_CERT_PASSWORD} -T /usr/bin/codesign -T /Applications/Xcode.app

    Zunächst wird der Schlüsselbund mit dem Passwort des Benutzers entsperrt. Danach sind Anpassungen erforderlich, damit das Programm codesign von Apple ohne manuelle Bestätigung auf die Keychain zugreifen kann. Der letzte Befehl importiert dann das Zertifikat in den Schlüsselbund.

  3. An die Versionsnummer in der Datei Info.plist müssen wir noch die Buildnummer anhängen. Dies erfolgt über folgende Befehle:

    $ /usr/libexec/PlistBuddy -c "Set CFBundleVersion $(/usr/libexec/PlistBuddy -c "Print CFBundleVersion" ${INFO_PLIST_PATH}).${CI_PIPELINE_ID}" ${INFO_PLIST_PATH}
    $ /usr/libexec/PlistBuddy -c "Set CFBundleShortVersionString $(/usr/libexec/PlistBuddy -c "Print CFBundleShortVersionString" ${INFO_PLIST_PATH}).${CI_PIPELINE_ID}" ${INFO_PLIST_PATH}
  4. Beim Build der App soll nun eine IPA-Datei generiert werden, die mit dem Production-Provisioning-Profile signiert wurde. Dafür müssen wir den Build wie folgt anpassen:

    $ tns build ios --release --provision ${PROVISION_PROFILE_ID} --for-device --bundle --copy-to ${IPA_FILE_NAME}
  5. In einer neuen Stage upload:appstore können wir unter Verwendung einer berechtigten Apple-ID nun den Upload der vorher erstellten IPA-Datei durchführen:

    $ tns publish ios ${APPLE_ID} ${APPLE_ID_PASSWORD} --ipa ${IPA_FILE_NAME}

Ergebnis: GitLab-Pipeline .gitlab-ci.yml

Insgesamt hat die Datei .gitlab-ci.yml, in der die Gitlab-Pipeline definiert ist, nun folgenden Inhalt:

stages:
  - build
  - upload

variables:
  APPLE_ID: [email protected]
  APPLE_ID_PASSWORD: Secure12345

  IPA_FILE_NAME: helloworld.ipa
  INFO_PLIST_PATH: app/App_Resources/iOS/Info.plist

  MACOS_USER_PASSWORD: secure

  PROVISION_PROFILE_ID: 266d6214-9e74-478a-b0c7-ed68b18d6d3b
  PRODUCTION_CERT_FILE: distribution-cert.p12
  PRODUCTION_CERT_PASSWORD: secure1337
  PRODUCTION_PROVISIONING_PROFILE: production.mobileprovision

cache:
  key: ${CI_COMMIT_REF_SLUG}
  paths:
    - node_modules

build:ios:
  stage: build
  tags:
    - macos
  artifacts:
    name: 'IPA'
    expire_in: 1 day
    paths:
      - ${IPA_FILE_NAME}
  script:
    - open ${HOME}/Library/Keychains/login.keychain-db
    # This command sets the PartitionIDs (items after -S separated by comma) for keys that can sign (-s) for a specific keychain. The actual partitionID that allows the codesigning is apple:.
    - security -v unlock-keychain -p ${MACOS_USER_PASSWORD} ${HOME}/Library/Keychains/login.keychain-db
    - security set-key-partition-list -S "apple-tool:,apple:" -s -k ${MACOS_USER_PASSWORD} ${HOME}/Library/Keychains/login.keychain-db
    - security import ${PRODUCTION_CERT_FILE} -k ${HOME}/Library/Keychains/login.keychain-db -P ${PRODUCTION_CERT_PASSWORD} -T /usr/bin/codesign -T /Applications/Xcode.app
    - /usr/libexec/PlistBuddy -c "Set CFBundleVersion $(/usr/libexec/PlistBuddy -c "Print CFBundleVersion" ${INFO_PLIST_PATH}).${CI_PIPELINE_ID}" ${INFO_PLIST_PATH}
    - /usr/libexec/PlistBuddy -c "Set CFBundleShortVersionString $(/usr/libexec/PlistBuddy -c "Print CFBundleShortVersionString" ${INFO_PLIST_PATH}).${CI_PIPELINE_ID}" ${INFO_PLIST_PATH}
    - cat ${INFO_PLIST_PATH}
    - tns build ios --release --provision ${PROVISION_PROFILE_ID} --for-device --bundle --copy-to ${IPA_FILE_NAME}

upload:appstore:
  stage: upload
  tags:
    - macos
  dependencies:
    - build:ios
  script:
    - tns publish ios ${APPLE_ID} ${APPLE_ID_PASSWORD} --ipa ${IPA_FILE_NAME}

Hier müssen lediglich die Variablen im variables-Block entsprechend angepasst werden. Danach werden die Änderungen gepusht und die Pipeline startet automatisch. Nach der obligatorischen Wartezeit bis der Build bei Apple erfolgreich verarbeitet wurde, steht eine neue Version der Test-App in TestFlight bereit.

Hinweis: Anstatt die erforderlichen Informationen, wie Provisioning-Profile, Passwörter oder Zertitikate ins Projekt einzuchecken, können diese auch vom Build-Admin verwaltet und in Gitlab bereitgestellt werden. In dem Fall muss sich das Entwicklungsteam nur mit dem Admin über die Namen der Umgebungsvariablen einig werden.

Ergebnis

Wir haben nun eine Gitlab-Pipeline für ein NativeScript-Projekt erstellt, die mit nur einem Commit die App baut und bei App Store Connect hochlädt. Die Pipeline ermöglichst es dem Entwicklungs-Team ihre Änderungen ohne viel Aufwand an Tester bereitzustellen.




Zu den Themen NativeScript, Ansible und Angular bieten wir sowohl Beratung, Entwicklungsunterstützung als auch passende Schulungen an:

Auch für Ihren individuellen Bedarf können wir Workshops und Schulungen anbieten. Sprechen Sie uns gerne an.

Feedback oder Fragen zu einem Artikel - per Twitter @triondevelop oder E-Mail freuen wir uns auf eine Kontaktaufnahme!

Los geht's!

Bitte teilen Sie uns mit, wie wir Sie am besten erreichen können.