Skip to content
Wszystkie wpisy
Blog25 marca 20263 min read
SL

Screenshots.live

Team

Budowanie pipeline'u zrzutow ekranu w CI/CD: Przewodnik krok po kroku

Dowiedz sie, jak zbudowac zautomatyzowany pipeline zrzutow ekranu uzywajac API Screenshots.live, GitHub Actions i Fastlane. Z pelna konfiguracja YAML, skryptami renderowania i automatyzacja uploadu.

Dlaczego zrzuty ekranu naleza do pipeline'u CI/CD

Zrzuty ekranu App Store sa zwykle traktowane jako zadanie designerskie, cos co dzieje sie raz przed premiera i potem jest boleznie aktualizowane co kilka miesiecy. To podejscie zawodzi, gdy zespol wydaje czesto.

Rozwiazaniem jest traktowanie zrzutow jak kazdego innego artefaktu build. Powinny byc generowane automatycznie przy zmianach UI, wersjonowane razem z kodem i wdrazane do sklepow jako czesc procesu release.

Przeglad architektury

  1. Projektowanie szablonu — Zespol designerski tworzy szablony w edytorze wizualnym Screenshots.live.
  2. Konfiguracja — Plik YAML definiuje szablony, jezyki i zmienne tekstowe.
  3. Renderowanie — Pipeline CI/CD wywoluje API Screenshots.live, ktore zwraca archiwum ZIP.
  4. Przetwarzanie koncowe — Pipeline rozpakowuje ZIP i organizuje pliki.
  5. Upload — Fastlane dostarcza zrzuty automatycznie.

Konfiguracja pliku

# .screenshots/config.yml

api_key: ${SCREENSHOTS_API_KEY}
base_url: https://api.screenshots.live/v1

templates:
  - id: tpl_hero_screen
    name: "Hero Screenshot"
    devices:
      - iphone67
      - ipad129
      - android_phone
      - android_tablet

locales:
  - code: en
    variables:
      headline: "Track Your Progress"
  - code: pl
    variables:
      headline: "Sledz swoj postep"

Workflow GitHub Actions

name: Generate App Store Screenshots

on:
  push:
    branches: [main]
    paths:
      - '.screenshots/**'
  workflow_dispatch:

env:
  SCREENSHOTS_API_KEY: ${{ secrets.SCREENSHOTS_API_KEY }}
  SCREENSHOTS_OUTPUT_DIR: ./fastlane/screenshots

jobs:
  generate-screenshots:
    runs-on: ubuntu-latest
    timeout-minutes: 30
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: '20'
      - uses: actions/cache@v4
        with:
          path: .screenshots/cache
          key: screenshots-${{ hashFiles('.screenshots/config.yml') }}
      - run: npm install js-yaml node-fetch@2 adm-zip
      - run: node .screenshots/generate.js
      - uses: actions/upload-artifact@v4
        with:
          name: app-store-screenshots
          path: ${{ env.SCREENSHOTS_OUTPUT_DIR }}

  upload-ios:
    needs: generate-screenshots
    runs-on: macos-latest
    if: github.ref == 'refs/heads/main'
    steps:
      - uses: actions/checkout@v4
      - uses: actions/download-artifact@v4
        with:
          name: app-store-screenshots
          path: fastlane/screenshots
      - run: gem install fastlane
      - run: fastlane ios upload_screenshots

  upload-android:
    needs: generate-screenshots
    runs-on: ubuntu-latest
    if: github.ref == 'refs/heads/main'
    steps:
      - uses: actions/checkout@v4
      - uses: actions/download-artifact@v4
        with:
          name: app-store-screenshots
          path: fastlane/screenshots
      - run: gem install fastlane
      - run: fastlane android upload_screenshots

Integracja Fastlane

# fastlane/Fastfile

platform :ios do
  lane :upload_screenshots do
    deliver(
      skip_binary_upload: true,
      skip_metadata: true,
      screenshots_path: "./fastlane/screenshots/ios",
      overwrite_screenshots: true,
    )
  end
end

platform :android do
  lane :upload_screenshots do
    upload_to_play_store(
      skip_upload_apk: true,
      skip_upload_aab: true,
      skip_upload_metadata: true,
      images_path: "./fastlane/screenshots/android",
    )
  end
end

Obsluga jezykow w pipeline

Gdy dodajesz nowy jezyk, dodajesz wpis w config.yml. Nastepne uruchomienie pipeline'u generuje zrzuty dla kazdego szablonu w nowym jezyku.

Wskazowki dotyczace cache i optymalizacji

Klucze cache oparte na zawartosci. Workflow uzywa hashFiles('.screenshots/config.yml') jako klucza cache.

Selektywne renderowanie. Jesli zmienil sie tylko jeden jezyk, rozdziel rendery wg jezyka.

Renderowanie rownolegle:

const renderPromises = config.templates.map(template =>
  renderTemplate(template, config, apiKey)
);
await Promise.all(renderPromises);

Monitorowanie renderow za pomoca webhookow

Screenshots.live wspiera webhooki, ktore powiadamiaja systemy po zakonczeniu lub niepowodzeniu renderowania.

Skladanie wszystkiego razem

  1. Designer tworzy lub aktualizuje szablon.
  2. Developer aktualizuje konfiguracje i pushuje na main.
  3. GitHub Actions wykrywa zmiane i uruchamia workflow.
  4. Skrypt renderowania czyta konfiguracje, wywoluje API i pobiera zrzuty.
  5. Fastlane laduje zrzuty do obu sklepow.
  6. Obie strony sklepu sa aktualizowane w ciagu minut.

Powiązane posty