Zum Inhalt springen

fastlane & App Store Connect

Ticket n12 baut die Release-Maschinerie auf: Alles, was App Store Connect braucht — Screenshots, Metadaten, Builds — wird eine Datei im Repo oder eine Lane, die eine erzeugt. Das folgende Setup existiert in 4Notice wie beschrieben; der erste vollständige Screenshot-Lauf und der erste Upload stehen noch aus (wo die Spur endet).

fastlanes Verhalten ändert sich zwischen Versionen, also ist die Version ein Repo-Fakt, kein Maschinen-Fakt:

# Gemfile
source "https://rubygems.org"
gem "fastlane", "~> 2.236"

Einmal bundle install, danach läuft jeder Aufruf als bundle exec fastlane <lane> — dieselbe Version auf jeder Maschine und in jedem Agent-Lauf.

Die Regel des Board-Workflows — niemals Secrets in Repo-Dateien — greift hier mit voller Härte, denn fastlane braucht einen App-Store-Connect-API-Key. Das Fastfile liest ihn ausschließlich aus der Umgebung:

def asc_api_key
app_store_connect_api_key(
key_id: ENV.fetch("ASC_KEY_ID"),
issuer_id: ENV.fetch("ASC_ISSUER_ID"),
key_filepath: ENV.fetch("ASC_KEY_PATH"), # .p8 außerhalb des Repos
...
)
end

Eine check_asc-Lane schlägt früh fehl und nennt die fehlende Variable; .env ist gitignored. Das Appfile enthält nur die zwei ohnehin öffentlichen Werte: Bundle-Identifier und Team-ID.

fastlane snapshot fährt die Screenshot-Matrix — in 4Notice: zwei Geräte × sieben Sprachen, einmal deklariert im Snapfile:

devices(["iPhone 17", "iPad Pro 13-inch (M5)"])
languages(["en-US", "de-DE", "fr-FR", "es-ES", "it", "ja", "zh-Hans"])
launch_arguments(["-uitest -uitest-reset -uitest-demo"])

Zwei Entscheidungen machen das tragfähig:

  • Demo-Inhalte werden im Code gesät. Das Startargument -uitest-demo füllt die vier Zettel mit Beispieltext — und der Beispieltext liegt im selben String-Katalog wie die UI (demo.*-Keys). Eine Seeding-Funktion, und die Screenshots jeder Sprache zeigen übersetzte Zettel.
  • Die Aufnahmen sind ein gewöhnlicher XCUITest. ScreenshotUITests wischt durch die Zettel und ruft je Motiv snapshot("01-yellow"). fastlane wiederholt das pro Gerät und Sprache.

Der Lauf ist als Projekt-Action registriert und damit vom Board aus startbar — mit den Kosten in der Beschreibung: Die volle Matrix dauert rund 30 Minuten.

Der Store-Eintrag wird nicht in ein Webformular getippt. Er liegt in fastlane/metadata/<lang>/name.txt, subtitle.txt, description.txt, keywords.txt, release_notes.txt — für alle sieben Sprachen, versioniert wie jede andere Quelle. Felder, deren echte Werte noch fehlen (support_url, privacy_url), werden leer committet statt mit Platzhaltern gefüllt. Eine metadata_dry_run-Lane lädt nur die Metadaten hoch (deliver mit skip_binary_upload) — so lässt sich der Eintrag iterieren, ohne etwas zu bauen.

Eine Lane pro Plattform, gleiche Form: Xcode-Projekt neu erzeugen, archivieren, hochladen.

lane :beta do
check_asc
sh("cd .. && xcodegen generate --quiet")
build_app(scheme: "FourNotice-iOS", export_method: "app-store", ...)
upload_to_testflight(...)
end

Vor jedem Upload läuft der importierte release-checks-Skill — Plist-Keys, Entitlements, verwaiste Strings — dieselben drei Verträge, die seit dem Import jedes Ticket absichern.

Das ist zum Zeitpunkt dieses Textes der praktizierte Stand: Die Lanes, der Test und die Metadaten-Dateien existieren und sind die oben zitierten. Die erste vollständige Screenshot-Matrix, der App-Store-Connect-Eintrag und der erste TestFlight-Upload sind noch nicht gelaufen — dieses Kapitel geht weiter, und das Submission-Kapitel beginnt, sobald sie es sind.