Aller au contenu
Tous les guides
Guide pratiqueLecture de 45 min

Comment automatiser les captures d'écran App Store en CI/CD

Un pipeline pratique de bout en bout pour générer des captures d'écran App Store et Google Play depuis votre système CI avec Fastlane, GitHub Actions et Bitrise — avec des configurations concrètes que vous pouvez coller dans votre dépôt.

Eric Isensee
Eric IsenseeFounder · Last updated 5 mai 2026

TL;DR

Capturez les captures d'écran brutes de l'application dans votre runner de tests, envoyez-les à l'API Screenshots.live avec un identifiant de modèle et une liste de langues, et Fastlane récrit la sortie rendue, encadrée et localisée dans votre dépôt. Fastlane deliver / supply les pousse vers les stores. Tout le pipeline s'exécute lors d'un push de tag ou d'un cron nocturne en moins de cinq minutes.

Pourquoi automatiser les captures d'écran tout court ?

La plupart des équipes traitent les captures d'écran App Store et Google Play comme un actif unique fait main : un designer les maquette dans Figma, un marketeur les dépose dans App Store Connect, et personne n'y touche plus jusqu'à la prochaine refonte majeure. Ce modèle s'effondre dès que vous livrez sur plus d'une langue. Avec 13 langues prises en charge, trois tailles iPhone requises, deux tailles iPad, plus téléphone et tablette sur Google Play, vous regardez plus de 100 fichiers PNG pour une seule mise en production. Multipliez par chaque changement de copy, chaque promo, chaque variante de test A/B, et les calculs ne tiennent plus.

Automatiser en CI/CD fait des captures d'écran un artefact de build comme tout autre binaire. Elles sont versionnées, reproductibles et liées à un commit. Quand le marketing change une légende, le pipeline reconstruit chaque langue et les téléverse — pas de sessions Photoshop manuelles, pas de dérive d'actifs entre les langues, pas de rejet à la soumission parce que quelqu'un a oublié une variante iPhone 6,7 pouces.

À quoi ressemble réellement le pipeline ?

La forme d'un pipeline propre de captures d'écran CI est en trois étapes : capture, rendu et livraison. La capture est votre suite de tests UI existante — XCUITest sur iOS, Espresso sur Android, Detox ou Maestro pour React Native. Le rendu est un appel API Screenshots.live par langue qui compose vos frames brutes sur un modèle que vous avez conçu une fois. La livraison est les actions Fastlane deliver et supply existantes que vous utilisez déjà pour pousser des binaires.

L<link>API REST de rendu</link> Screenshots.live est la clé de voûte. Vous envoyez les captures décran brutes une fois et récupérez chaque taille d'appareil, chaque langue et chaque variante — entièrement encadrées, sous-titrées et localisées. Pas de navigateur headless, pas de Puppeteer, pas de redimensionnement manuel.

Comment le brancher avec Fastlane ?

Fastlane est l'outil canonique d'automatisation de mise en production iOS / Android. Nous livrons un plugin Fastlane officiel qui enveloppe l'API de rendu dans une seule action. Installez-le depuis la racine de votre projet :

terminal
bash
fastlane add_plugin screenshotslive

Puis ajoutez une lane à votre Fastfile qui capture, rend et écrit la sortie rendue :

fastlane/Fastfile
ruby
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
  )
end

Le plugin gère les téléversements, l'interrogation pour la complétion et le téléchargement en parallèle. Un rendu typique de 5 langues, 3 appareils se termine en 60 à 90 secondes.

Comment l'exécuter sur GitHub Actions ?

Déposez la lane dans un fichier de workflow. Le workflow ci-dessous s'exécute sur chaque push de tag qui correspond à v* et sur un planning nocturne, donc un git tag v1.2.0 && git push --tags manuel est tout ce dont vous avez besoin pour déclencher un nouveau rendu.

.github/workflows/screenshots.yml
yaml
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/

