App Store-screenshots automatiseren in CI/CD
Een praktische, volledige pipeline voor het genereren van App Store- en Google Play-screenshots vanuit je CI-systeem met Fastlane, GitHub Actions en Bitrise — inclusief concrete configuratie die je rechtstreeks in je repo kunt plakken.
Samenvatting
Maak ruwe app-screenshots in je testrunner, stuur ze naar de Screenshots.live API met een template-ID en een lijst met locales, en Fastlane schrijft de gerenderde, geframede en gelokaliseerde uitvoer terug in je repo. Fastlane deliver / supply pusht ze naar de stores. De volledige pipeline draait bij een tag-push of nightly cron in minder dan vijf minuten.
Waarom screenshots überhaupt automatiseren?
De meeste teams behandelen App Store- en Google Play-screenshots als eenmalige, handgemaakte assets: een ontwerper maakt ze in Figma, een marketeer plaatst ze in App Store Connect, en niemand raakt ze meer aan tot het volgende grote redesign. Dat model breekt zodra je naar meer dan één locale uitlevert. Met 13 ondersteunde locales, drie verplichte iPhone-formaten, twee iPad-formaten plus phone en tablet op Google Play, kijk je tegen meer dan 100 PNG-bestanden aan voor één enkele release. Vermenigvuldig dat met elke tekstwijziging, elke promotie en elke A/B-testvariant en de rekensom houdt geen stand.
Door te automatiseren in CI/CD worden screenshots een build-artefact zoals elke andere binary. Ze zijn versiebeheerd, reproduceerbaar en gekoppeld aan een commit. Wanneer marketing een onderschrift wijzigt, herbouwt de pipeline elke locale en uploadt ze — geen handmatige Photoshop-sessies, geen drift tussen talen, geen afwijzing bij indiening omdat iemand een 6,7-inch iPhone-variant vergat.
Hoe ziet de pipeline er nu eigenlijk uit?
De vorm van een schone CI-screenshotpipeline bestaat uit drie fasen: capture, render en deliver. Capture is je bestaande UI-testsuite — XCUITest op iOS, Espresso op Android, Detox of Maestro voor React Native. Render is één Screenshots.live API-aanroep per locale die je ruwe frames samenstelt op een template die je eenmalig hebt ontworpen. Deliver bestaat uit de bestaande Fastlane deliver- en supply-acties die je al gebruikt om binaries te pushen.
De Screenshots.live REST-rendering-API is de hoeksteen. Je stuurt ruwe screenshots eenmalig in en krijgt elk apparaatformaat, elke locale en elke variant terug — volledig geframed, voorzien van onderschriften en gelokaliseerd. Geen headless browser, geen Puppeteer, geen handmatig formaat aanpassen.
Hoe koppel je dit aan Fastlane?
Fastlane is dé tool voor releaseautomatisering op iOS en Android. We leveren een officiële Fastlane-plugin die de rendering-API in één enkele actie verpakt. Installeer hem vanuit de root van je project:
fastlane add_plugin screenshotsliveVoeg vervolgens een lane toe aan je Fastfile die captured, rendert en de gerenderde uitvoer wegschrijft:
lane :render_screenshots do
# 1. Capture raw frames with XCUITest
capture_screenshots(
workspace: "MyApp.xcworkspace",
scheme: "MyAppUITests",
devices: ["iPhone 16 Pro Max", "iPad Pro 12.9-inch"],
languages: ["en-US", "de-DE", "es-ES", "fr-FR", "pt-BR"]
)
# 2. Send raw frames to Screenshots.live, get framed PNGs back
screenshotslive_render(
api_token: ENV["SCREENSHOTSLIVE_API_TOKEN"],
template_id: "tpl_app_release_v3",
input_dir: "./fastlane/screenshots",
output_dir: "./fastlane/rendered",
locales: ["en", "de", "es", "fr", "pt"],
devices: ["iphone-6.7", "iphone-6.1", "ipad-12.9"]
)
# 3. Push to App Store Connect
deliver(
screenshots_path: "./fastlane/rendered",
skip_binary_upload: true,
skip_metadata: false
)
endDe plugin verzorgt uploads, het pollen op voltooiing en parallelle downloads. Een typische render met 5 locales en 3 apparaten is in 60 tot 90 seconden klaar.
Hoe draai je dit op GitHub Actions?
Plaats de lane in een workflowbestand. De onderstaande workflow draait bij elke tag-push die overeenkomt met v* en op een nachtelijk schema, dus een handmatige git tag v1.2.0 && git push --tags is alles wat je nodig hebt om een nieuwe render te triggeren.
name: Render Store Screenshots
on:
push:
tags: ["v*"]
schedule:
- cron: "0 4 * * *" # nightly at 04:00 UTC
workflow_dispatch:
jobs:
render:
runs-on: macos-14
steps:
- uses: actions/checkout@v4
- uses: ruby/setup-ruby@v1
with:
ruby-version: "3.2"
bundler-cache: true
- name: Render screenshots
env:
SCREENSHOTSLIVE_API_TOKEN: ${{ secrets.SCREENSHOTSLIVE_API_TOKEN }}
FASTLANE_USER: ${{ secrets.FASTLANE_USER }}
FASTLANE_PASSWORD: ${{ secrets.FASTLANE_PASSWORD }}
run: bundle exec fastlane render_screenshots
- name: Upload rendered artifacts
uses: actions/upload-artifact@v4
with:
name: store-screenshots
path: fastlane/rendered/Voor teams die liever een GitHub Action zonder Fastlane gebruiken, publiceren we ook een standalone GitHub Action die rechtstreeks met de API praat:
- uses: Screenshots-Live/render-screenshots-action@v1
with:
api-token: ${{ secrets.SCREENSHOTSLIVE_API_TOKEN }}
template-id: tpl_app_release_v3
locales: en,de,es,fr,pt,it,nl
devices: iphone-6.7,iphone-6.1,ipad-12.9
output-dir: ./screenshotsEn hoe zit het met Bitrise?
Bitrise-gebruikers krijgen dezelfde lane via de bestaande Fastlane-stap. Voeg een Secret met de naam SCREENSHOTSLIVE_API_TOKEN toe in je Bitrise-workspace en plaats dit vervolgens in je bitrise.yml:
workflows:
render-screenshots:
steps:
- activate-ssh-key@4: {}
- git-clone@8: {}
- script@1:
title: Install Fastlane plugins
inputs:
- content: |-
#!/usr/bin/env bash
bundle install
bundle exec fastlane add_plugin screenshotslive
- fastlane@3:
inputs:
- lane: render_screenshots
- work_dir: "$BITRISE_SOURCE_DIR"
- deploy-to-bitrise-io@2:
inputs:
- deploy_path: ./fastlane/renderedHoe houd je de buildtijden laag?
Het trage onderdeel van elke CI-screenshotpipeline is het renderen, niet het uploaden. De truc is om renders te cachen op basis van content-hash, zodat ongewijzigde locales eerdere uitvoer hergebruiken. Screenshots.live retourneert een stabiele renderHash in de respons — gebruik die als cachesleutel:
- Templateversie + locale + varianthash → cachesleutel
- Gerenderde PNG-bytes → cachewaarde
- Cache-TTL: 30 dagen, of totdat de template opnieuw wordt gepubliceerd
Gebruik op GitHub Actions actions/cache@v4 met een sleutel die afgeleid is van je template-ID en de lijst met locales. De meeste releasebuilds slaan het renderen volledig over en herbouwen alleen de locale die daadwerkelijk is gewijzigd.
Hoe valideer je de uitvoer voordat je indient?
Apple en Google wijzen screenshots stilzwijgend af wanneer ze niet aan de formaatcontroles voldoen: een PNG met een alfakanaal, een JPEG die als CMYK is gecodeerd, of een 6,7-inch iPhone-screenshot dat één pixel te kort is. Bouw een lintstap van 20 regels die deze problemen vóór indiening opspoort:
require "chunky_png"
Dir.glob("./fastlane/rendered/**/*.png").each do |path|
png = ChunkyPNG::Image.from_file(path)
raise "alpha channel: #{path}" if png.metadata["ColorType"] == 6
raise "too large: #{path}" if File.size(path) > 30 * 1024 * 1024
raise "wrong size: #{path}" if png.width < 1242
endMoet je het op een schema laten draaien?
Ja. Een nachtelijke cron betekent dat screenshots opnieuw worden gegenereerd zodra je template verandert — of die wijziging nu komt van een ontwerper in de editor, een tekstupdate vanuit marketing of een nieuw toegevoegde locale. Zonder schema raken store-vermeldingen uit de pas met je echte product en moet iemand eraan denken om vóór elke indiening een nieuwe build te pushen.
Combineer het schema met een Slack- of e-mailmelding bij falen. Een mislukte render om 04:00 UTC is een notificatie om 07:00 lokale tijd — niet een release-blokker die wordt ontdekt om 17:00 op de dag dat je wilde uitleveren.
Hoe zit het met Android, React Native en Flutter?
De pipeline is platformonafhankelijk aan de renderkant — alleen de capture-fase verandert. Vervang voor Android capture_screenshots door Fastlane screengrab en je Espresso-suite. Gebruik voor React Native Detox-snapshots. Gebruik voor Flutter integration_test-screenshots. Allemaal leveren ze ruwe PNG's op die Screenshots.live op identieke wijze behandelt.
Lees meer in onze gids voor multi-platformondersteuning over de captureconfiguratie voor elke stack.
Hoe ga je verder?
Zodra je CI-pipeline screenshots betrouwbaar uitlevert, is de volgende vraag welke screenshots winnen. Combineer deze pipeline met de A/B-testgids om varianten op een schema uit te leveren en conversie te meten. Combineer hem met de lokalisatiegids om 30+ locales toe te voegen zonder 30+ pipelines.
Gezaghebbende referenties voor verdere verdieping: Fastlane iOS screenshots-documentatie, Fastlane deliver-actie en de officiële App Store Connect-screenshotspecificaties.
Genereer al deze formaten automatisch
Stop met het handmatig vergroten of verkleinen van screenshots. Ontwerp één sjabloon en render elk formaat, apparaat en elke taal met één enkele API-aanroep.
Gratis starten — Probeer Screenshots.live