Slik automatiserer du App Store-skjermbilder i CI/CD
En praktisk, helhetlig pipeline for å generere skjermbilder til App Store og Google Play fra CI-systemet ditt med Fastlane, GitHub Actions og Bitrise — med konkret konfigurasjon du kan lime rett inn i repoet ditt.
Kort oppsummert
Ta råe app-skjermbilder i testkjøreren din, send dem til Screenshots.live-API-et med en mal-ID og en liste over språk, så skriver Fastlane den ferdig renderte, innrammede og lokaliserte utdataen tilbake til repoet ditt. Fastlane deliver / supply sender dem videre til butikkene. Hele pipelinen kjører på en tag-push eller et nattlig cron-jobb på under fem minutter.
Hvorfor i det hele tatt automatisere skjermbilder?
De fleste team behandler skjermbilder til App Store og Google Play som et håndlaget engangsmateriale: en designer setter dem opp i Figma, en markedsfører laster dem opp i App Store Connect, og ingen rører dem igjen før neste store redesign. Den modellen knekker i det øyeblikket du leverer på mer enn ett språk. Med 13 støttede språk, tre påkrevde iPhone-størrelser, to iPad-størrelser, pluss telefon og nettbrett på Google Play, ender du opp med over 100 PNG-filer for én enkelt utgivelse. Gang det med hver tekstendring, hver kampanje, hver A/B-testvariant, og regnestykket går ikke lenger opp.
Ved å automatisere i CI/CD blir skjermbilder et byggeartefakt på linje med en hvilken som helst annen binærfil. De er versjonert, reproduserbare og knyttet til en commit. Når markedsføring endrer en bildetekst, bygger pipelinen om alle språk og laster dem opp — ingen manuelle Photoshop-økter, ingen skjevheter mellom språkene, ingen avvisning ved innsending fordi noen glemte en 6,7-tommers iPhone-variant.
Hvordan ser pipelinen egentlig ut?
En ren CI-pipeline for skjermbilder har tre faser: fangst, rendering og levering. Fangsten er testpakken for grensesnittet du allerede har — XCUITest på iOS, Espresso på Android, Detox eller Maestro for React Native. Rendering er ett Screenshots.live-API-kall per språk som komponerer de råe rammene dine på en mal du designet én gang. Levering er Fastlane-handlingene deliver og supply du allerede bruker for å sende binærfiler.
REST-rendering-API-et til Screenshots.live er hjørnesteinen. Du sender råe skjermbilder én gang og får tilbake hver enhetsstørrelse, hvert språk og hver variant — fullt innrammet, med tekster og lokalisert. Ingen headless browser, ingen Puppeteer, ingen manuell skalering.
Hvordan kobler du det opp med Fastlane?
Fastlane er det kanoniske verktøyet for å automatisere iOS- og Android-utgivelser. Vi leverer en offisiell Fastlane-plugin som pakker rendering-API-et inn i én enkelt handling. Installer den fra prosjektroten:
fastlane add_plugin screenshotsliveLegg deretter til en lane i Fastfile som tar fangsten, rendrer og skriver ut den ferdige utdataen:
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
)
endPluginen håndterer opplastinger, polling for ferdigstillelse og parallell nedlasting. En typisk rendering med 5 språk og 3 enheter er ferdig på 60–90 sekunder.
Hvordan kjører du dette på GitHub Actions?
Slipp lanen inn i en workflow-fil. Workflowen under kjører ved hver tag-push som matcher v*, og på en nattlig tidsplan, så et manuelt git tag v1.2.0 && git push --tags er alt du trenger for å utløse en ny rendering.
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/For team som heller vil bruke en GitHub Action uten Fastlane, publiserer vi også en frittstående GitHub Action som snakker direkte med API-et:
- 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: ./screenshotsHva med Bitrise?
Bitrise-brukere får den samme lanen via det eksisterende Fastlane-steget. Legg til en Secret kalt SCREENSHOTSLIVE_API_TOKEN i Bitrise-arbeidsområdet ditt, og slipp dette inn i 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/renderedHvordan holder du byggetiden lav?
Den trege delen av enhver CI-pipeline for skjermbilder er rendering, ikke opplasting. Trikset er å mellomlagre renderinger etter innholds-hash slik at uendrede språk gjenbruker tidligere utdata. Screenshots.live returnerer en stabil renderHash i svaret — bruk den som cache-nøkkel:
- Malversjon + språk + varianthash → cache-nøkkel
- Renderte PNG-byte → cache-verdi
- Cache-TTL: 30 dager, eller til malen blir publisert på nytt
På GitHub Actions bruker du actions/cache@v4 med en nøkkel utledet fra mal-ID-en din og språk-listen. De fleste utgivelsesbygg hopper over rendering helt og bygger bare om språket som faktisk er endret.
Hvordan validerer du utdataen før innsending?
Både Apple og Google avviser skjermbilder stille når de ikke består formatkontroller: en PNG med alfa-kanal, en JPEG kodet som CMYK, eller et 6,7-tommers iPhone-skjermbilde som mangler én piksel. Bygg et 20-linjers lint-steg som fanger dette før innsending:
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
endBør du kjøre det på en tidsplan?
Ja. En nattlig cron betyr at skjermbilder regenereres hver gang malen din endres — enten endringen kom fra en designer i editoren, en tekstoppdatering fra markedsføring eller et nytt språk som ble lagt til. Uten en tidsplan kommer butikkoppføringene ut av synk med det faktiske produktet ditt, og noen må huske å sende et nytt bygg før hver innsending.
Kombiner tidsplanen med en Slack- eller e-postvarsling ved feil. En ødelagt rendering klokken 04:00 UTC er en varsling klokken 07:00 lokal tid — ikke en utgivelsesblokker som oppdages klokken 17:00 den dagen du skulle levere.
Hva med Android, React Native og Flutter?
Pipelinen er plattformuavhengig på rendering-siden — bare fangst-fasen endres. På Android bytter du ut capture_screenshots med Fastlane screengrab og Espresso-pakken din. For React Native bruker du Detox-snapshots. For Flutter bruker du integration_test-skjermbilder. Alle produserer råe PNG-er som Screenshots.live behandler likt.
Les mer i vår guide for støtte på flere plattformer for fangstkonfigurasjon på hver stack.
Hvor går du videre herfra?
Når CI-pipelinen din pålitelig leverer skjermbilder, blir neste spørsmål hvilke skjermbilder som vinner. Kombiner denne pipelinen med guiden for A/B-testing for å levere varianter på en tidsplan og måle konvertering. Par den med lokaliseringsguiden for å legge til 30+ språk uten 30+ pipelines.
Autoritative referanser for videre lesing: Fastlane iOS-skjermbilde-dokumentasjon, Fastlane deliver-handling og de offisielle App Store Connect-spesifikasjonene for skjermbilder.
Generer alle disse størrelsene automatisk
Slutt å endre størrelse på skjermbilder manuelt. Design én mal og render hver størrelse, enhet og lokalitet med ett enkelt API-kall.
Start gratis — Prøv Screenshots.live