Pour les équipes qui préfèrent une GitHub Action sans Fastlane, nous publions également une GitHub Action autonome qui parle directement à l'API :

.github/workflows/screenshots-direct.yml
yaml
- 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: ./screenshots

Et Bitrise ?

Les utilisateurs de Bitrise obtiennent la même lane via l'étape Fastlane existante. Ajoutez un Secret nommé SCREENSHOTSLIVE_API_TOKEN dans votre espace de travail Bitrise, puis déposez ceci dans votre bitrise.yml :

bitrise.yml
yaml
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/rendered

Comment maintenir les temps de build bas ?

La partie lente de tout pipeline CI de captures d'écran est le rendu, pas le téléversement. L'astuce consiste à mettre en cache les rendus par hash de contenu afin que les langues inchangées réutilisent la sortie précédente. Screenshots.live retourne un renderHash stable dans la réponse — utilisez-le comme clé de cache :

  • Version du modèle + langue + hash de variante → clé de cache
  • Octets PNG rendus → valeur de cache
  • TTL du cache : 30 jours, ou jusqu'à ce que le modèle soit republié

Sur GitHub Actions, utilisez actions/cache@v4 avec une clé dérivée de votre identifiant de modèle et de la liste des langues. La plupart des builds de mise en production sautent entièrement le rendu et reconstruisent uniquement la langue qui a réellement changé.

Comment valider la sortie avant de soumettre ?

Apple et Google rejettent tous deux silencieusement les captures d'écran lorsqu'elles échouent aux contrôles de format : un PNG avec un canal alpha, un JPEG encodé en CMJN ou une capture d'écran iPhone 6,7 pouces à un pixel près. Construisez une étape de lint de 20 lignes qui les attrape avant la soumission :

fastlane/lint_screenshots.rb
ruby
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
end

Devriez-vous l'exécuter selon un planning ?

Oui. Un cron nocturne signifie que les captures d'écran se régénèrent chaque fois que votre modèle change — que le changement vienne d'un designer dans l'éditeur, d'une mise à jour de copy du marketing ou de l'ajout d'une nouvelle langue. Sans planning, les fiches de store dérivent par rapport à votre vrai produit, et quelqu'un doit se rappeler de pousser un nouveau build avant chaque soumission.

Combinez le planning avec une alerte Slack ou e-mail en cas d'échec. Un rendu cassé à 04h00 UTC est une notification à 07h00 heure locale — pas un bloqueur de mise en production découvert à 17h00 le jour où vous vouliez livrer.

Et Android, React Native et Flutter ?

Le pipeline est agnostique de plateforme côté rendu — seule l'étape de capture change. Pour Android, échangez capture_screenshots contre Fastlane screengrab et votre suite Espresso. Pour React Native, utilisez les snapshots Detox. Pour Flutter, utilisez les captures d'écran integration_test. Toutes produisent des PNG bruts que Screenshots.live traite à l'identique.

En savoir plus dans notre guide de prise en charge multi-plateformes pour la configuration de capture sur chaque stack.

Où aller à partir d'ici ?

Une fois que votre pipeline CI livre fiablement les captures d'écran, la prochaine question est : quelles captures d'écran gagnent. Combinez ce pipeline avec le guide de tests A/B pour livrer des variantes selon un planning et mesurer la conversion. Associez-le au guide de localisation pour ajouter plus de 30 langues sans 30+ pipelines.

Références faisant autorité pour aller plus loin : documentation des captures d'écran iOS Fastlane, action deliver Fastlane et les spécifications officielles des captures d'écran App Store Connect.

Essayez-le sur un vrai dépôt

Générez automatiquement toutes ces tailles

Arrêtez de redimensionner les captures d'écran manuellement. Concevez un seul modèle et rendez chaque taille, chaque appareil et chaque langue avec un seul appel API.

Commencer gratuitement — Essayer Screenshots.live