Saltar para o conteúdo
Todos os Guias
Guia Prático45 min de leitura

Como Automatizar Capturas de Ecrã da App Store em CI/CD

Um pipeline prático de ponta a ponta para gerar capturas de ecrã da App Store e Google Play a partir do seu sistema de CI usando Fastlane, GitHub Actions e Bitrise — com configuração concreta que pode colar no seu repositório.

Eric Isensee
Eric IsenseeFounder · Last updated 5 de maio de 2026

Resumo

Capture as capturas de ecrã brutas da app no seu test runner, envie-as para a API Screenshots.live com um ID de template e uma lista de localizações, e o Fastlane escreve a saída renderizada, emoldurada e localizada de volta no seu repositório. O Fastlane deliver / supply envia-as para as lojas. Todo o pipeline corre num push de tag ou cron noturno em menos de cinco minutos.

Porquê automatizar capturas de ecrã?

A maioria das equipas trata as capturas de ecrã da App Store e Google Play como um ativo único, feito à mão: um designer faz uma maquete no Figma, um marketeer carrega-as no App Store Connect, e ninguém volta a tocar nelas até ao próximo redesign importante. Esse modelo desmorona-se no momento em que envia para mais do que uma localização. Com 13 localizações suportadas, três tamanhos obrigatórios de iPhone, dois tamanhos de iPad, mais telemóvel e tablet no Google Play, está a olhar para mais de 100 ficheiros PNG para um único lançamento. Multiplique por cada alteração de texto, cada promoção, cada variante de teste A/B, e a matemática deixa de funcionar.

Automatizar em CI/CD transforma as capturas de ecrã num artefacto de build como qualquer outro binário. São versionadas, reproduzíveis e ligadas a um commit. Quando o marketing altera uma legenda, o pipeline reconstrói cada localização e carrega-as — sem sessões manuais de Photoshop, sem desvios entre línguas, sem rejeição na submissão porque alguém se esqueceu de uma variante de iPhone de 6,7 polegadas.

Como é realmente o pipeline?

A forma de um pipeline limpo de capturas de ecrã em CI tem três fases: captura, renderização e entrega. A captura é a sua suite de testes de UI existente — XCUITest no iOS, Espresso no Android, Detox ou Maestro para React Native. A renderização é uma chamada à API Screenshots.live por localização que compõe os seus frames brutos sobre um template que desenhou uma única vez. A entrega são as ações Fastlane deliver e supply que já usa para enviar binários.

A API REST de renderização da Screenshots.live é a peça-chave. Envia capturas de ecrã brutas uma vez e recebe de volta todos os tamanhos de dispositivo, todas as localizações e todas as variantes — totalmente emolduradas, com legendas e localizadas. Sem navegador headless, sem Puppeteer, sem redimensionamento manual.

Como ligar tudo com o Fastlane?

O Fastlane é a ferramenta canónica de automação de lançamentos para iOS / Android. Disponibilizamos um plugin oficial do Fastlane que envolve a API de renderização numa única ação. Instale-o a partir da raiz do seu projeto:

terminal
bash
fastlane add_plugin screenshotslive

Depois adicione uma lane ao seu Fastfile que captura, renderiza e escreve a saída renderizada:

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

O plugin trata dos uploads, da consulta para verificar a conclusão e do download em paralelo. Uma renderização típica de 5 localizações e 3 dispositivos termina em 60 a 90 segundos.

Como executar isto no GitHub Actions?

Coloque a lane num ficheiro de workflow. O workflow abaixo corre em cada push de tag que corresponda a v* e num agendamento noturno, portanto um simples git tag v1.2.0 && git push --tags manual é tudo o que precisa para acionar uma nova renderização.

.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/

Para equipas que preferem uma GitHub Action sem Fastlane, também publicamos uma GitHub Action autónoma que comunica diretamente com a 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

E o Bitrise?

Os utilizadores do Bitrise obtêm a mesma lane através do passo Fastlane existente. Adicione um Secret chamado SCREENSHOTSLIVE_API_TOKEN no seu workspace Bitrise, e depois adicione isto ao seu 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

Como manter os tempos de build baixos?

A parte lenta de qualquer pipeline de capturas de ecrã em CI é a renderização, não o upload. O truque é colocar em cache as renderizações por hash de conteúdo, para que localizações inalteradas reutilizem a saída anterior. A Screenshots.live devolve um renderHash estável na resposta — use-o como chave de cache:

  • Versão do template + localização + hash da variante → chave de cache
  • Bytes do PNG renderizado → valor de cache
  • TTL da cache: 30 dias, ou até o template ser republicado

No GitHub Actions, use actions/cache@v4 com uma chave derivada do ID do seu template e da lista de localizações. A maioria das builds de lançamento ignora completamente a renderização e apenas reconstrói a localização que efetivamente mudou.

Como validar a saída antes de submeter?

Tanto a Apple como a Google rejeitam silenciosamente capturas de ecrã quando estas falham nas verificações de formato: um PNG com canal alfa, um JPEG codificado como CMYK, ou uma captura de ecrã de iPhone de 6,7 polegadas com um pixel a menos. Construa um passo de lint de 20 linhas que apanha estes problemas antes da submissão:

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

Deve executá-lo num agendamento?

Sim. Um cron noturno significa que as capturas de ecrã são regeneradas sempre que o seu template muda — quer a alteração tenha vindo de um designer no editor, de uma atualização de texto do marketing, ou de uma nova localização adicionada. Sem um agendamento, as listagens da loja desviam-se do seu produto real, e alguém tem de se lembrar de fazer uma nova build antes de cada submissão.

Combine o agendamento com um alerta no Slack ou por email em caso de falha. Uma renderização partida às 04:00 UTC é uma notificação às 07:00 hora local — não um bloqueador de lançamento descoberto às 17:00 no dia em que queria publicar.

E o Android, React Native e Flutter?

O pipeline é agnóstico em relação à plataforma do lado da renderização — só a fase de captura muda. Para Android, troque capture_screenshots pelo screengrab do Fastlane e a sua suite Espresso. Para React Native, use snapshots Detox. Para Flutter, use capturas de ecrã integration_test. Todas produzem PNGs brutos que a Screenshots.live trata de forma idêntica.

Saiba mais no nosso guia de suporte multiplataforma para configuração da captura em cada stack.

Para onde ir a partir daqui?

Quando o seu pipeline de CI envia capturas de ecrã de forma fiável, a próxima questão é quais capturas vencem. Combine este pipeline com o guia de testes A/B para enviar variantes num agendamento e medir conversão. Junte-o ao guia de localização para adicionar mais de 30 localizações sem mais de 30 pipelines.

Referências autoritativas para leitura adicional: documentação de capturas de ecrã iOS do Fastlane, ação deliver do Fastlane, e as especificações oficiais de capturas de ecrã do App Store Connect.

Experimente num repositório real

Gere Todos Estes Tamanhos Automaticamente

Pare de redimensionar capturas de ecrã manualmente. Desenhe um modelo e renderize todos os tamanhos, dispositivos e idiomas com uma única chamada de API.

Comece Grátis — Experimente Screenshots.live